1827412 Members
4466 Online
109965 Solutions
New Discussion

Re: OK...

 
SOLVED
Go to solution
Rob Johnson_3
Regular Advisor

OK...

I want to put a script together that will do this:
1. Read the Cisco devices from a file I create:
host1.domain.com
host2.domain.com
host3.domain.com
2. For each device in this list do snmpgets to get:
a. how many ports for each device
b. a port description for each port
c. the oper status for each port
d. the admin status for each port
e. the last change status for each port
3. I want the output to be in a CSV format so the file can be opened with excel. I could then place a., b., c., d. and e. in seperate columns. If there are 48 ports on a switch, there would be 48 rows and 5 columns for each row.

Can you guys help me get started?
6 REPLIES 6
H.Merijn Brand (procura
Honored Contributor

Re: OK...

http://search.cpan.org/~maxb/SNMP-Info-0.9.0/

Is a perl SNMP module that has support for Cisco routers:
http://search.cpan.org/author/MAXB/SNMP-Info-0.9.0/Info/Layer3/Cisco.pm

There are quite a few perl modules that deal with Cisco:
http://search.cpan.org/search?query=Cisco&mode=all

http://search.cpan.org/search?query=Cisco+SNMP&mode=all

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
Bob_Vance
Esteemed Contributor

Re: OK...

Here's a start.
I don't know exactly what snmp commands you would run for "snmpgets" nor the actual snmp command request codes.
So, I just used "snmpgets" for the command and dummy command codes "sn_desc", "sn_ostat", etc.
You'll have to flesh it out with actual commands and codes


#
#------------
echoopt="" # for bash compatibility
cat /tmp/dev_list \
| while read dev trash
do

# headers
echo $echoopt "$dev,pnum,desc,ostat,astat,cstat"
nport=$(snmpgets $dev num_ports )
#nport=3 # for testing

p=0
while [ $p -lt $nport ]
do

echo $echoopt ",$p\c" ;

for sn_req in \
sn_desc \
sn_ostat \
sn_astat \
sn_cstat \
# end snmp req commands
do

result=$(snmpgets $dev sn_req )
#result="$sn_req" # for testing
echo $echoopt ",\"$result\"\c"

done
echo # get rid of last \c

p=$(($p+1))
done
done
#------------


hth
bv
"The lyf so short, the craft so long to lerne." - Chaucer
Rob Johnson_3
Regular Advisor

Re: OK...

for device in `cat /opt/home/johnsonr/scripts/nodes`
do
snmpget $device public interfaces.ifTable.ifEntry.ifIndex.0
snmpget $device public interfaces.ifTable.ifEntry.ifDescr.0
snmpget $device public interfaces.ifTable.ifEntry.ifAdminStatus.0
snmpget $device public interfaces.ifTable.ifEntry.ifOperStatus.0
snmpget $device public interfaces.ifTable.ifEntry.ifDescr.0
snmpget $device public interfaces.ifTable.ifEntry.ifLastChange.0
done

I couldnâ t really understand everything in the script given by Mr. Vance so I think Iâ m going to have to do something like this. I wasnâ t made to be a programmer so I have to stay very simple.

How can I separate the returned value on each line with a comma?
Muthukumar_5
Honored Contributor

Re: OK...

You can collect return values as,

index=0
for device in `cat /opt/home/johnsonr/scripts/nodes`
do
snmpget $device public interfaces.ifTable.ifEntry.ifIndex.0
ret1[$index]=$?","
snmpget $device public interfaces.ifTable.ifEntry.ifDescr.0
ret2[$index]=$?","
snmpget $device public interfaces.ifTable.ifEntry.ifAdminStatus.0
ret3[$index]=$?","
snmpget $device public interfaces.ifTable.ifEntry.ifOperStatus.0
ret4[$index]=$?","
snmpget $device public interfaces.ifTable.ifEntry.ifDescr.0
ret5[$index]=$?
snmpget $device public interfaces.ifTable.ifEntry.ifLastChange.0
ret6[$index]=$?
let index=index+1
done

# Return value
echo ${ret1[*]}
echo ${ret2[*]}
echo ${ret3[*]}
echo ${ret4[*]}
echo ${ret5[*]}
echo ${ret6[*]}

hth.
Easy to suggest when don't know about the problem!
Rob Johnson_3
Regular Advisor

Re: OK...

The snmpget values I have in right now are just for testing purposes. I will change them when I found out exactly what to enter to get what I'm looking for for everything I want to get back. For now, I'm using sysName, one interfaces description, it's admin and oper status.

The script and the output when I run the script are below. I only have one device in the nodes file I'm cat 'ing' out for simplicity.

It doesn't look like each value returned is putting a comma in. Any ideas?

johnsonr@nmscrme01 > cat snmptest2
index=0
for device in `cat /opt/home/johnsonr/scripts/nodes`
do
snmpwalk $device VER143r system.sysName.0
ret1[$index]=$?","
snmpwalk $device VER143r interfaces.ifTable.ifEntry.ifDescr.1
ret2[$index]=$?","
snmpwalk $device VER143r interfaces.ifTable.ifEntry.ifAdminStatus.1
ret3[$index]=$?","
snmpwalk $device VER143r interfaces.ifTable.ifEntry.ifOperStatus.1
ret4[$index]=$?","
let index=index+1
done
johnsonr@nmscrme01 > ./snmptest2
system.sysName.0 = lcacptc18-mob1.2.cpt.ca.kp.org
interfaces.ifTable.ifEntry.ifDescr.1 = FastEthernet0/1
interfaces.ifTable.ifEntry.ifAdminStatus.1 = up(1)
interfaces.ifTable.ifEntry.ifOperStatus.1 = down(2)
johnsonr@nmscrme01 >

Bob_Vance
Esteemed Contributor
Solution

Re: OK...

OK (;>)

I'll explain my script a little bit.

NOTE1:
In general, it's better to do an in-line read of a file to get values as I did with with the

cat file| while read ...

loop, than to do the

for x in `cat file`

loop that you did.
Using `...` means that all of the file's contents would be placed in-line on 'for x' command as arguments as if you had typed it there.
What if the file were huge (in solving some other problem)??
On older versions of HPUX, the shell would overflow with not really much argument data.
True, the current shell can take much more (I think that it is 32meg, now), but I still think the "read" loop is better and cleaner.
Plus you could have a very complicated set of commands piped together ultimately piping into the 'while read' and it is visually more "readable' (no pun intended) this way.


NOTE2:
The shell 'read' command that I used places the next line of input into the variable(s) that you specify in the command. Each "word" on the line goes into the next-mentioned variable. When it runs out of your specified variable names, it puts the rest of the line into the last variable.
That's why I used 2 variables:
read device trash
.
If a line contained a hostname and then some additional stuff after it, such as comments, or whatever, then the "device" variable would have only the first word, while "trash" has the rest of the line.
The same result could be achieved via:

cat file \
| awk '{print $1}' \
|while read ....

or even

awk < file '{print $1}' \
|while read ....

but I just wanted to show the above technique.


NOTE3:
If you want to see what my script outputs:
. change the host file name from "/tmp/dev_list" to your actual file
. uncomment the 2 "for testing" lines
. comment the line preceding the 2 "for testing" lines.
)))


There are 3 loops:

------
loop1: reads the device_hostname_file

for each device from loop 1,

. print out a CSV header line:
",pnum,desc,ostat,astat,cstat"
(You would change these header names to your taste.
)
. get the number of ports on the device by some means -- I just had a dummy "snmpgets".
There may not be a simple "get_number_of_ports" snmp get command.


-----
loop2: loop thru the ports (0 thru number-1 from previous "get_number_of_ports" get).

for each port, get the 4 pieces of info you wanted via *another* loop


-----
loop3:
for each info you wanted, do a snmpget to obtain it:
sn_desc \
sn_ostat \
sn_astat \
sn_cstat \
These are just dummy snmpget command codes that I made up. You would have to substitute an actual snmpget and proper request code to obtain it.

Since this info is obtained by 4 different commands and we want to display them as CSV on one line, I 'echo'ed the results obtained with the "continuation" option (\c").
so each port line out looks like:

,,"p_desc","p_ostat","p_astat","p_cstat"

where each "p_item" is the results obtained from the snmpgets for that item.
Notice that the device_name column is empty.

Unfortunately, I don't have access to any snmp devices nor an OpenView system, so I can't flesh out any of the SNMP stuff.



hth
bv

"The lyf so short, the craft so long to lerne." - Chaucer