#!/usr/bin/perl
#use strict;
#use warnings;
use Getopt::Long; #used for grabbing the command line arguments by name
use Text::CSV; #used for parsing the input CSV file
if ( @ARGV == 0 || @ARGV eq \'/?\' || @ARGV eq \'?\') {goto SYNTAX;}
my $debug=0; #set to 1 for debug output, 0 to disable debug output
my ($outnpcxml,$outsacsv,$outnvcsv,$outucmcsv,$npcinspath,$inputfile) = (0,0,0,0,"","sites.csv"); #set default command line options
my ($npcxmlname,$sacsvname,$nvcsvname,$ucmcsvname) = (\'NPCGroups.xml\',\'SANetworks.csv\',\'NVScopes.csv\',\'UCMLocations.csv\'); #change these values to change the default output file names
GetOptions ( # get command line options (if provided)
\'outnpcxml\' => \\$outnpcxml,
\'outsacsv\' => \\$outsacsv,
\'outnvcsv\' => \\$outnvcsv,
\'outucmcsv\' => \\$outucmcsv,
\'infile:s\' => \\$inputfile,
\'npcinspath:s\' => \\$npcinspath,
\'npcxmlname:s\' => \\$npcxmlname,
\'sacsvname:s\' => \\$sacsvname,
\'nvcsvname:s\' => \\$nvcsvname,
\'ucmcsvname:s\' => \\$ucmcsvname,
\'verbose\' => \\$debug,
\'v\' => \\$debug);
if ($debug){print "Input CSV: $inputfile\\nNPC Insertion Path: $npcinspath\\nOutput Types\\nNPC: $outnpcxml (to file $npcxmlname)\\nSA: $outsacsv (to file $outsacsvname)\\nNV: $outnvcsv (to file $outnvcsvname)\\nUCM: $outucmcsv (to file $outucmcsvname)\\n";} #output command line parameters
if ($outnpcxml+$outsacsv+$outnvcsv+$outucmcsv == 0) {print "ERROR: You have not specified any output files.\\n";goto SYNTAX;}
if ($outnpcxml) { #check for required argument (npcinspath) and insert header text into output xml
if ($npcinspath eq "") { #can\'t generage npc xml without the insertion point
print "ERROR: The insertion point argument is missing.\\nAdd it with \'--npcinspath \\"\\\\All Groups\\\\Sites\\"\\n\\n";
goto SYNTAX; #exit the script without doing anything else
}
open OUTNPCFILE, ">", $npcxmlname or die $!; #open output file
print OUTNPCFILE "<GroupTree path=\\"" . $npcinspath . "\\" inheritDefault=\\"true\\" xmlns=\\"\\">\\n"; #insert xml header data
}
if ($outsacsv) {open OUTSAFILE, ">", $sacsvname or die $!;} #open output file
if ($outnvcsv) {open OUTNVFILE, ">", $nvcsvname or die $!;} #open output file
if ($outucmcsv) {open OUTUCMFILE, ">", $ucmcsvname or die$!;} #open output file
my $csv = Text::CSV->new(); #create csv instance
open (CSV, "<", $inputfile) or die $!; #open the intput file
my @subnets; #create array to hold input from CSV. This array will be an array of arrays.
print "Reading input file contents...";
while (<CSV>) { #Import the CSV file into @subnets
if ($csv->parse($_)) { #parse the current line into the $csv variable
my @columns = $csv->fields(); #split the csv contents into an array and store in @columns
if ($columns[0] ne \'NetworkNumber\') { #skip if the first line contains column headers
push @subnets, [ @columns ]; #add the line contents to the @subnets array
}
}
}
close CSV; #get rid of the input file
my @sites; #array to contain the individual sites
my ($i, $n, $aref, $j); #initialize counters and reference variables for loops
if ($debug) {
print "Network Number\\tNetwork Mask\\tSite\\n"; #print column headers
for $i ( 0 .. $#subnets ) { #print contents of @subnets
$aref = $subnets[$i]; #get the reference of the array of the current row
$n = @$aref - 1; #find the length of the current row
for $j ( 0 .. $n ) { #cycle through each column of the current row
if ($j==2) {print "\\t";} #extra tab to line things up
print "$subnets[$i][$j]\\t"; #output the contents
}
print "\\n";
}
}
for $i ( 0 .. $#subnets ) { push @sites, $subnets[$i][2]; } #populate the @sites array with site names
my %temphash = map { $_, 1 } @sites; @sites = keys %temphash; #remove duplicate sites
print "Done\\nProcessing content and preparing to generate output files...\\n";
my $currentsite; #variable to hold the current site name from @sites for comparison when looping through @subnets
if ($outnpcxml) { # print OUTNPCFILE
print "Generating NPC XML...";
foreach (@sites){ #loop through sites list
$currentsite = $_; #grab the current site name
#count subnets per site
$j=0; #reset counter
for $i ( 0 .. $#subnets) {if ($currentsite eq $subnets[$i][2]){$j++;}} #$j now has the number of subnets for this site
#output xml
print OUTNPCFILE "<Group name=\\"$currentsite\\" inherit=\\"true\\" type=\\"site\\" desc=\\"\\" >\\n";
print OUTNPCFILE " <Rules allowDeletes=\\"true\\" saveRules=\\"true\\">\\n";
#make rule to add devices by IP
print OUTNPCFILE " <Rule add=\\"Devices\\" name=\\"Add Devices by IP Address\\">\\n";
print OUTNPCFILE " <Match>\\n";
print OUTNPCFILE " <Compare using=\\"equals\\">\\n";
print OUTNPCFILE " <Property type=\\"Device\\" name=\\"Address\\" />\\n";
if ($j > 1) {print OUTNPCFILE " <ValueList>\\n";} #if multiple subnets, open ValueList tag
for $i ( 0 .. $#subnets) {if ($currentsite eq $subnets[$i][2]){print OUTNPCFILE " <Value>$subnets[$i][0]/$subnets[$i][1]</Value>\\n";}}
if ($j > 1) {print OUTNPCFILE " </ValueList>\\n";} #if multiple subnets, close ValueList tag
print OUTNPCFILE " </Compare>\\n </Match>\\n </Rule>\\n";
if ($outsacsv) { #make rule to add subnets by IP
print OUTNPCFILE " <Rule add=\\"Networks\\" name=\\"Add Networks\\">\\n";
print OUTNPCFILE " <Match>\\n";
print OUTNPCFILE " <Compare using=\\"equals\\">\\n";
print OUTNPCFILE " <Property type=\\"Network\\" name=\\"Subnet\\" />\\n";
if ($j > 1) {print OUTNPCFILE " <ValueList>\\n";} #if multiple subnets, open ValueList tag
for $i ( 0 .. $#subnets) {if ($currentsite eq $subnets[$i][2]){print OUTNPCFILE " <Value>$subnets[$i][0]/$subnets[$i][1]</Value>\\n";}}
if ($j > 1) {print OUTNPCFILE " </ValueList>\\n";} #if multiple subnets, close ValueList tag
print OUTNPCFILE " </Compare>\\n </Match>\\n </Rule>\\n";
}
if ($outucmcsv) { #make rule to add VoIP locations by name
print OUTNPCFILE " <Rule add=\\"VoIP Locations\\" name=\\"Add UCMonitor Locations\\">\\n";
print OUTNPCFILE " <Match>\\n";
print OUTNPCFILE " <Compare using=\\"equals\\">\\n";
print OUTNPCFILE " <Property type=\\"VoIP Location\\" name=\\"Name\\" />\\n";
print OUTNPCFILE " <Value>$currentsite</Value>\\n";
print OUTNPCFILE " </Compare>\\n </Match>\\n </Rule>\\n";
}
print OUTNPCFILE " </Rules>\\n</Group>\\n";
}
print OUTNPCFILE "</GroupTree>";
close OUTNPCFILE;
print "Done\\n";
}
if ($outsacsv) { # output SA CSV
print "Generating SA CSV...";
for $i ( 0 .. $#subnets) { #loop through subnets list
my $regions = 2**(24-$subnets[$i][1]); #calculate the best number of regions
if ($regions < 1) { $regions=1; } #use 1 if mask is > 24
if ($regions > 256) { $regions=256; } #use the lower value (validate the regions)
print OUTSAFILE "$subnets[$i][2],$subnets[$i][0],$subnets[$i][1],$regions\\n"; #output to csv
}
close OUTSAFILE;
print "Done\\n";
}
if ($outnvcsv) { # output NV CSV
print "Generating NV CSV...";
for $i ( 0 .. $#subnets) { print OUTNVFILE "$subnets[$i][0]/$subnets[$i][1]\\n"; } #loop through the sites list and export it
close OUTNVFILE;
print "Done\\n";
}
if ($outucmcsv) { # output UCM CSV
print "Generating UCM CSV...";
foreach (@sites){
$currentsite = $_; #grab current site name
#count subnets per site
$j=0; #reset counter
for $i ( 0 .. $#subnets) {if ($currentsite eq $subnets[$i][2]){$j++;}} #$j now has the number of subnets for this site
#make rule to add devices by IP
print OUTUCMFILE "LOCATION,$currentsite\\n"; #for each site insert a Location line
for $i ( 0 .. $#subnets) { if ($currentsite eq $subnets[$i][2]){ print OUTUCMFILE "SUBNET,$currentsite,$subnets[$i][0]/$subnets[$i][1],$subnets[$i][0],$subnets[$i][1]\\n";}} #if the current subnet belongs to the current site, output the subnet line
}
close OUTUCMFILE;
print "Done\\n";
}
goto THEEND;
SYNTAX:
print <<FOO;
\\nThis script outputs any combination of configuration files for the NetQoS
suite of products. You must install strawberry perl and Text::CSV,
Text::CSV_XS, and Getopt::Long. To install CPAN modules, run cpan [module name]
from the command prompt.
\\nExample: cpan Text::CSV\\n
This script was created by Stuart Weenig (C)2012. For more information visit
http://stuart.weenig.com. This script may be redistributed as long as all the
files are kept in their original state.\\n
Current Version: 2.0
Usage: PERL gxmlg.pl [-outnpcxml] [-outsacsv] [-outnvcsvnv] [-outucmcsv]
[-infile NAMEOFINFILE] [-npcinspath INSERTPATH]
[-npcxmlname NPCXMLFILE] [-sacsvname SACSVFILE]
[-nvcsvname NVCSVFILE] [-ucmcsvname UCMCSVFILE]
-infile NAMEOFINFILE Specifies the name of the Sites file to be
imported. (If omitted: sites.csv)
-outnpcxml Output an NPC XML groups definition file.
-npcxmlname NPCXMLFILE Name of the NPC file to be output. (If
omitted: NPCGroups.xml)
-npcinspath INSERTPATH The path to the group that will serve as
the insertion point. Required if using
-outnpcxml option.
-outsacsv Output a SA networks CSV file.
-sacsvname SACSVFILE Name of the SA file to be output. (If omitted:
SANetworks.csv)
-outnvcsv Output a NV discovery scopes file.
-nvcsvname NVCSVFILE Name of the NV file to be output. (If omitted:
NVScopes.csv)
-outucmcsv Output a UCMonitor locations file.
-ucmcsvname UCMCSVFILE Name of the UCMonitor locations file to be output.
(If omitted: UCMLocations.csv)
-v|-verbose Runs with verbose output, including an echo of the
content after it is imported, allowing verification
of the imported data.
You must install strawberry perl and Text::CSV, Text::CSV_XS, and Getopt::Long.
To install CPAN modules, run cpan [module name] from the command prompt
Example: cpan Text::CSV
The infile must be a CSV with the following columns:
NetworkNumber,NetworkMask,Site
Here is an example:
NetworkNumber,NetworkMask,Site
10.1.0.0,16,New York
10.2.0.0,15,Los Angeles (Bldg 1)
10.4.0.0,16,Los Angeles (Bldg 2 - Corp)
10.5.0.0,16,Los Angeles (Bldg 2 - Sales)
172.16.1.0,24,Los Angeles (Bldg 2 - DC)
10.100.0.0,16,London
10.150.0.0,16,Singapore
192.168.150.0,24,Singapore
If the server you will be running this on doesn\'t have access to the internet, you
won\'t be able to install the modules automatically (since they have to be downloaded
from the internet). The solution is to download the tarballs from www.cpan.org and
extract them using winzip or winrar or 7z. You might need to extract several times
until you get just the folder with the files in them. Then copy them to your server.
Open a command prompt and cd to the directory containing Makefile.pl (you\'ll have to
do this for each module). Then execute the following:
perl Makefile.pl && dmake && dmake test && dmake install
For the text modules, do Text::CSV first, then Text::CSV_XS.
FOO
THEEND: