diff --git a/surveillance/demenagement.py b/surveillance/demenagement.py new file mode 100755 index 00000000..40858935 --- /dev/null +++ b/surveillance/demenagement.py @@ -0,0 +1,131 @@ +#! /usr/bin/env python +# -*- coding: iso8859-15 -*- + +""" +Détection des déménagements non signalés + +Auteur : Étienne Chové +""" + +import sys, os +sys.path.append('/usr/scripts/gestion') +from hptools import hpswitch +from annuaires import all_switchs, bat_switchs, reverse, uplink_prises +from ldap_crans import crans_ldap, crans +from affich_tools import anim, OK +from email_tools import send_email +import sqlite +import time + +# On redirige les sorties si invoqué via cron +if 'cron' in sys.argv[0]: + so = file('/dev/null', 'a+', 0) + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(so.fileno(), sys.stderr.fileno()) + +conn = sqlite.connect('/var/lib/misc/demenagement') +conn.autocommit = True +curs = conn.cursor() +try: + curs.execute("CREATE TABLE machines (host TEXT(128), debut INTEGER);") + print "SQL : Table machines recrée" +except: + pass + +if '--list' in sys.argv: + curs.execute("SELECT * FROM machines ORDER BY debut;") + for r in curs.fetchall(): + print '%25s %s' % (r[0], time.strftime('%d/%m/%Y %H:%M',time.localtime(r[1]))) + sys.exit(0) + +# exemption +exempt = [("shosur.crans.org", "b511d")] + +# nombre minimal de jours pour dire que quelqu'un a déménagé +min_jours = 7 +# envoie un mail tous les X jours +re_mail = 7 + +# construction de rev = { bat : { prise : chbre } } +rev = {} +for bat in bat_switchs: + rev[bat] = reverse(bat) + +# remplissage de l'annuaire chambre = { mac : prise } en interrogeant les switchs +switchs = all_switchs() +progression = anim('Interrogation des switchs',len(switchs)) +chambre = {} +for host in switchs: + progression.cycle() + switch = hpswitch(host) + for prise in range(1,switch.nb_prises()+1): + if prise < 10: + prise = '0%d'%prise + else : + prise = str(prise) + + for mac in switch.show_prise_mac(prise): + try: + chambre[mac] = [ host[3] + x for x in rev[host[3]][ host[5] + prise ] ] + except: + pass +progression.reinit() +print OK + +# interrogation de la base ldap +progression = anim('Interrogation de la base LDAP') +base = crans_ldap().search('paiement=ok') +progression.reinit() +proprios = base['adherent'] +print OK + +# recherche des erreurs +progression = anim('Recherche des erreurs',len(proprios)) + +now = int(time.time()) +msg=u'' +for proprio in proprios: + if proprio.chbre()=='EXT': + continue + progression.cycle() + for machine in proprio.machines_fixes(): + if not chambre.has_key(machine.mac()): + # mac non trouvée sur switch + continue + + if proprio.chbre().lower() in chambre[machine.mac()]: + # la machine est dans sa chambre + curs.execute("DELETE FROM machines WHERE host='%s';"%machine.nom()) + + else: + # on regarde la chambre dans la base + curs.execute("SELECT debut FROM machines WHERE host='%s';" % machine.nom()) + result = curs.fetchall() + + if result: + # mise à jour de l'entrée, si vu il y a au moins une semaine + if result[0][0] < now-86400*min_jours: + if (machine.nom(),'/'.join(chambre[machine.mac()])) not in exempt: + print type(machine.nom()) + print type(u'/'.join(chambre[machine.mac()])) + print type(proprio.chbre()) + msg += u'%s vu en chambre %s mais déclaré en %s\n' % ( + machine.nom(), + '/'.join(chambre[machine.mac()]), + proprio.chbre().lower()) + # prochain rappel dans 1 semaine + curs.execute("UPDATE machines SET debut = '%d' WHERE host = '%s';" % (now+(re_mail-min_jours)*86400, machine.nom())) + else: + # nouvelle entrée + curs.execute("INSERT INTO machines (host,debut) VALUES ('%s', '%d');" % (machine.nom(),now)) + +progression.reinit() +print OK + +# sys.stderr.write(msg.encode('iso8859-15')) +# sys.stderr.flush() +if msg: + print "Envoi du mail... ", + send_email('disconnect@crans.org', 'disconnect@crans.org', u'Déménagement(s) non déclaré(s)', + msg + u'\n\n-- Généré par demenagement.py\n') + print OK