Scripting

Cisco Nexus Switch Backups with Perl SNMP

24

I’ve spent some time over the past few days trying to get our home grown Perl script designed to backup all our network switches to work with the Cisco Nexus 7010 and 5010 switches.

With previous Cisco switches such as the 6509, 3750, 2960, etc we know that the following commands (when sent via a Perl script using the Net-SNMP Perl module) would instruct the switch to copy it’s running-config to a TFTP server.

snmpset -v1 -c$COMMUNITY $HOST ccCopyProtocol.$RANDOM i 1
snmpset -v1 -c$COMMUNITY $HOST ccCopySourceFileType.$RANDOM i 4
snmpset -v1 -c$COMMUNITY $HOST ccCopyDestFileType.$RANDOM i 1
snmpset -v1 -c$COMMUNITY $HOST ccCopyServerAddress.$RANDOM a "10.1.1.50"
snmpset -v1 -c$COMMUNITY $HOST ccCopyFileName.$RANDOM s "sw-train-acme.cfg"
snmpset -v1 -c$COMMUNITY $HOST ccCopyEntryRowStatus.$RANDOM i 1
sleep 5
snmpget -v1 -c$COMMUNITY $HOST ccCopyState.$RANDOM
#if not successful sleep 3 and re-check ccCopyState else continue and destroy table entry
snmpset -v1 -c$COMMUNITY $HOST ccCopyEntryRowStatus.$RANDOM i 6

I know that the both the Cisco Nexus 7010 and 5010 both balk at the SNMP OIDS/MIBS used above. So I’m searching for a set of equivalent SNMP OIDS/MIBS as those in CISCO-CONFIG-COPY-MIB for NX-OS. I’m not sure that such a OID/MIB even exists for NX-OS but it doesn’t hurt to search and ask.

I’m curious if anyone else has come across this issue? I know that there is an XML interface available but I would prefer to keep using the PERL/SNMP script that I’ve already developed. In the interim I’ll probably write an Expect script (or add some Expect code to my existing Perl script) to remotely connect to the switches and issue the appropriate copy commands.

Cheers!

Updated: Monday June 27, 2011

I’ve finally found the issue and now I’m able to backup the Cisco Nexus switches as expected.

ASCII Configuration Generator (ACG) for Nortel Switches

12

I wrote a Perl script a long time ago to backup the binary configuration files for all our Nortel Ethernet and Ethernet Routing Switches (including BayStack 350 and 450s, Ethernet Switch 460 and 470s, Ethernet Routing Switch 4500s and Ethernet Routing Switch 5500s, Ethernet Routing Switch 1600 and 8600s along with Motoroal WS5100 and RFS7000s and HP GbE2s). The Perl script was very simple and straightforward. The problem was that the Nortel configuraiton files were binary files that we as engineers were unable to review or analyze. There were no tools (at least not that I’m aware of) that could allow us to review those configurations. If we had a question about the configuration stored in the binary file we had to restore the configuration to a mock up switch(s) in our testlab in order to be able to review the actually configuration. It seems that Nortel finally heard our cries for help and added a new feature in v3.7.x (ES460/ES470) and v5.1.x (ERS5500) software that would allow us to TFTP upload the ASCII configuration from the ACG.

There was one problem though… the SNMP OID has yet to be documented in the Nortel SNMP MIBS. I had to run a packet trace against Nortel’s Device Manager to determine the OID that Device Manager was using to initiate the manual config upload. I found that the OID was ”
1.3.6.1.4.1.45.1.6.4.4.19.0″

I took my existing script and created a new subroutine and had everything working within about 30 minutes.

Here’s some of the code I wrote;

############################################################################
# Subroutine baystack_tftp_config_ascii
#
# Purpose: use SNMP to instruct BayStack switches to TFTP upload their
# ASCII configuration file to the central TFTP server
############################################################################
sub baystack_tftp_config_ascii {

#s5AgSysTftpServerAddress
#s5AgSysAsciiConfigFilename
#s5AgSysAsciiConfigManualUpload (NOT IN THE MIBS) USE 1.3.6.1.4.1.45.1.6.4.4.19.0
# snmpset -v2c -cprivate 10.1.1.100 1.3.6.1.4.1.45.1.6.4.4.19.0 i 4

   # Declare Local Variables
   my $setresult;

   $filename = "ascii/".$filename;

   my $sess = new SNMP::Session (  DestHost  => $snmphost,
                                   Community => $community,
                                   Version   => SNMPVER );

   my $vars = new SNMP::VarList(
                        ['s5AgSysTftpServerAddress', 0, "10.1.1.20",],
                        ['s5AgSysAsciiConfigFilename', 0, $filename,] );

   my $go = new SNMP::VarList(
                        ['.1.3.6.1.4.1.45.1.6.4.4.19', 0, 4, 'INTEGER'] );

   &check_filename($filename);

   # Set TFTP source and destination strings
   $setresult = $sess->set($vars);
   if ( $sess->{ErrorStr} ) {
      print "ERROR: {BayStack} problem setting the TFTP parameters (TFTP IP, FILENAME) for $snmphost\n";
      print "ERROR: {BayStack} sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }

   # Start TFTP copy
   $setresult = $sess->set($go);
   if ( $sess->{ErrorStr} ) {
      print "ERROR: {BayStack} problem setting the TFTP action bit for $snmphost\n";
      print "ERROR: {BayStack} sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }

   # Pause while the TFTP copy completes
   sleep $PAUSE;

   # Check to see if the TFTP copy completed
   $setresult = $sess->get('.1.3.6.1.4.1.45.1.6.4.4.19.0');
   if ( $sess->{ErrorStr} ) {
      print "ERROR: problem checking the TFTP result for $snmphost\n";
      print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n";
   }

   # If TFTP failed output error message
   if ($setresult != 1) {
        while ($setresult == 2) {
           print "DEBUG: config upload status = $setresult (waiting)\n" if (DEBUG);
           sleep $PAUSE;
           $setresult = $sess->get('.1.3.6.1.4.1.45.1.6.4.4.19.0');
        } #end while
   } #end if $test ne "success"

   # If the upload command failed let's try again
   if ($setresult == 3) {

      print "DEBUG: initial command returned $setresult\n" if (DEBUG);
      print "DEBUG: lets try the upload command again\n" if (DEBUG);

      # Let's pause here for a few seconds since the previous command failed
      sleep $PAUSE;

      # Start TFTP copy
      $setresult = $sess->set($go);
      if ( $sess->{ErrorStr} ) {
         print "ERROR: problem setting the TFTP action bit for $snmphost\n";
         print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n";
      }

      # Pause while the TFTP copy completes
      sleep $PAUSE;

      # Check to see if the TFTP copy completed
      $setresult = $sess->get('.1.3.6.1.4.1.45.1.6.4.4.19.0');
         if ( $sess->{ErrorStr} ) {
            print "ERROR: problem checking the TFTP result for $snmphost\n";
            print "ERROR: sess->{ErrorStr} = $sess->{ErrorStr}\n";
      }

      # If TFTP failed output error message
      if ($setresult != 1) {
         while ($setresult == 2) {
            print "DEBUG: config upload status = $setresult (waiting)\n" if (DEBUG);
            sleep $PAUSE;
            $setresult = $sess->get('.1.3.6.1.4.1.45.1.6.4.4.19.0');
         } #end while
      } #end if
   } #end if

   if ($setresult != 1) {
      print "DEBUG: $snmphost config upload *FAILED*!\n";
      print SENDMAIL "ERROR:$snmphost ($sysObjectID) config (ASCII) upload *FAILED*!
\n";
   } elsif ($setresult == 1) {
      print SENDMAIL "$snmphost ($sysObjectID) was successful (ASCII)
\n";
      print "DEBUG: $snmphost ($sysObjectID) was successful (ASCII)\n";
   } else {
      print "DEBUG: unknown error return = $setresult (ASCII)" if (DEBUG);
   } #end if

   print "DEBUG: upload config file results = $setresult (ASCII)\n" if (DEBUG);

   return 1;

} #end sub baystack_tftp_config_ascii

Cheers!
Update: Friday April 10, 2009

I’ve discovered a small issue using the MIB “s5AgSysAsciiConfigFilename”. While the MIB says the value can be between 0..128 characters long I’ve actually found that the value can’t be an longer than 30 characters. If you try to use a filename that is greater than 30 characters you’ll get an SNMP set error. I actually had quite a few switches failing to backup properly because I was prepending “ascii/” to the filename. I tested this with software v3.7.2.x and v3.7.3.x on a Ethernet Switch 470.

s5AgSysAsciiConfigFilename OBJECT-TYPE
        SYNTAX  DisplayString (SIZE (0..128))
        MAX-ACCESS      read-write
        STATUS  current
        DESCRIPTION
                "Name of the ascii configuration file that will be
             downloaded/uploaded either at boot time when the
             s5AgSysAsciiConfigAutoDownload object is set to
             useConfig(3), or when the s5AgSysAsciiConfigDownloadStatus
             object is set to startDownload(4).  When not used, the
             value is a zero length string."
        ::= { s5AgentSystem 6 }

Cheers!

Expect Scripts for ERS8600 Troubleshooting

1

Whenever you contact Nortel, Cisco or Juniper support these days your going to need to spend some time and effort collecting a fair amount of information for the engineer assigned to your case.

I’ve written a very simple Expect script that will telnet into a Nortel Ethernet Routing Switch 8600 and issue a series of commands saving all the output so you can forward it to Nortel (or examine it yourself offline).

#!/usr/bin/expect -f
#
# Filename: /usr/local/etc/8600dump.exp
#
# Purpose:  Dump technical information from Nortel Ethernet Routing Switch
#           via telneting to the device and issuing various "show" cmds.
#           The output will then be saved to the working directory using
#           a filename based on the switch name used to call the script.
#
# Language: Expect
#
# Author:   Michael McNamara
#
# Date:     May 6, 2003
#
# Changes:
#
#   Sept 29, 2006: cleaned up script/updated documentation
#    Dec 30, 2005: added command line arguments for portability
#    Mar 18, 2005: added file logging for troubleshooting and monitoring
#    May 20, 2003: fine tuned script removing a great many "expect" commands.
#    May  6, 2003: original Expect script generated from auto_expect
#
# Notes:
#        Command Line Reference;
#          ./8600dump.exp <switch> <username> <password>
#
# This Expect script was generated by autoexpect on Thu Aug 18 10:57:50 2005
# Expect and autoexpect were both written by Don Libes, NIST.
#
# 

set force_conservative 0  ;# set to 1 to force conservative mode even if
              ;# script wasn't run conservatively originally
if {$force_conservative} {
    set send_slow {1 .1}
    proc send {ignore arg} {
        sleep .1
        exp_send -s -- $arg
    }
}

#
# Declare Global Variables
#
set PATH "/usr/local/etc/"
set TELNET "/usr/bin/telnet"

#
# Assign Command Line Variablbes
#
set SWITCH [lindex $argv 0]
set USERNAME [lindex $argv 1]
set PASSWD [lindex $argv 2]

#
# Time Date Stamp
#
set TODAY [timestamp -format %y%m%d ]
set WEEKDAY [timestamp -format %a ]
set DATE [timestamp -format %c ]

set send_human {.1 .3 1 .05 2}

######################################################################
# proc usage
#
# Purpose: display the usage information to the enduser.
######################################################################
proc usage {} {
    send_user "\n"
    send_user "ERROR: command line paramaters incorrect\n"
    send_user "\n"
    send_user "usage: 8600dump.exp <switch> <username> <password>\n"
    send_user "\n"
    send_user "    switch        the DNS or IP address of switch    \n"
    send_user "    username        the username for login to the switch    \n"
    send_user "    password        the password for username\n"
    send_user "\n"
    send_user "\n"
    exit
}
#######################################################################

#######################################################################
# M A I N    P R O G R A M
#######################################################################

if {[llength $argv]!=3} usage

log_file $PATH/$SWITCH.dump.log
log_user 0      # Disable logging to STDOUT
#log_user 1     # Enable logging to STDOUT

# Useful information out to logfile
send_log "******************************************************************\r\n"
send_log "* STARTING LOGFILE FOR $SWITCH ON $DATE         \r\n"
send_log "******************************************************************\r\n"

set timeout -1
spawn $TELNET $SWITCH
match_max 100000
expect "Connected to"
expect "Login: "
send -- "$USERNAME\r"
expect "Password: "
send -- "$PASSWD\r"
expect -re "\:.\#|> "

# DATE
send -- "date\r"
expect -re "\:.\#|> "

####################################################
# YOU CAN ADD AND REMOVE COMMANDS AS YOU SEE FIT
####################################################

# CONFIG CLI MORE FALSE
send -- "config cli more false\r"
expect -re "\:.\#|> "

# SHOW TECH
send -- "show tech\r"
expect -re "\:.\#|> "

# SHOW CONFIG
send -- "show config\r"
expect -re "\:.\#|> "

# SHOW SYS TOPO
send -- "show sys topo\r"
expect -re "\:.\#|> "

# SHOW
send -- "show ports error show-all\r"
expect -re "\:.\#|> "

# SHOW PORT ERROR MAIN
#send -- "show port error main\r"
#expect -re "\:.\#|> "

# SHOW PORT ERROR EXT
#send -- "show port error ext\r"
#expect -re "\:.\#|> "

# SHOW IP ROUTE INFO ALTERNATIVE
#send -- "show ip route info alternative\r"
#expect -re "\:.\#|> "

# SHOW IP BGP SHOW-ALL
#send -- "show ip bgp show-all\r"
#expect -re "\:.\#|> "

# DATE
send -- "date\r"
expect -re "\:.\#|> "

send -- "logout\r"
expect eof

#######################################################################
# E N D    P R O G R A M
#######################################################################

You can also download the complete Expect script from my website here.

Occasionally you might have multiple switches that you’ll need to interrogate and for that I’ve written a quick and dirty little Bash shell script to loop through the FQDN of the switches calling the Expect script above.

#!/bin/sh
#
# Filename: /usr/local/etc/8600dump.sh
#
# Purpose:  Dump technical information from Nortel Ethernet Routing Switch
#           via telneting to the device and issuing various "show" cmds.
#           The output will then be saving to the working directory using
#           a filename based on the switch name used to call the script.
#
# Language: Bash Script
#
# Author:   Michael McNamara
#
# Date:     May 6, 2003
#
# Changes:
#
#   Sept 29, 2006: cleaned up script/updated documentation
#    Dec 30, 2005: added command line arguments for portability
#    Mar 18, 2005: added file logging for troubleshooting and monitoring
#    May 20, 2003: fine tuned script removing a great many "expect" commands.
#    May  6, 2003: original Expect script generated from auto_expect
#
# Notes:
#        Command Line Reference;
#          ./8600dump.sh
#
# There are system and network specific variables below. Obviously the "PATH"
# to the location of the Bash script and supporting Expect script. The location
# of MUTT if email is used and most importantly the username and password to the
# Nortel Ethernet Routing Switch 8600. I would highly suggest using the ro (ReadOnly)
# account for all scripting purposes that are "read-only" in nature. The last most
# obvious piece is the list of switches that you'd like the script run against.
#

# Global Variables
PATH_TO=/usr/local/etc/mlh
DUMP=8600dump.exp
MAIL_LIST=''
PAGER_LIST=''
ERROR_FLAG=0
MAILEXE='/usr/bin/mutt'
MAILTXT='/tmp/mutt.txt'
LOCKFILE=/tmp/trace.lck
USERNAME=ro
PASSWORD=

SWITCHES='switch1.domain switch2.domain'

#############################################################################
#  B E G I N   M A I N
#############################################################################

for SWITCH in $SWITCHES
do
    $PATH_TO/$DUMP $SWITCH $USERNAME $PASSWORD
    $MAILEXE -s "ALERT: Dump Report for $SWITCH" $MAIL_LIST -a $PATH_TO/$SWITCH.trace.log < $MAILTXT
done

exit
#############################################################################
#  E N D   M A I N
#############################################################################

You can also download the complete shell script here.

The use of Expect really helps save me a lot of time and it speeds up the troubleshooting process with the vendor.

Cheers!

Go to Top