#!\usr\bin\perl
# Written by Richard Graves
#
# This script is used to issue config commands to a cisco device 
# using either telnet or SSHv1
#
# Special mention to Vladimir Parkhaev and Benjamin Trott for Net:SSH:Perl
# Without those two folks, this script would not be possible!
#
# Props to Joshua Keroes for Net::Telnet::Cisco and Jay Rogers for Net::Telnet
#
# ARGV[0] = Device list file
# ARGV[1] = Command list file
# ARGV[2] = noprompt option
# ARGV[3] = Device Type
# ARGV[4] = Username
# ARGV[5] = Password
# ARGV[6] = Enable Password
#
# To run without being prompted use the following format:
#
# main.pl DevList CmdList noprompt DevType(numeric) Username Password Enable-Password 
#
# DevTypes are 1-Router, 2-Switch, 3-Firewall
#--------------------------------------------------------------------------

use strict;
no warnings;
#use Net::Ping;

my ($file, $line, %devices, $cmdfile);

$file=$ARGV[0]|| die "Usage: $0 [device list filename] [command list filename] noprompt [Device Type Numeric] [Username] [Password] [Enable Password]\n";									#grab filename as cmd line arg

if (-e $file && -r $file)						#if file exists and is readable
{
	open(IN, "$file");							#open the file using the IN filehandle
}

while($line=<IN>)								#while data is coming in from file
{
		
	unless($line=~ m/^\#+/)						#unless the line starts with # do the following..
	{											
		
		if($line=~ m/(.{1,15})\t(.+)/)			#match the IP from the hosts file
			{
				$devices{$1}=$2;				#push it into a hash
			}
		else									#otherwise do nothing
			{
			}
			
	}
	
	
}

close(IN);										#close the filehandle


#--------------------------------------------------------------------------------------------
#This will be passed to the script that actually connects to the devices

$cmdfile=$ARGV[1] || die "Usage: $0 [device list filename] [command list filename] noprompt [Device Type Numeric] [Username] [Password] [Enable Password]\n";			 #grab filename as cmd line arg

my (@CONFIGVAR, $CONFIGVAR);
my ($cntr, $line);

if (-e $cmdfile && -r $cmdfile)						#if file exists and is readable
{
	open(IN, "$cmdfile");							#open the file using the IN filehandle
}


while($line=<IN>)								#while data is coming in from file
{
		
	unless($line=~ m/^\!+/)						#unless the line starts with ! do the following..
	{											
		$cntr++;
		if ($cntr > 20) 
		{
			die "Please limit number of commands to 20!\n";
		}
		else
		{
			push (@CONFIGVAR, $line);
		}
			
	}
	
	
}
close(IN);										#close the filehandle
												#close the filehandle

#--------------------------------------------------------------------------------------------

my ($DEVUSER, $DEVPWD, $ENBPWD, $timer1, $timer2, $timer3);
my ($DevType, $GoNoGo, @timearray, $mnth, $yr, $OutputFile, $ErrorFile);

push (@timearray, localtime(time));

$mnth = @timearray[4] + 1;
$yr = @timearray[5] + 1900;

$OutputFile = "$mnth-@timearray[3]-$yr-@timearray[2]-@timearray[1]-@timearray[0]-Output.txt";
$ErrorFile = "$mnth-@timearray[3]-$yr-@timearray[2]-@timearray[1]-@timearray[0]-Error.txt";

#--------------------------------------------------------------------------------------------


if ($ARGV[2]=~ m/noprompt|NOPROMPT/)
{
	$DevType=$ARGV[3];
	$DEVUSER=$ARGV[4];
	$DEVPWD=$ARGV[5];
	$ENBPWD=$ARGV[6];
	
	goto NOPROMPTSTART;
}

#--------------------------------------------------------------------------------------------


use Term::ReadKey;		#Remove comment if term::readkey is available

print("\n1. Cisco Router\n");
print("2. Cisco Switch\n");
print("3. Cisco PIX Firewall\n");
print("\nPlease select a Device Type: ");
$DevType=<STDIN>;
chomp($DevType);

if($DevType=='')
{ 
	die "\nYou Must Enter a Device Type!\n";
}

print("\nEnter your Username: ");
$DEVUSER=<STDIN>;
chomp($DEVUSER);

ReadMode('noecho'); # don't echo #Remove comment if term::readkey is available
print("\nEnter your Password: ");
$DEVPWD=<STDIN>;
chomp($DEVPWD);

print("\nEnter your ENABLE Password: ");
$ENBPWD=<STDIN>;
chomp($ENBPWD);
ReadMode(0);        # back to normal #Remove comment if term::readkey is available

#--------------------------------------------------------------------------------------------
#Display config update, last chance to say no..

print("\n\n***************************************************\n");
print("*** Please review the following config changes. ***\n");
print("***    This is your last chance to abort!!!     ***\n");
print("***************************************************\n\n\n");


print (@CONFIGVAR);

print("\n\n\n***************************************************\n");

print("\n\n\nContinue? (Y/N): ");
$GoNoGo=<STDIN>;
chomp($GoNoGo);

if ($GoNoGo=~ m/Y|y/) 
{
}
else
{
	die "\n\n***Aborted***\n";
}
#--------------------------------------------------------------------------------------------

NOPROMPTSTART:;

my ($numdev);

$numdev = keys( %devices );

print "\n\nNumber of devices to touch:  " . $numdev . "\n\n";

$timer1 = time;
#--------------------------------------------------------------------------------------------

my ($Key, $Value);

while(($Key, $Value) = each(%devices))			#step through hash for each device
{

	
	if($DevType=='1')
		{
			print `perl CCS_sub_Telnet.pl $Key $cmdfile $DEVUSER $DEVPWD $ENBPWD $OutputFile`; #call script that actually connects to device
		}	
	
	elsif($DevType=='2')
		{
			print `perl CCS_sub_Telnet.pl $Key $cmdfile $DEVUSER $DEVPWD $ENBPWD $OutputFile`; #call script that actually connects to device
		}	
	
		
	elsif($DevType=='3')
		{
			print `perl CCS_sub_SSH.pl $Key $cmdfile $DEVUSER $DEVPWD $ENBPWD $OutputFile`; #call script that actually connects to device
		}														  		  				#and pass needed variables
}
	
$timer2 = time;
$timer3 = $timer2 - $timer1;
print ("\n\nOperation Complete:  $numdev device(s) touched in $timer3 seconds\n\n");

#-------------------------------------------------------------------------------------------------------
#After action report



my ($cntr2, @FailDev, $BadDev);

if (-e $OutputFile && -r $OutputFile)				#if file exists and is readable
{
	open (AFTER, "$OutputFile");					#open the file using the AFTER filehandle
													
}

while($line=<AFTER>)								#while data is coming in from file
{
	
	$cntr2++;
	
	if($cntr2>=1)
	{
			
	 	if($line=~ m/.?Successful/) 
	 		{
	 			
	 		}	
	 	else
	 	{
		
		$line =~ s/^\s+//;
		#$line =~ s/\s+$//;
		
	 	push (@FailDev, $line);
		}
	}
}

close (AFTER);

if ($#FailDev>0)
	{
	$BadDev = $#FailDev;
	print ("\nThe following $BadDev devices failed to complete successfully:\n\n");
	print (" @FailDev\n\n");
	open (PRINTRPT, ">>$ErrorFile");
	print (PRINTRPT "@FailDev");
	close (PRINTRPT);
	}

=head1 NAME

Combined Cisco Script

=head1 DESCRIPTION

This script is used to issue config commands to a cisco device using either telnet or SSHv1.

This is the main script, the other two scripts CCS_sub_telnet.pl and CCS_sub_SSH.pl are also required

=head1 README


=head1 PREREQUISITES

This script requires:

Perl 5.8 or higher
Net::SSH::Perl 
Net::SSH::Perl::Constants
Net::Telnet
Net::Telnet::Cisco

=head1 COREQUISITES

CCS_sub_telnet.pl
CCS_sub_SSH.pl


=pod OSNAMES

any

=pod SCRIPT CATEGORIES

Networking

=cut