source: genesis/tools/get-link-traffic.py@ 10035

Last change on this file since 10035 was 10035, checked in by rick, 13 years ago

MultiManager dict is buggy.

  • Property svn:executable set to *
File size: 4.2 KB
RevLine 
[9987]1#!/usr/bin/env python
2#
3# XXX: Parsing snmpwalk is soo wrong todo, use a proper python library.
4#
[10035]5#
[9987]6# Rick van der Zwet <info@rickvanderzwet.nl>
7#
8import glob
9import logging
10import subprocess
11import sys
12import yaml
[9988]13from multiprocessing import Process, Manager, Pool, Queue, freeze_support
14
[9987]15logging.basicConfig(level=logging.DEBUG)
16logger = logging.getLogger()
17
[9988]18
19
[9987]20DATASTORE='store.yaml'
21
22class ConnectError(Exception):
23 pass
24
[9988]25def get_snmp_stats(logger, ip,target):
[9987]26 p = subprocess.Popen("snmpwalk -t 1 -r 1 -Oq -c public -v2c %s %s" % (ip, target),
27 shell=True,
28 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
29 (stdout, stderr) = p.communicate()
30 if p.returncode != 0:
31 logger.error(stderr.strip())
32 raise ConnectError
33 r = {}
34 for line in stdout.strip().split('\n'):
35 index = line.split()[0][len(target)+1:]
36 value = line.split()[1]
37 r[index] = value
38 return r
39
[9988]40def get_snmp_value(logger, ip, target):
[9987]41 p = subprocess.Popen("snmpget -t 1 -r 1 -Ovt -c public -v2c %s %s" % (ip, target),
42 shell=True,
43 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
44 (stdout, stderr) = p.communicate()
45 if p.returncode != 0:
46 logger.error(stderr.strip())
47 raise ConnectError
48 return stdout.strip()
49
[9988]50def find_right_snmp_ip(logger, data):
51 for k,v in data.iteritems():
52 if k.startswith('iface_'):
53 ip = v['ip'].split('/')[0]
54 logger.info("Trying ip %s", ip)
55 try:
56 uptime = get_snmp_value(logger, ip, 'DISMAN-EVENT-MIB::sysUpTimeInstance')
57 return ip
58 except ConnectError:
59 pass
60 return None
61
[9987]62try:
63 ff = sys.argv[1]
64except IndexError:
65 ff = ''
66
[10035]67def process_file(logger, m_snmp, m_traffic, m_uptime, nf, rescan):
[9988]68 data = yaml.load(open(nf,'r'))
69 nodename = data['nodename']
70
[10035]71 if m_snmp.has_key(nodename):
72 ip = m_snmp[nodename]
[9988]73 if not ip and rescan:
74 logger.info("Re-scanning for new valid IP")
75 ip = find_right_snmp_ip(logger, data)
[10035]76 m_snmp[nodename] = ip
[9987]77 else:
[9988]78 try:
79 uptime = get_snmp_value(logger, ip, 'DISMAN-EVENT-MIB::sysUpTimeInstance')
80 except ConnectError:
81 logger.info("Re-scanning for new valid IP")
82 ip = find_right_snmp_ip(logger, data)
[10035]83 m_snmp[nodename] = ip
[9988]84 else:
85 logger.info("Running discovery for %s", nodename)
86 ip = find_right_snmp_ip(logger, data)
[10035]87 m_snmp[nodename] = ip
[9987]88
[9988]89 if ip == None:
90 logger.error("No valid ip found for node %s", nodename)
91 return
[10035]92
[9988]93 logger.info("Processing %s via %s", nodename, ip)
94 target = 'IF-MIB::ifDescr'
[10035]95
[9988]96 try:
97 iface = get_snmp_stats(logger, ip, 'IF-MIB::ifDescr')
98 ifout = get_snmp_stats(logger, ip, 'IF-MIB::ifOutOctets')
99 ifin = get_snmp_stats(logger, ip, 'IF-MIB::ifInOctets')
100
101 uptime = get_snmp_value(logger, ip, 'DISMAN-EVENT-MIB::sysUpTimeInstance')
[10035]102 m_uptime[nodename] = int(uptime)
103
[9988]104 traffic = {}
105 for i,f in iface.iteritems():
106 traffic[f] = (int(ifin[i]), int(ifout[i]))
[10035]107 m_traffic[nodename] = traffic
[9988]108 except ConnectError:
109 logger.error("Unable to get all data")
110 pass
[9987]111
[10035]112def worker(i, input, m_snmp, m_traffic, m_uptime):
[9988]113 logger = logging.getLogger('Worker%s' % i)
114 logger.info("Worker")
115 for (nf, rescan) in iter(input.get, 'STOP'):
[10035]116 process_file(logger, m_snmp, m_traffic, m_uptime, nf, rescan)
[9988]117 logger.info("END")
[9987]118
[9988]119if __name__ == '__main__':
120 freeze_support()
121 task_queue = Queue()
122 manager = Manager()
[9987]123
[9988]124 try:
125 store = yaml.load(open(DATASTORE,'r'))
126 except IOError:
127 store = { 'snmp' : {}, 'traffic' : {}, 'uptime' : {}}
128 pass
[10035]129 # XXX: Manager.dict has bug of handling dicts inside dicts, using awefull quick
130 # XXX: http://bugs.python.org/issue6766
131 m_snmp = manager.dict(store['snmp'])
132 m_traffic = manager.dict(store['traffic'])
133 m_uptime = manager.dict(store['uptime'])
[9987]134
[9988]135 NUMBER_OF_PROCESSES = 10
136 RESCAN = True
137 plist = {}
138 for i in range(NUMBER_OF_PROCESSES):
[10035]139 plist[i] = Process(target=worker, args=(i, task_queue,m_snmp,m_traffic,m_uptime))
[9988]140 plist[i].start()
141
142 for nf in sorted(glob.glob('nodes/*%s*/wleiden.yaml' % ff)):
143 task_queue.put((nf, RESCAN))
[10035]144
[9988]145 for i in range(NUMBER_OF_PROCESSES):
146 task_queue.put('STOP')
147
148 for i in range(NUMBER_OF_PROCESSES):
149 plist[i].join()
150
[10035]151 store = {'snmp' : dict(m_snmp), 'traffic' : dict(m_traffic), 'uptime' : dict(m_uptime)}
[9988]152 yaml.dump(store,open(DATASTORE,'w'))
153
154
155
Note: See TracBrowser for help on using the repository browser.