Cisco: Configuration save

Robert S. Galloway - Nagios Account nagios at the-galloways.us
Fri Feb 6 08:35:19 CET 2004


Check out Kiwi CatTools. It will do all of this and more.

Robert S. Galloway
Chief Network Security Engineer
IKANO Communications

On Fri, 2004-02-06 at 00:14, Peter Hicks wrote:
> Steinbacher Manfred wrote:
> 
> > I have many Cisco Systems (Routers and Switches).
> > 
> > Does anyone known that I can save the configuration of these system with 
> > nagios?
> > 
> > I also want to known which mac-addresses are in my network. We have same 
> > VLAN`s.
> > 
> > Can I do this with Nagios or any other tool?
> 
> Try the attached script, ios-copy.pl.  You will have to hack it around a 
> bit, as I wrote it and just pulled straight from one of our NOC boxes. 
> In particular, you'll need to work out how to pass SNMP community 
> strings without using a database.
> 
> The core functionality's there, its just a case of modifying it to work 
> outside NETMAN.  I might get to do this some day.
> 
> For monitoring MAC addresses on your LAN, look at the BRIDGE-MIB and in 
> particular the dot1dTpFdbTable, which contains a list of MAC addresses 
> and their corresponding switch ports.  I have scripts that will 
> automagically poll devices and record their bridge table, as well as 
> getting updates from the CISCO-MAC-NOTIFICATION-MIB traps.  This is in 
> less of a "I can email it to you" state because it doesn't work at the 
> moment.
> 
> Hope the attached script helps - email it back to me if you make any 
> changes and I'll incorporate them in to NETMAN (with credit).
> 
> Best wishes,
> 
> 
> Peter.
> 
> ______________________________________________________________________
> #!/usr/bin/perl -w
> #
> #  NETMAN - An Open Source Network Management System
> #  Copyright (C) 2003 Peter Hicks
> #
> #  This program is free software; you can redistribute it and/or
> #  modify it under the terms of the GNU General Public License
> #  as published by the Free Software Foundation; either version 2
> #  of the License, or (at your option) any later version.
> #
> #  This program is distributed in the hope that it will be useful,
> #  but WITHOUT ANY WARRANTY; without even the implied warranty of
> #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> #  GNU General Public License for more details.
> #
> #  You should have received a copy of the GNU General Public License
> #  along with this program; if not, write to the Free Software
> #  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
> #
> #  $Source: /home/cvsroot/netman/cisco-config/ios-copy.pl,v $
> #
> #  Request the configuration from a Cisco IOS device is copied to a
> #  TFTP server.
> #
> #  $Id: ios-copy.pl,v 1.5 2003/11/18 15:08:28 pwh Exp $
> #
> 
> use strict;
> use Netman;
> use Getopt::Long;
> 
> Netman::print_version();
> 
> 
> # Options parsing
> 
> my $verbose = 0;
> my $debug = 0;
> my $hostname;
> my $help;
> 
> GetOptions('verbose' => \$verbose, 'debug' => \$debug, 'hostname=s' => \$hostname, 'help' => \$help);
> 
> if($help) {
> 
> print <<ENDHELP;
> This script will copy a Cisco IOS device's configuration to a TFTP server
> and import the configuration in to the configuration database.
> 
> Commands:
> 
>  -d, --debug                    Show debugging information for troubleshooting
>  -v, --verbose                  Show detailed progress information
>      --help                     Display this help screen
>      --hostname [host]          Copy configuration for the specified host only
> 
> ENDHELP
> 
> 	exit;
> 
> };
> 
> 
> # Read in the configuration files
> 
> my %config = Netman::read_config();
> 
> 
> # Build an SQL query to find the devices from which to copy configurations
> 
> my $configcopy_query = "
> 			SELECT  devices.id AS id,
> 				devices.hostname AS hostname,
> 				devices.ip_address AS ip_address,
> 				devices.checks AS checks
> 
> 			FROM	devices
> 
> 			LEFT JOIN sites
> 			ON	devices.site_id = sites.id
> 
> 			LEFT JOIN management_systems
> 			ON	sites.poll_from = management_systems.id
> 
> 			WHERE   management_systems.hostname = '".$config{'node_config'}{'hostname'}."'
> 			AND	checks LIKE '%config-copy%'
> 			AND	devices.enabled = '1'
> 			";
> 
> # If a hostname has been specified on the command line, then append this to
> # the SQL query.
> 
> if($hostname) {
> 
> 	$configcopy_query = $configcopy_query . "AND devices.hostname LIKE '%".$hostname."%'";
> 
> };
> 
> 
> # Sort the data
> 
> $configcopy_query = $configcopy_query . "ORDER BY hostname";
> 
> 
> my $dbh = Netman::db_connect();
> 
> my $db_query = $dbh->prepare($configcopy_query);
> my $db_result = $db_query->execute;
> 
> if($db_query->rows == 0) {
> 
> 	print "No targets found.\n\n";
> 	print "  * Set 'config-copy' as a check for every host for you wish to maintain a copy\n";
> 	print "    of the configuration.\n\n";
> 	print "  * Make sure that the devices are configured to be at a location polled from this\n";
> 	print "    management system\n\n";
> 	print "  * If a hostname was specified in the command line, is this hostname set to be\n";
> 	print "    polled from this system?\n";
> 	print "\n\n";
> 
> 	exit 0;
> 
> } else {
> 
> 	while(my $row = $db_query->fetchrow_hashref) {
> 
> 		if($verbose) {
> 
> 			print "  * Copying from ".$row->{'hostname'}." (".$row->{'ip_address'}.")...\n";
> 
> 		} else {
> 
> 			print "  * Copying from ".$row->{'hostname'}."...\n";
> 
> 		};
> 
> 		my $device_info = Netman::device_info($row->{'hostname'});
> 
> 		my $result = get_configuration($device_info->{'hostname'}, $device_info->{'ip_address'}, $device_info->{'passwords'}{'snmpwrite'});
> 
> 		if($result eq 0) {
> 
> 			if($verbose) {
> 
> 				print "  * Copying configuration to SQL database... ";
> 
> 			};
> 
> 			my $tftp_filename = $config{'miscellaneous'}{'system_tftproot'}."/configs/".$device_info->{'hostname'};
> 
> 
> 			# Loop until the file size stops growing
> 
> 			my $old_tftp_size = 0;
> 			my $new_tftp_size = -1;
> 
> 			do {
> 
> 				sleep 1;
> 
> 				$old_tftp_size = $new_tftp_size;
> 				$new_tftp_size = -s $tftp_filename;
> 
> 				print "      - File is $new_tftp_size bytes\n" if $debug;
> 
> 			} until($new_tftp_size > $old_tftp_size);
> 
> 			open(CONFIG, "<".$tftp_filename) || warn "Could not open ".$tftp_filename;
> 
> 			my $config_text = "";
> 
> 			my $lines = 0;
> 
> 			while(<CONFIG>) {
> 
> 				chomp;
> 
> 				$config_text = $config_text . $_ . "\n";
> 
> 				$lines++;
> 
> 			};
> 
> 			print "      - Read $lines lines from configuration\n" if $debug;
> 
> 			my $db_query = $dbh->prepare("
> 
> 							INSERT INTO	cisco_configs
> 									(device_id, config_text, updated)
> 
> 							VALUES('".$device_info->{'id'}."', ".$dbh->quote($config_text).",
> 								UNIX_TIMESTAMP(NOW())
> 								)
> 
> 							");
> 
> 			$db_query->execute;
> 
> 			close(CONFIG);
> 
> 			if($verbose) {
> 
> 				print "OK\n";
> 
> 			};
> 
> 		} elsif($result eq -1) {
> 
> 			print "  * TFTP copy failed\n";
> 
> 		};
> 
> 	};
> 
> };
> 
> 
> sub get_configuration {
> 
> 	# Read in variables
> 
> 	my %config = Netman::read_config();
> 
> 	my $hostname = shift;
> 	my $ip_address = shift;
> 	my $write_community = shift;
> 
> 
> 	# Connect to the NETMAN datbase
> 
> 	my $db_handle = Netman::db_connect();
> 
> 
> 
> 	# Connect to the device using the SNMP read-write community string
> 	# as defined in the NETMAN database
> 
> 	if($debug) {
> 
> 		print "  * Connecting to $hostname ($write_community\@$ip_address)... ";
> 
> 	} elsif($verbose) {
> 
> 		print "  * Connecting to $hostname... ";
> 
> 	};
> 
> 	my $snmp_handle = new SNMP::Session(DestHost => $ip_address, Community => $write_community);
> 
> 
> 	# Retreive sysUptime.0 to check that the connection was successful
> 
> 	my @sysUpTime = [ ['sysUpTime', 0] ];
> 
> 	my $sysUpTimeValue = $snmp_handle->get(@sysUpTime);
> 
> 	if(!defined($sysUpTimeValue)) {
> 
> 		if($debug) {
> 
> 			print "failed - incorrect community string?\n"; 
> 
> 		} else {
> 
> 			print "failed.\n";
> 
> 		};
> 
> 		return -1;
> 
> 	} else {
> 
> 		print "OK\n" if $verbose;
> 
> 	};
> 
> 
> 	# Tell the user what we are doing
> 
> 	if($verbose) {
> 
> 		print "  * Copying configuration from device...\n";
> 
> 	};
> 
> 
> 	# Create an empty file in the TFTP root directory. The TFTP daemon will
> 	# not allow us to create files by default - it will only allow us to
> 	# overwrite files.
> 
> 	print "      - Creating skeleton TFTP file\n" if $debug;
> 
> 	system("touch ".$config{'miscellaneous'}{'system_tftproot'}."/configs/".$hostname."; chmod 777 ".$config{'miscellaneous'}{'system_tftproot'}."/configs/".$hostname."");
> 
> 
> 	
> 
> };
> 
> 
> sub netman_configcopy_writenet {
> 
> 	# Attempt to use SNMP writeNet, which is depreciated but still works
> 	# for some versions of IOS.  This method should be tried last as it
> 	# isn't possible to tell whether a device supports this method until
> 	# we try it.  Kinda like pulling the trigger of a gun to see if its
> 	# loaded.
> 
> 
> 	# Pull in the SNMP handle
> 
> 	my $snmp_handle = shift || die "No SNMP handle was passed to netman_configcopy_writenet()\n";
> 
> 
> 	print "      - Attempting to use SNMP writeNet (legacy)...\n" if $debug;
> 
> 	my @writeNet = [	['writeNet', '192.168.1.1', 'configs/'.$hostname, 'OCTETSTR']	];
> 
> 	my $writeNet = $snmp_handle->set(@writeNet);
> 
> 	my $writeNetErrorNum = $snmp_handle->{ErrorNum};
> 	my $writeNetErrorString = $snmp_handle->{ErrorStr};
> 
> 	if($writeNetErrorNum eq 0) {
> 
> 		if($verbose) {
> 
> 			print "  * Copy successful\n";
> 
> 		};
> 
> 		return 0;
> 
> 	} else {
> 
> 		print "      - Failed.\n" if $debug;
> 
> 	};
> 
> 
> 
> };
> 
> sub netman_configcopy_catos {
> 
> 	# Try to copy the device's configuration using the CISCO-STACK-MIB.
> 	# This method isn't as sey as the CONFIG-COPY-MIB, but we aren't
> 	# dealing with IOS here!
> 
> 
> 	# Pull in the SNMP handle
> 
> 	my $snmp_handle = shift || die "No SNMP handle was passed to netman_configcopy_writenet()\n";
> 
> 
> 	print "      - Attempting to use SNMP CatOS method...\n" if $debug;
> 
> 	my @tftpCatOS = [	['tftpHost', '0', '192.168.1.1', 'OCTETSTR'],
> 				['tftpFile', '0', 'configs/'.$hostname, 'OCTETSTR'],
> 				['tftpModule', '0', '1', 'INTEGER'],
> 				['tftpAction', '0', '3', 'INTEGER']
> 			];
> 
> 	my $tftpCatOS = $snmp_handle->set(@tftpCatOS);
> 
> 	my @tftpResult = [	['tftpResult', '0']	];
> 
> 
> 	print "      - Waiting for completion" if $debug;
> 
> 	$| = 1;
> 
> 	sleep 1;
> 
> 
> 	# Loop until tftpResult is not inProgress(1)
> 
> 	while($snmp_handle->get(@tftpResult) eq 1) {
> 
> 		print ".";
> 
> 		sleep 1;
> 
> 	};
> 
> 	print "\n";
> 
> 	$| = 0;
> 
> 	my $finaltftpResult = $snmp_handle->get(@tftpResult);
> 
> 	if($finaltftpResult eq 2) {
> 
> 		print "      - Success!\n" if $debug;
> 
> 		return 0;
> 
> 	} elsif($finaltftpResult eq 3) {
> 
> 		print "      - Error 3: No response from TFTP server\n" if $debug;
> 
> 		return -1;
> 
> 	} elsif($finaltftpResult eq 4) {
> 
> 		print "      - Error 4: Too many retries\n" if $debug;
> 
> 		return -1;
> 
> 	} elsif($finaltftpResult eq 16) {
> 
> 		print "      - Error 16: Access Violation\n" if $debug;
> 
> 		return -1;
> 
> 	};
> 
> };
> 
> sub netman_configcopy_configcopymib {
> 
> 	# Try to copy the device's configurating using the CONFIG-COPY-MIB.
> 	# This method provides the best feedback on completion and errors,
> 	# and full documentation is available at:
> 	#
> 	# http://www.cisco.com/warp/customer/477/SNMP/copy_configs_snmp.shtml
> 
> 
> 	# Pull in the SNMP handle
> 
> 	my $snmp_handle = shift || die "No SNMP handle was passed to netman_configcopy_configcopymib()\n";
> 
> 
> 	print "      - Attempting to use SNMP ccConfigCopy MIB...\n" if $debug;
> 
> 	my $rowIndex;
> 	my @rowIndexCheck;
> 	my $rowIndexCheckValue;
> 	my $rowIndexCheckError = 0;
> 	my $rowIndexCheckErrorString = "";
> 	my $rowIndexCheckErrorCount = 0;
> 
> 
> 
> 	# Choose a random number for the row index, and check whether this
> 	# index is already being used (will probably never happen, but best
> 	# to be safe).  If the row index is being used, retry five times and
> 	# then assume there's some other problem.
> 
> 	while($rowIndexCheckError ne 2 && $rowIndexCheckErrorCount lt 5) {
> 
> 		print "      - Finding a valid row index...\n" if $debug;
> 
> 		$rowIndex = int(rand(2**24));
> 
> 		print "      - Trying index $rowIndex...\n" if $debug;
> 
> 		@rowIndexCheck = [	['ccCopyEntryRowStatus', $rowIndex]	];
> 
> 		$rowIndexCheckValue = $snmp_handle->get(@rowIndexCheck);
> 
> 		my $rowIndexCheckError = $snmp_handle->{ErrorNum};
> 		my $rowIndexCheckErrorString = $snmp_handle->{ErrorStr};
> 
> 		if($rowIndexCheckError ne 2 && $rowIndexCheckErrorCount lt 5) {
> 
> 			print STDERR "      - Error '".$rowIndexCheckErrorString."' returned\n" if $debug;
> 
> 			$rowIndexCheckErrorCount++;
> 
> 		};
> 
> 	};
> 
> 
> 	# Bail out if we've hit five or more errors from above 
> 
> 	if($rowIndexCheckErrorCount ge 5) {
> 
> 		print STDERR "  * Too many errors - skipping!\n";
> 
> 		return -1;
> 
> 	};
> 
> 
> 	print "      - Using row index $rowIndex\n" if $debug;
> 
> 
> 	# Prepare an SNMP VarList of OIDs to set, then set them
> 
> 	print "      - Preparing SNMP sets\n" if $debug;
> 
> 	my @copyVarList = [	['ccCopyProtocol', $rowIndex, '1', 'INTEGER'], 
> 				['ccCopySourceFileType', $rowIndex, '4', 'INTEGER'],
> 				['ccCopyDestFileType', $rowIndex, '1', 'INTEGER'],
> 				['ccCopyServerAddress', $rowIndex, '192.168.1.1', 'IPADDR'],
> 				['ccCopyFileName', $rowIndex, 'configs/'.$hostname, 'OCTETSTR'],
> 				['ccCopyEntryRowStatus', $rowIndex, '4', 'INTEGER']
> 			];
> 
> 	$snmp_handle->set(@copyVarList);
> 
> 
> 	# Check to see if the SNMP set was successful
> 
> 	if($snmp_handle->{ErrorStr} ne "") {
> 
> 		print "      - SNMP set failed - ".$snmp_handle->{ErrorStr}."\n" if $debug;
> 
> 		return -1;
> 
> 	};
> 
> 
> 	# Keep tabs on the ccCopyState, printing a '.' for every 100ms that
> 	# the row is in the running(2) state
> 
> 	my @copyState = [	['ccCopyState', $rowIndex]	];
> 	my @copyFailCause = [	['ccCopyFailCause', $rowIndex]	];
> 
> 	print "      - Waiting for completion" if $debug;
> 
> 	$| = 1;
> 
> 	sleep 1;
> 
> 
> 	# Loop until ccCopyState is not running(2)
> 
> 	while($snmp_handle->get(@copyState) eq 2) {
> 
> 		print "." if $verbose;
> 
> 		sleep 1;
> 
> 	};
> 
> 	print "\n" if $verbose;
> 
> 	$| = 0;
> 
> 
> 	# Find out the final copy status and the fail cause
> 
> 	my $copyFinalStatus = $snmp_handle->get(@copyState);
> 	my $copyFailCause = $snmp_handle->get(@copyFailCause);
> 
> 
> 	# Check the final copy status
> 
> 	if($copyFinalStatus eq 3) {
> 
> 		return 0;
> 
> 	} elsif($copyFinalStatus eq 4) {
> 
> 		if($copyFailCause eq "1") { $copyFailCause = "Unknown error"; };
> 		if($copyFailCause eq "2") { $copyFailCause = "TFTP server returned an error"; };
> 		if($copyFailCause eq "3") { $copyFailCause = "TFTP server timeout"; };
> 		if($copyFailCause eq "4") { $copyFailCause = "Low memory on device"; };
> 		if($copyFailCause eq "5") { $copyFailCause = "Configuration not found"; };
> 		if($copyFailCause eq "6") { $copyFailCause = "Unsupported protocol"; };
> 		if($copyFailCause eq "7") { $copyFailCause = "Configuration application failed"; };
> 
> 		print "      - Configuration copy was unsuccessful - $copyFailCause\n" if $debug;
> 
> 		return -1;
> 
> 	} else {
> 
> 		print "      - Final status unknown (error code $copyFinalStatus)\n" if $debug;
> 
> 		return -1;
> 
> 	};
> 
> };



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
Nagios-users mailing list
Nagios-users at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nagios-users
::: Please include Nagios version, plugin version (-v) and OS when reporting any issue. 
::: Messages without supporting info will risk being sent to /dev/null





More information about the Users mailing list