Fortsättning på det tidigare inlägget om Python & SNMP, tänkte komplettera med att spara ner resultatet till en databas istället för att endast skriva ut till terminalen.
Först installerar vi MySQL via “sudo apt-get install mysql” och python-plugin:et “python-mysqldb”.
Databasen vi vill sätta upp ser ut enligt följande:

När installationen är klar logga in med användaren du skapade:
mysql -h localhost -u root -p
Vi skapar sedan databasen my_network:
CREATE DATABASE my_network;
Och sedan tabellerna unit & interface:
USE my_network;
CREATE TABLE unit
(
id int unsigned NOT NULL auto_increment,
ip_address VARCHAR(16),
name VARCHAR(40),
model VARCHAR(40),
PRIMARY KEY (id),
UNIQUE (ip_address)
);
CREATE TABLE interface
(
id int unsigned NOT NULL auto_increment,
unit_id int unsigned NOT NULL,
name VARCHAR(40),
mac_address VARCHAR(40),
ip_address VARCHAR(16),
mask VARCHAR(16),
PRIMARY KEY (id)
);
Vilket ger följande resultat:
mysql> SHOW TABLES;
+----------------------+
| Tables_in_my_network |
+----------------------+
| interface |
| unit |
+----------------------+
2 rows in set (0.00 sec)
mysql> DESCRIBE unit;
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| ip_address | varchar(16) | YES | UNI | NULL | |
| name | varchar(40) | YES | | NULL | |
| model | varchar(40) | YES | | NULL | |
+------------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> DESCRIBE interface;
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| unit_id | int(10) unsigned | NO | MUL | NULL | |
| name | varchar(40) | YES | | NULL | |
| mac_address | varchar(40) | YES | | NULL | |
| ip_address | varchar(16) | YES | | NULL | |
| mask | varchar(16) | YES | | NULL | |
+-------------+------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
Vi kompletterar sedan koden med fetmarkerad text:
#!/usr/bin/env python
#Python
import netsnmp
import ipaddr
import sys
import subprocess
import MySQLdb
import prettytable
from prettytable import PrettyTable
checkarg = sys.argv[1:]
#Database
conn = MySQLdb.connect("localhost", "root", "netadm01", "my_network")
cursor = conn.cursor()
#Checks arguments and saves to variables
if len(checkarg) == 2:
cCommunity = checkarg[0]
cIP = checkarg[1]
print cCommunity, cIP
if isinstance(cCommunity, str):
try:
#Checks for valid IPv4-address
ccIP = ipaddr.IPv4Address(cIP)
try:
#Modelname
#Gets the Model-ID, returns numeric
cModelInt = subprocess.Popen([r"snmpwalk","-v2c","-Oqv","-c",cCommunity,cIP,"sysObjectID"],stdout=subprocess.PIPE).communicate()[0]
cModelSplit = cModelInt.split("::")
cModelSplit = cModelSplit[1].rstrip()
#Translate numeric Model-ID to string
cModel = subprocess.Popen([r"snmptranslate","-m","CISCO-PRODUCTS-MIB","-IR",cModelSplit],stdout=subprocess.PIPE).communicate()[0]
cModel = cModel.split("::")
#Name
oid = netsnmp.Varbind('sysName.0')
cName = netsnmp.snmpget(oid, Version = 2, DestHost = cIP, Community = cCommunity)
#Description
oid = netsnmp.Varbind('sysDescr.0')
cDesc = netsnmp.snmpget(oid, Version = 2, DestHost = cIP, Community = cCommunity)
#Output
print ""
print "Device info:"
print ""
print "Host:", ccIP
print "Model:", cModel[1].rstrip()
print "Name:", cName[0]
print cDesc[0]
print ""
try:
cursor.execute("INSERT INTO unit(ip_address,name,model) VALUES(%s,%s,%s)", (ccIP,cName[0],cModel[1].rstrip()))
conn.commit()
cID = cursor.lastrowid
print "Highest ID:",cID
except:
cursor.execute("SELECT id FROM unit WHERE ip_address=%s", (ccIP))
dbexists = cursor.fetchone()[0]
if cursor.rowcount > 0:
print ccIP, " Already exists in the database, cleaning up. ID: ", dbexists
try:
cursor.execute("DELETE FROM unit WHERE unit.id=%s", (dbexists))
conn.commit()
cursor.execute("DELETE FROM interface WHERE interface.unit_id=%s", (dbexists))
conn.commit()
try:
cursor.execute("INSERT INTO unit(ip_address,name,model) VALUES(%s,%s,%s)", (ccIP,cName[0],cModel[1].rstrip()))
conn.commit()
cID = cursor.lastrowid
print "Highest ID:",cID
except:
print "Unable to insert data"
except:
print "Delete failed"
pass
x = PrettyTable(["Interface", "IP", "Subnet", "MAC"])
x.align["Interface"] = "l"
x.align["IP"] = "l"
x.align["Subnet"] = "l"
#Index of all the interfaces
oid = netsnmp.Varbind("ifIndex")
cIndex = netsnmp.snmpwalk(oid, Version = 2, DestHost = cIP, Community = cCommunity)
#Index of all the interfaces with IP
oid = netsnmp.Varbind("ipAdEntIfIndex")
cIndexIP = netsnmp.snmpwalk(oid, Version = 2, DestHost = cIP, Community = cCommunity)
#IP-Adress list
oid = netsnmp.Varbind("ipAdEntAddr")
ipAdd = netsnmp.snmpwalk(oid, Version = 2, DestHost = cIP, Community = cCommunity)
#MAC for all interfaces
oid = netsnmp.Varbind("ifPhysAddress")
cMAC = netsnmp.snmpwalk(oid, Version = 2, DestHost = cIP, Community = cCommunity)
#Subnetmask for all IP interfaces
oid = netsnmp.Varbind("ipAdEntNetMask")
cNetmask = netsnmp.snmpwalk(oid, Version = 2, DestHost = cIP, Community = cCommunity)
looped = 0
#Prints out interface-details
for i in cIndex:
#Name of every interface
oid = netsnmp.Varbind("ifDescr."+i)
cIntName = netsnmp.snmpget(oid, Version = 2, DestHost = cIP, Community = cCommunity)
try:
#Matches interface-list with interface+IP-list
IPindex = cIndexIP.index(i)
try:
#Hex to readable
mac = cMAC[looped]
mac = ":".join( [ '%x'%(ord(c)) for c in mac ] )
#Prints row
x.add_row([cIntName[0], ipAdd[IPindex], cNetmask[IPindex], mac])
cursor.execute("INSERT INTO interface(unit_id,name,ip_address,mask,mac_address) VALUES(%s,%s,%s,%s,%s)", (cID,cIntName[0],ipAdd[IPindex],cNetmask[IPindex],mac))
conn.commit()
except:
pass
looped += 1
except:
try:
#Hex to readable
mac = cMAC[looped]
mac = ":".join( [ '%x'%(ord(c)) for c in mac ] )
#Prints row w/o IP
x.add_row([cIntName[0], '', '', mac])
cursor.execute("INSERT INTO interface(unit_id,name,mac_address) VALUES(%s,%s,%s)", (cID,cIntName[0],mac))
conn.commit()
except:
#Prints row w/o MAC & IP
x.add_row([cIntName[0], '', '', ''])
cursor.execute("INSERT INTO interface(unit_id,name) VALUES(%s,%s)", (cID,cIntName[0]))
conn.commit()
looped += 1
print x
#Close database
cursor.close()
conn.close()
try:
foutput = x.get_string()
f = open(cIP, "w")
f.write("Device info: " + cIP + "\nCommunity: " + cCommunity + "\n")
f.write("\nHost: " + cIP)
f.write("\nModel: " + cModel[1].rstrip())
f.write("\nName:" + cName[0])
f.write("\n" + cDesc[0])
f.write("\n" + foutput + "\n")
# f.writelines(x)
except:
print "Failed to write file"
finally:
f.close()
except:
print "SNMP-polling failed"
print x
except:
print "Invalid IP given:", cIP
else:
print "Invalid Community given (must be string)"
else:
print "Error - you must set both Community and IP (ex ./3a.py public localhost):"
Exempel på output:
Device info: 192.168.152.9
Community: public
Host: 192.168.152.9
Model: catalyst355024
Name:3550-1
Cisco Internetwork Operating System Software
IOS (tm) C3550 Software (C3550-I5Q3L2-M), Version 12.1(22)EA1a, RELEASE SOFTWARE (fc1)
Copyright (c) 1986-2004 by cisco Systems, Inc.
Compiled Fri 20-Aug-04 00:44 by yenanh
+--------------------+----------------+-----------------+-----------------+
| Interface | IP | Subnet | MAC |
+--------------------+----------------+-----------------+-----------------+
| FastEthernet0/1 | 192.168.152.2 | 255.255.255.252 | 0:a:b7:9c:93:80 |
| FastEthernet0/2 | | | 0:a:b7:9c:93:82 |
| FastEthernet0/3 | | | 0:a:b7:9c:93:83 |
| FastEthernet0/4 | | | 0:a:b7:9c:93:84 |
| FastEthernet0/5 | | | 0:a:b7:9c:93:85 |
| FastEthernet0/6 | | | 0:a:b7:9c:93:86 |
| FastEthernet0/7 | | | 0:a:b7:9c:93:87 |
| FastEthernet0/8 | | | 0:a:b7:9c:93:88 |
| FastEthernet0/9 | | | 0:a:b7:9c:93:89 |
| FastEthernet0/10 | | | 0:a:b7:9c:93:8a |
| FastEthernet0/11 | | | 0:a:b7:9c:93:8b |
| FastEthernet0/12 | | | 0:a:b7:9c:93:8c |
| FastEthernet0/13 | | | 0:a:b7:9c:93:8d |
| FastEthernet0/14 | | | 0:a:b7:9c:93:8e |
| FastEthernet0/15 | | | 0:a:b7:9c:93:8f |
| FastEthernet0/16 | | | 0:a:b7:9c:93:90 |
| FastEthernet0/17 | | | 0:a:b7:9c:93:91 |
| FastEthernet0/18 | | | 0:a:b7:9c:93:92 |
| FastEthernet0/19 | | | 0:a:b7:9c:93:93 |
| FastEthernet0/20 | | | 0:a:b7:9c:93:94 |
| FastEthernet0/21 | | | 0:a:b7:9c:93:95 |
| FastEthernet0/22 | | | 0:a:b7:9c:93:96 |
| FastEthernet0/23 | | | 0:a:b7:9c:93:97 |
| FastEthernet0/24 | 192.168.152.5 | 255.255.255.252 | 0:a:b7:9c:93:80 |
| GigabitEthernet0/1 | | | 0:a:b7:9c:93:99 |
| GigabitEthernet0/2 | | | 0:a:b7:9c:93:9a |
| Null0 | | | |
| Vlan1 | | | 0:a:b7:9c:93:80 |
| Vlan2 | 192.168.152.9 | 255.255.255.248 | 0:a:b7:9c:93:80 |
| Vlan10 | 192.168.152.17 | 255.255.255.240 | 0:a:b7:9c:93:80 |
| Vlan12 | 192.168.152.97 | 255.255.255.224 | 0:a:b7:9c:93:80 |
| Vlan15 | 192.168.152.65 | 255.255.255.224 | 0:a:b7:9c:93:80 |
| Vlan20 | 192.168.152.49 | 255.255.255.240 | 0:a:b7:9c:93:80 |
| Vlan25 | 192.168.152.33 | 255.255.255.240 | 0:a:b7:9c:93:80 |
| Vlan153 | 192.168.153.1 | 255.255.255.0 | 0:a:b7:9c:93:80 |
+--------------------+----------------+-----------------+-----------------+
Ska försöka hitta tillbaka till Cisco snart men eventuellt kommer det några kortare inlägg om Cacti/Nagios & EEM här framöver först. Fullt upp i jobbsökandet dessutom, den 18-19:e mars ska jag till Oslo för lite intervjuer som verkar riktigt spännande! 🙂