whodal: câbleurs au d'Alembert ?
This commit is contained in:
parent
e7659bdc82
commit
27fbf3f5c9
2 changed files with 204 additions and 0 deletions
196
gestion/tools/whosthere.py
Executable file
196
gestion/tools/whosthere.py
Executable file
|
@ -0,0 +1,196 @@
|
|||
#!/bin/bash /usr/scripts/python.sh
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
'''Ce script permet de savoir s'il y a du monde dans un local donné,
|
||||
à des fins de perms, et cie, filtre par membres actifs.'''
|
||||
|
||||
import sys
|
||||
from socket import gethostname
|
||||
import collections
|
||||
import os
|
||||
import xml.dom.minidom
|
||||
|
||||
from gestion.ldap_crans import crans_ldap
|
||||
from gestion.hptools import hpswitch, ConversationError
|
||||
from gestion.affich_tools import coul, cprint
|
||||
from gestion.whos import aff
|
||||
|
||||
# Constantes pour munin.
|
||||
# L'ordre est important : il détermine comment sont empilés les valeurs
|
||||
# dans le graphe (mode STACK). Les premières valeurs ont donc intérêts
|
||||
# à avoir le moins de variations (empilées les premières)
|
||||
STATE_DESCR = collections.OrderedDict([
|
||||
('unknown_macs', ('machines inconnues de la base', 0xff0000)),
|
||||
('crans', ('machines du crans', 0x0000ff)),
|
||||
('ma', ('machines de membres actifs', 0x00ff00)),
|
||||
('adh', ('autres machines appartenant aux autres adhérents', 0xe5ff00)),
|
||||
])
|
||||
|
||||
CLUB_CRANS = 35
|
||||
CLUB_BDE = 1
|
||||
|
||||
def _mucode(u):
|
||||
"""Sad but true: munin ne fait pas d'utf-8 …"""
|
||||
return u.encode('iso-8859-15', errors='ignore')
|
||||
|
||||
class WhosThere(object):
|
||||
""": Nom du local, tel qu'il apparaît sur munin, et cie"""
|
||||
name = u"Unamed Local"
|
||||
|
||||
""": Liste de macs et hostsname qui doivent être ignorées"""
|
||||
expected = []
|
||||
|
||||
_ignore_inactive = True
|
||||
_ignore_wifi_only = False
|
||||
def set_ignore_inactive(self, ignore, wifi_only=None):
|
||||
"""Définit si l'ajout d'une mac a effectivement lieu pour les
|
||||
mac à ajouter si elles n'appartiennent pas à un membre actif"""
|
||||
self._ignore_inactive = ignore
|
||||
if wifi_only is not None:
|
||||
self._ignore_wifi_only = wifi_only
|
||||
|
||||
def populate_from_mac(self, mac):
|
||||
"""Rempli à partir de la mac"""
|
||||
fm = self.db.search("mac=%s" % mac)
|
||||
res = self._res
|
||||
if mac in self.expected:
|
||||
return
|
||||
if fm['machine']:
|
||||
m = fm['machine'][0]
|
||||
if m.nom() in self.expected:
|
||||
return
|
||||
proprio = m.proprietaire()
|
||||
if fm['machineCrans'] or fm["borneWifi"] or (proprio.idn == 'cid' and int(proprio.id()) == CLUB_CRANS):
|
||||
key = 'crans'
|
||||
elif hasattr(proprio, 'droits') and proprio.droits():
|
||||
key = 'ma'
|
||||
elif proprio.idn == "cid" and int(proprio.id()) == CLUB_BDE:
|
||||
key = 'bde'
|
||||
else:
|
||||
if self._ignore_inactive:
|
||||
if fm['machineWifi'] or self._ignore_wifi_only:
|
||||
return
|
||||
key = 'adh'
|
||||
res[key].append(m)
|
||||
else:
|
||||
res['unknown_macs'].append(mac)
|
||||
|
||||
def populate_from_switch(self, host, port):
|
||||
"""Rempli les macs à partir de la prise d'un switch"""
|
||||
sw = hpswitch(host)
|
||||
try:
|
||||
macs = sw.show_prise_mac(port)
|
||||
except ConversationError:
|
||||
cprint("Impossible de communiquer avec le switch !", 'rouge')
|
||||
for mac in macs:
|
||||
self.populate_from_mac(mac)
|
||||
|
||||
def populate_from_ap(self, host):
|
||||
"""Rempli les macs à partir de la prise d'un switch"""
|
||||
path = os.path.join('/usr/scripts/var/wifi_xml/', host) + '.xml'
|
||||
with open(path, 'r') as f:
|
||||
doc = xml.dom.minidom.parse(f)
|
||||
|
||||
for mac in doc.getElementsByTagName('mac'):
|
||||
self.populate_from_mac(mac.firstChild.nodeValue)
|
||||
|
||||
def do_scan(self):
|
||||
"""Fonction à surcharger pour remplir la liste de personnes présentes.
|
||||
La fonction pourra faire appel à populate_from_*"""
|
||||
pass # à surcharger
|
||||
|
||||
_res = None
|
||||
def query(self):
|
||||
if self._res:
|
||||
return self._res
|
||||
self._res = {
|
||||
'ma': [],
|
||||
'crans': [],
|
||||
'adh': [],
|
||||
'bde': [],
|
||||
'unknown_macs': [],
|
||||
'ttyfound': 0,
|
||||
}
|
||||
self.db = crans_ldap()
|
||||
self.do_scan()
|
||||
return self._res
|
||||
|
||||
def summary(self):
|
||||
u"""Réalise un joli aperçu de l'état donné en paramètre."""
|
||||
current = self.query()
|
||||
if current['ma']:
|
||||
cprint('---=== Machines des membres actifs ===---', 'bleu')
|
||||
aff(current['ma'])
|
||||
cprint("---=== Il y a du monde ===---", 'vert')
|
||||
else:
|
||||
cprint("---=== Il semble n'y avoir personne ... ===---", 'rouge')
|
||||
for mac in current['unknown_macs']:
|
||||
cprint("Machine inconnue: %s" % mac, 'rouge')
|
||||
if current['crans']:
|
||||
cprint("---=== Machines Cr@ns ===---", 'bleu')
|
||||
aff(current['crans'])
|
||||
if current['bde']:
|
||||
cprint("---=== Machines du BDE ===---", 'bleu')
|
||||
aff(current['bde'])
|
||||
if current['adh']:
|
||||
cprint("---=== Machines d'adhérents ===---", 'bleu')
|
||||
aff(current['adh'])
|
||||
|
||||
def munin_config(self):
|
||||
"""Donne la configuration du graphe munin"""
|
||||
munin_title = u"Fréquentation du local %s" % self.name
|
||||
print """graph_title %s
|
||||
graph_vlabel N
|
||||
graph_category environnement""" % _mucode(munin_title)
|
||||
|
||||
for (name, (descr, color)) in STATE_DESCR.iteritems():
|
||||
print """%(name)s.label %(descr)s
|
||||
%(name)s.draw AREASTACK
|
||||
%(name)s.colour %(color)06X""" % {'name': name, 'descr': _mucode(descr), 'color': color}
|
||||
# Dans le doute, n'affichons pas les adhérents
|
||||
print "adh.graph no"
|
||||
|
||||
def munin_values(self):
|
||||
res = self.query()
|
||||
for name in STATE_DESCR.iterkeys():
|
||||
print """%(name)s.value %(value)d\n""" % \
|
||||
{'name': name, 'value': len(res[name]) }
|
||||
|
||||
class WhoKfet(WhosThere):
|
||||
name = u"Kfet"
|
||||
|
||||
def do_scan(self):
|
||||
self.populate_from_switch('backbone.adm.crans.org', 21)
|
||||
|
||||
class Who2B(WhosThere):
|
||||
name = u"2B"
|
||||
|
||||
expected = ['00:07:cb:b1:99:4e'] # Freebox
|
||||
|
||||
def do_scan(self):
|
||||
# Tous les gens au 2B sont supposés actifs (local technique quoi)
|
||||
# mais on cache quand-même les personnes connectées en WiFi
|
||||
self.set_ignore_inactive(True, wifi_only=True)
|
||||
self.populate_from_switch('backbone.adm.crans.org', 33)
|
||||
|
||||
class WhoDalembert(WhosThere):
|
||||
name = u"D'alembert (PR)"
|
||||
|
||||
expected = ['danae.wifi.crans.org']
|
||||
|
||||
def do_scan(self):
|
||||
# Tous les gens au 2B sont supposés actifs (local technique quoi)
|
||||
self.populate_from_ap('danae')
|
||||
|
||||
if __name__ == '__main__':
|
||||
where = {
|
||||
'dalembert': WhoDalembert,
|
||||
'2b': Who2B,
|
||||
'kfet': WhoKfet,
|
||||
}
|
||||
for what in sys.argv[1:]:
|
||||
try:
|
||||
name = where[what.lower()]
|
||||
except KeyError:
|
||||
continue
|
||||
name().summary()
|
8
respbats/whodal
Executable file
8
respbats/whodal
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ `hostname` != "zamok" ]; then
|
||||
echo "Merci d'executer ce script sur zamok."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo -u respbats /usr/scripts/gestion/tools/whosthere.py dalembert
|
Loading…
Add table
Add a link
Reference in a new issue