Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
#!/usr/bin/perl -w # ciscoconf.pl # pod at tail use strict; use Net::Telnet::Cisco; use Term::ReadKey; use Tie::IxHash; use Time::localtime; use vars qw( $target @targets $timeout @timeout $oldpass $newpass $confpass $olden $newen $confen $command @commands $setpass @setpass $writemem @writemem $section $yn $devtype ); my $conf = 'ciscoconf.conf'; my $tmp = 'ciscoconf.tmp'; my $log = 'ciscoconf.log'; my $errmode = 'return'; # so bad command won't kill s +cript my $timeout = '30'; # default is none in $conf my @regex = ( # strip these strings from $l +og '^Enter configuration commands, one per line.*$', '^\s+$', # blank lines. Should be last + regex line ); &CONFEXT(); &WARNTEXT(); &STARTCLEAN(); &OLDPASSLIST(); &NEWPASSLIST(); &CATORIOS(); &STARTTEXT(); print " ------------------------------------------\n\n"; print " The following devices have been configured:\n"; print " (listed by system prompt)\n"; umask oct 177; # tempfile owner-only readable. Like "chmod + 0600", but no race condition. for $target (@targets) { if (my $cs=Net::Telnet::Cisco->new( host => $target, errmode => $errmode, timeout => $timeout, input_log => $tmp, ) ) {$cs->login('',$oldpass); # vty login print " ", $cs->last_prompt; # show progress w/ +device prompt to console if ($cs->enable($olden)) { # privilaged mode +for config changes print " ", $cs->last_prompt; # show progress w/ +device prompt to console foreach $setpass (@setpass) { # iterate through +internal set pass commands my @output = $cs -> cmd($setpass); } foreach $command (@commands) { # iterate through +external config commands my @output = $cs -> cmd($command); } } else { # privilaged mode +failed warn " Error connecting. Did you enter a bad password?\n +"; #. $cs->errmsg; } print " ", $cs -> last_prompt, "\n"; # show progress w/ +device prompt to console $cs->close; # exit session &LOGREGX(); } else { # telnet connectio +n failed warn " Error connecting. Is the device reachable?\n"; } } &ENDCLEAN(); &ENDTEXT(); ###################################################################### +### sub WARNTEXT { print <<EOF; = ciscoconf.pl = Automate configuration changes for multiple Cisco routers and/or switches. This program will do *exactly* what you tell it to do. If your config entries are horky, then your configs will get horked! YOU HAVE BEEN WARNED! Ctrl+C at any time to abort, EOF &CONTINUE(); } ###################################################################### +### sub OLDPASSLIST { print <<EOF; ------------------------------------------ Prompting for existing passwords (*not* echoed to screen nor written to disk) EOF tie my %prompts, "Tie::IxHash"; %prompts = ( 'Enter existing password:' => 'oldpass', 'Enter existing enable password:' => 'olden', ); tie my %passwds, "Tie::IxHash"; for my $prompt (keys %prompts) { print " $prompt "; ReadMode('noecho'); # don't echo to screen. chomp(my $input = <STDIN>); $passwds{$prompts{$prompt}} = $input; ReadMode(0); # re-activate screen ech +o. print "\n"; } print "\n"; $oldpass = ($passwds{"oldpass"}); $olden = ($passwds{"olden"}); } ###################################################################### +### sub NEWPASSLIST { print " Change passwords? (y or n) "; $yn = 'n'; chomp($yn = <STDIN>); if ($yn eq ('y' or 'Y' or 'yes' or 'YES')) { # only do this if ch +anging passwords print " Prompting for new passwords\n"; print " (*not* echoed to screen nor written to disk)\n"; tie my %newprompts, "Tie::IxHash"; %newprompts = ( 'Enter new password:' => 'newpass', ' Retype password to confirm:' => 'confpass', 'Enter new enable password:' => 'newen', ' Retype enable to confirm:' => 'confen', ); tie my %newpasswds, "Tie::IxHash"; for my $newprompt(keys %newprompts) { print " $newprompt "; ReadMode('noecho'); # don't echo passwor +d to screen. chomp(my $input = <STDIN>); $newpasswds{$newprompts{$newprompt}} = $input; ReadMode(0); # re-activate screen + echo. print "\n"; } print "\n"; $newpass = ($newpasswds{"newpass"}); $confpass = ($newpasswds{"confpass"}); $newen = ($newpasswds{"newen"}); $confen = ($newpasswds{"confen"}); unless ( # Confirm new passwo +rds re-entered identically ("$newpass" eq "$confpass") and ("$newen" eq "$confen")) {&MISMATCHTEXT();} } } ###################################################################### +### sub CATORIOS { print "\n Hit \"c\" if CatOS devices or \"i\" if IOS devices: "; chomp(my $devtype = <STDIN>); if ($devtype eq ('c'|'C')) { $devtype = 'CatOS'; &SETPASSLISTCATOS(); } else { if ($devtype eq ('i'|'I')) { $devtype = 'IOS'; &SETPASSLISTIOS(); } else { print " D'ot! Only two choices - \"i\" or \"c\". +Try again..."; &CATORIOS(); } } print " You selected $devtype.\n\n"; &CONTINUE(); } ###################################################################### +### sub SETPASSLISTIOS { @setpass = ( "conf t", "enable pass $newen", "line con 0", "pass $newpass", "login", "line aux 0", "pass $newpass", "login", "line vty 0 4", "pass $newpass", "login", "line vty 5 9", "pass $newpass", "login", "line vty 10 15", "pass $newpass", "login", "end", "write mem", ); } ###################################################################### +## sub SETPASSLISTCATOS { @setpass = ( "set enablepass $newen", "set pass $newpass", ); } ###################################################################### +## sub MISMATCHTEXT { print " D'oh! Password confirmation(s) didn't match!\n"; print " Run this program again if you want, and try not to fatfin +ger it next time!\n\n"; exit; # "exit" instead of "die" so no error to console. } ###################################################################### +### sub CONFEXT { open (CONF, "<$conf") or die " ciscoconf.pl: Error opening $conf + for read: $!"; while (<CONF>) { next if /^#/ or /^\s.*$/ or /^!/; # ignore comment lines chomp; if (/^\[([^\]]+)\]/) { $section = $1; next; } else { if ($section =~ /timeout/i) { push @timeout,$_; } if ($section =~ /targets/i) { push @targets,$_; } if ($section =~ /commands/i) { push @commands,$_; } } } close (CONF) or die " ciscoconf.pl: Error closing $conf after re +ad: $!"; } ###################################################################### +### sub STARTCLEAN { # so we're not appending to exi +sting file(s) if (-e $tmp and -f _) { print " Unlinking $tmp from prior (aborted) program run.\n"; &CONTINUE(); unlink ($tmp) or die " ciscoconf.pl: Error unlinking $tmp: $! +" } if (-e $log and -f _) { print " Unlinking $log from prior program run.\n"; &CONTINUE(); unlink ($log) or die " ciscoconf.pl: Error unlinking $log: $! +" } } ###################################################################### +### sub STARTTEXT { print "\n These devices are targeted for configuration:\n"; print " (listed by DNS name or IP address)\n"; foreach $target (@targets) { print " $target\n" } &CONTINUE(); print "\n These commands will be sent to above devices:\n"; print " (Password changes not shown)\n"; foreach $command (@commands) { print " $command\n" } print "\n This is your LAST CHANCE to abort cleanly.\n"; &CONTINUE(); } ###################################################################### +### sub ENDCLEAN { if (-e $tmp and -f _) { unlink ($tmp) or die " ciscoconf.pl: Error unlinking $tmp: $! +" } } ###################################################################### +### sub ENDTEXT { print "\n Finished updating device configs.\n"; print " Review $log to confirm your commands did what you intende +d.\n\n"; } ###################################################################### +### sub CONTINUE { print " <enter> to continue...\n"; my $continue = <STDIN>; } ###################################################################### +### sub PCTIME { printf LOG " PC localtime is %d:%d:%d %d-%d-%d\n", localtime -> hour(), localtime -> min(), localtime -> sec(), localtime -> mon()+1, localtime -> mday(), localtime -> year()+1900, ; } ###################################################################### +### sub LOGREGX { umask oct 133; # logfile wo +rld-readable. Like "chmod 644" open (TMP, "<$tmp") or die " ciscoconf.pl: Error opening $tmp +for read: $!"; open (LOG, ">> $log") or die " ciscoconf.pl: Error opening $log +for append: $!"; &PCTIME(); print LOG "##########################################\n"; while (<TMP>) { foreach my $regex(@regex) { s/$regex//g; } if ($yn eq ('y' or 'Y' or 'yes' or 'YES')) { # only do th +is if changing passwords s/($newpass|$newen)/*****/g; # x-over pas +swords in $log } print LOG $_; } print LOG "\n##########################################\n"; &PCTIME(); close (TMP) or die " ciscoconf.pl: Error closing $tmp after +read: $!"; close (LOG) or die " ciscoconf.pl: Error closing $log after +append: $!"; } ###################################################################### +### =head1 name ciscoconf.pl =head1 Updated February 26, 2001 September 14, 2000 =head1 Summary Automate mass config changes (password updates, etc.) for any number of Cisco routers or switches. Accepts no command-line switches +. Target devices, command list, and comm timeout specified in $conf exte +rnal config file. Presents user with list of target devices and commands, +before proceeding. Records all sessions to common log file, with password up +dates stripped out. Comments or suggestions for improvement are very much w +elcomed. =head1 Usage ciscoconf.pl<enter> =head1 Tested with: Perl 5.00503 Debian 2.2 Espy against: Cisco 2514 - IOS 12.0(8) Catalyst 2924 - IOS 11.2(8)SA5 not yet: Catalyst 3500, 2948g, 5000, 6000 =head1 Troubleshooting use Data::Dumper; open (DUMP, "> ciscoconfext.dump") or die " ciscoconf.pl: Error opening ciscoconfext.dump for write +: $!"; print DUMP Dumper($timeout), "\n"; print DUMP Dumper(@targets), "\n"; print DUMP Dumper(@commands), "\n"; close (DUMP) or die " ciscoconf.pl: Error closing ciscoconfext.dump after wri +te: $!"; &CONTINUE(); =head1 Todos Verbify function names for greater legibility Add "waitfor()" to handler interactive password prompt of CatOS from Network Programming with Perl p151 Do "set leng 0" vs. "term leng 0" vi &CATORIOS() instead of in $conf Replace "roll-your-own" [ar0n] parser with AppConfig CPAN module [Bo +redByPolitics] Exclude "end, write mem, copy run start, disa" from $conf parsing as they are included in this program Cwd to set directory for $conf, $tmp, $log files [merlyn] File::Temp for, um... tempfile [tilly] Flock temp file (until File::Temp) Parse log for errors: Failed, error, timeout, expired, Invalid input, Cannot find communi +ty Timeout if wait too long for keyboard input Disable kb entry whil proggy running (except for CTRL+C to halt) =head1 Author [ybiC] =head1 Credits Examples and suggestions from the following helped a bunch: Joshua Keroes, [ar0n], [chromatic], [merlyn], [Fastolfe], [tilly], [mirod], and [BoredByPolitics]. Oh yeah, and some guy named [vroom]. Although they may not want that to be public knowledge ;^) www.perlmonks.org search.cpan.org/search?dist=Net-Telnet-Cisco search.cpan.org/search?dist=TermReadKey search.cpan.org/search?dist=Tie-IxHash =head1 Example $conf !! Program prompts user for $newpass $newen $newRO !! !! Comment lines start with "!" or "#" or " " !! !! Everything else except for [Sections] targets and timeout !! !! will be sent directly to router/switch as a command. !! ! [Timeout] !! Seconds to wait for device response !! !! Set short as practical for quickest program run !! !! ~20 for LAN device, more for WAN device !! !! Low-end routers may take 15-20 seconds to "write mem" !! not counting communications latency !! Default of 30 seconds if none specified here. 20 ! [Targets] !! one device name/address per line !! !! fqdn !! !! unqualified_device_name !! !! device_IP_address !! 10.0.0.1 10.254.254.254 ! [Commands] sho clo !! CatOS !! set leng 0 !! IOS !! term leng 0 conf t no service password-encryption logging buffered errors logging console errors logging console ! logging trap errors ! logging syslog_server ! ip name-server dns_server_address ! ip name-server another_dns_server_address ! ip domain-name domain_name no snmp-server community private no snmp-server community secret !snmp-server host some_host contact some_body new_RO ! ntp server ntp_server clock summer-time CST recurring no service udp-small-servers no service tcp-small-servers no banner login !! start banner with ^ and end with ^C !! banner login ^login banner^C no banner motd banner motd ^motd banner^C !! Do Not UnComment The Last Four Lines !! !! They Are Included In The Program Itself !! !! Run Here You Fall Down Go Boom !! !! end !! !! write mem !! !! disa !! !! sho clo !! =cut

In reply to (code)) Cisco Pass Mass - IOS (deprecated by node 123464) by ybiC

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2024-04-19 04:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found