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