scripts/wifi/bornes.py
Antoine Durand-Gasselin 42b74ec0e3 [wifi/bornes.py] fournit les plugins munin clients_bornes et canal_bornes
darcs-hash:20090929130309-bd074-93a279de6dde0b9c64117aceec42f12fa3bf4b67.gz
2009-09-29 15:03:09 +02:00

230 lines
7.1 KiB
Python
Executable file

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# uname_bornes.py
# ---------------
# Copyright : (c) 2009, Jeremie Dimino <jeremie@dimino.org>
# Licence : BSD3
"""Script qui fait un uname sur toute les bornes à la fois.
La sortie est la sortie de `uname -v` sur chaque borne."""
import sys, os, commands, re, time
from optparse import OptionParser
LOG = "/var/log/wifi/wifi.log"
DELTA = 60*60
def bornes():
"""Renvoie la liste des bornes
Moyen rapide, mais peut-être un peu crade pour récupérer la liste des bornes:
on regarde les machines présentes dans 138.231.148.1/24"""
names = []
for line in commands.getoutput("host -l wifi.crans.org").splitlines():
# Chaque ligne est de la forme:
# "truc.wifi.crans.org has address 138.231.148.42"
fields = line.split()
name = fields[0].split(".")[0]
ip = fields[3]
network = ip.rsplit(".", 1)[0]
# On ne prend que les machines du réseau 138.231.148.0/24, à part
# ragnarok:
if network == "138.231.148" and ip != "138.231.148.1":
names.append(name)
return names
def ssh_exec(host, cmd):
"""Execute une commande en ssh sur une machine et renvoie le résultat"""
(stdin, stdout, stderr) = os.popen3("ssh -T -x -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=no %(host)s exec %(cmd)s" % locals())
stdin.close()
stderr.close()
return stdout
def bornes_canal():
names = bornes()
outputs = {}
for name in names:
outputs[name] = ssh_exec(name+".wifi", 'iwlist wl0 channel')
count = 0
total = len(names)
while count < total:
try: os.wait()
except OSError: break
# On lit tout les résultats:
results = {}
for name, output in outputs.iteritems():
curoutput = output.read().strip()
if 'Current Channel' in curoutput:
results[name] = curoutput.split(':')[-1].strip()
else:
results[name] = '0'
output.close()
return results
def bornes_clients():
names = bornes()
outputs = {}
for name in names:
outputs[name] = ssh_exec(name+".wifi", 'brctl showmacs br-crans')
count = 0
total = len(names)
while count < total:
try: os.wait()
except OSError: break
# On lit tout les résultats:
results = {}
for name, output in outputs.iteritems():
macs = map(lambda x: x.split(), output.readlines())
results[name] = str(len([x for x in macs if x[0] == '2' and x[2] != 'yes']))
output.close()
return results
def bornes_uptime():
names = bornes()
outputs = {}
for name in names:
outputs[name] = ssh_exec(name+".wifi", 'cat /proc/uptime')
count = 0
total = len(names)
while count < total:
try: os.wait()
except OSError: break
# On lit tout les résultats:
results = {}
for name, output in outputs.iteritems():
uptime = output.read().strip()
if uptime:
results[name] = str(float(uptime.split()[1]) / (24*3600))
else:
results[name] = '0'
output.close()
return results
def munin(config, cmd=None, process=(lambda x: x), results=None, buckets=None):
"""plugin munin"""
if 'autoconf' in sys.argv:
print 'yes'
sys.exit(0)
names = bornes()
if 'config' in sys.argv:
print config
if buckets:
for val, lbl in buckets.iteritems():
print "%s.label %s" % (lbl, val)
else:
for borne in names:
print "%s.label %s" % (borne, borne)
sys.exit(0)
if not results:
res = results = {}
for name in names: res[name] = ssh_exec(name+".wifi", cmd)
for name in names: results[name] = res[name].read()
if buckets:
bins = {}
for (lbl, val) in buckets.iteritems(): bins[val] = 0
for name, res in results.iteritems():
value = process(res).split('\n', 1)[0].strip()
if buckets: bins[buckets[value]] += 1
else: print '%s.value %s' % (name, value)
if buckets:
for name, res in bins.iteritems():
print '%s.value %s' % (name, res)
def main():
parser = OptionParser(usage=usage)
parser.add_option('-v', '--uname', help=u"renvoie le uname -v",
action='store_const', const='uname -v', dest='cmd', default='uname -v')
parser.add_option('-u', '--uptime', help=u"renvoie l'uptime",
action='store_const', const='uptime', dest='cmd')
parser.add_option('-c', '--custom', help=u'exécute une commande custom',
action='store', dest='cmd')
(options, args) = parser.parse_args()
names = bornes()
outputs = {}
for name in names:
outputs[name] = ssh_exec(name+".wifi", options.cmd)
# On attend que tous les fils qu'on a lancé terminent, avec une petite
# animation si la sortie est un terminal:
count = 0
total = len(names)
show_anim = sys.stderr.isatty()
message = "Réception des résultats: %d/%d"
if show_anim: sys.stderr.write(message % (count, total))
while count < total:
try: os.wait()
except OSError: break
count += 1
if show_anim: sys.stderr.write("\r" + message % (count, total))
if show_anim: sys.stderr.write("\n")
# On lit tout les résultats:
results = {}
for name, output in outputs.iteritems():
results[name] = output.read().strip()
output.close()
results = results.items()
results.sort(key=lambda x: x[0])
for name, result in results:
if not result:
print "%-15s failure" % (name + ":")
for name, result in results:
if result:
print "%-15s %s" % (name + ":", result)
if __name__ == "__main__":
usage = u"""usage: %prog [OPTION]
Récupère la liste des bornes et récupère le résultat d'une commande sur
toutes les bornes"""
prog = os.path.basename(sys.argv[0])
if len(prog.split('_', 1)) > 1:
plugin = prog.split('_', 1)[0]
if plugin == 'uptime':
config = """graph_title Uptime Bornes
graph_args --base 1000 -l 0
graph_vlabel uptime in days"""
def process(uptime):
if uptime: return str(float (uptime.split()[1]) / (24 * 3600))
else: return '0'
munin(config, cmd = 'cat /proc/uptime', process=process)
elif plugin == 'clients':
config = """graph_title Clients connectés
graph_args --base 1000 -l 0
graph_vlabel Clients connectés"""
munin(config, results=bornes_clients())
elif plugin == 'canal':
config = """graph_title Canaux utilisés
graph_args --base 1000 -l 0"""
buckets = {'1': 'un', '2': 'deux', '3': 'trois', '4': 'quatre',
'5': 'cinq', '6': 'siz', '7': 'sept', '8': 'huit',
'9': 'neuf', '10': 'dix', '11': 'onze', '12': 'douze',
'13': 'treize', '14': 'quatorze', '0': 'echec' }
munin(config, results=bornes_canal(), buckets= buckets)
else: raise NotImplementedError
else:
main()