Home Python & MySQL
Post
Cancel

Python & MySQL

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: database 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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:  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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! :)

This post is licensed under CC BY 4.0 by the author.

Python & SNMP

VRF-Lite & BGP