#! /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_pg import all_switchs, bat_switchs, reverse, uplink_prises from ldap_crans import crans_ldap 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) # exemptions : # liste de tuple à deux éléments : # - la machine concernée # - la chambre(local) *en minuscules* dans laquelle peut se trouver la machine # sans envoyer de mail # exemple : exempt = [ ("shosur.crans.org", "b511d"), ("blabla.crans.org","bcl2") ] exempt = [] # 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) try: nb_prises = switch.nb_prises() except: continue for prise in range(1, 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-- \nGénéré par demenagement.py\n') print OK