984 lines
32 KiB
Python
Executable file
984 lines
32 KiB
Python
Executable file
#! /usr/bin/env python
|
|
# -*- coding: iso-8859-15 -*-
|
|
|
|
# Copyright (C) Frédéric Pauget
|
|
# Licence : GPLv2
|
|
|
|
"""Ce script permet de recherche et d'afficher le détail d'une machine ou
|
|
d'un adhérent.
|
|
|
|
Usage: %(prog)s [options] <chaine de recherche>
|
|
|
|
La chaine de recherche peut être :
|
|
* soit un terme unique, dans ce cas la recherche sera effectuée sur les
|
|
champs en bleu ci-dessous.
|
|
* soit du type "champ1=valeur1&champ2!=valeur2 ...", les résultats seront
|
|
alors limités aux entrées correspondantes à tous les critères.
|
|
|
|
Les champs de recherche possibles sont :
|
|
%(champs_rech)s
|
|
Recherche sur prise possible (utiliser uniquement ce champ dans ce cas)
|
|
|
|
Les options de recherches sont :
|
|
* limitations sur l'affichage :
|
|
-a ou --adherent : limitation de l'affichage aux adhérents
|
|
-m ou --machine : limitation de l'affichage aux machines
|
|
-c ou --club : limitation de l'affichage aux clubs
|
|
-b ou --bornes : limitation de l'affichage aux bornes wifi
|
|
--crans : recherche uniquement les machines du crans
|
|
* options d'affichage :
|
|
-t ou --tech : affichages des infos techniques des machines
|
|
à la place des infos administratives dans les résumés.
|
|
-i ou --ipsec : montre la clef ipsec des machines wifi
|
|
-l <num> ou --limit=<num> : limite du nombre de résultats pour utiliser
|
|
le mode d'affichage condensé au lieu du mode détaillé (défaut %(limit_aff_details)i)
|
|
-L <num> ou --limit-historique=<num> : limitation du nombre de lignes
|
|
d'historique affichées (défaut %(limit_aff_historique)i)
|
|
"""
|
|
|
|
try:
|
|
import sys,locale
|
|
|
|
loc = locale.getdefaultlocale()
|
|
if loc[1]:
|
|
sys.reallysetdefaultencoding(loc[1])
|
|
except:
|
|
pass
|
|
|
|
base = None
|
|
|
|
from ldap_crans import is_actif , crans_ldap, ann_scol, crans, hostname
|
|
from affich_tools import *
|
|
import user_tests
|
|
import popen2
|
|
|
|
limit_aff_details = 1
|
|
limit_aff_historique = 4
|
|
aff_ipsec = 0
|
|
|
|
def unicode_print(truc) :
|
|
""" Conversion de truc en iso-8859-15 puis affichage à l'écran """
|
|
print truc.encode('iso-8859-15','ignore')
|
|
|
|
def aff(qqch,mtech=0) :
|
|
""" Affichage de qqch.
|
|
qqch peut être une liste d'instances des classes adhérent ou machine
|
|
(un seul type dans la liste) dans ce cas :
|
|
* si la longueur de la liste est inférieure à limit_aff_details
|
|
affiche les propriétés détaillées de chaque élément.
|
|
* sinon résume dans un tabeau des principales propriétés
|
|
si qqch est une instance seul la traité comme une liste à une élément
|
|
Si mtech = 1 affiches les infomations techniques des machines plutot
|
|
qu'administratives dans le tableau des propriétés
|
|
"""
|
|
if type(qqch) != list :
|
|
qqch = [ qqch ]
|
|
|
|
if len(qqch) > limit_aff_details :
|
|
t = qqch[0].idn
|
|
if t == 'aid' :
|
|
unicode_print(adhers_brief(qqch))
|
|
elif t == 'mid' :
|
|
if mtech : unicode_print(list_machines(qqch))
|
|
else : unicode_print(machines_brief(qqch))
|
|
elif t == 'cid' :
|
|
unicode_print(clubs_brief(qqch))
|
|
else :
|
|
i = 0
|
|
for c in qqch :
|
|
t = c.idn
|
|
if i : print coul(u'='*80,'cyan')
|
|
i = 1
|
|
if t == 'aid' : unicode_print(adher_details(c))
|
|
elif t == 'mid' :
|
|
unicode_print(machine_details(c))
|
|
elif t == 'cid' : unicode_print(club_details(c))
|
|
if len(qqch) > 1:
|
|
print u"Total: %d" % len(qqch)
|
|
|
|
def adhers_brief(adhers) :
|
|
"""
|
|
Formatage sous forme de tableau des infos sur la liste d'adhérent fournie :
|
|
* aid
|
|
* prénom nom
|
|
* chambre
|
|
* machines
|
|
"""
|
|
data = [ ( u'aid' , u'Prénom Nom' , u'Chbre', u'P', u'C', u'Machines' ) ]
|
|
|
|
for a in adhers :
|
|
## Etat administratif
|
|
ok = u'\x1b[1;32mo\x1b[1;0m'
|
|
nok = u'\x1b[1;31mn\x1b[1;0m'
|
|
# Paiement
|
|
if ann_scol in a.paiement() : paid = ok
|
|
else : paid = nok
|
|
|
|
# Précablage
|
|
if ann_scol+1 in a.paiement() : paid = coul(paid,'f_vert')
|
|
|
|
# Carte d'étudiant
|
|
if ann_scol in a.carteEtudiant() : carte = ok
|
|
else : carte = nok
|
|
|
|
machines = ''
|
|
# Récupération des machines
|
|
for machine in a.machines() :
|
|
nom = machine.nom().split('.')[0]
|
|
if machine.blacklist_actif() : k = 'rouge'
|
|
else : k= ''
|
|
if machines : machines += ', ' + coul(nom,k)
|
|
else : machines = coul(nom,k)
|
|
|
|
# Données
|
|
data.append((a.id() , a.Nom(), a.chbre(),paid,carte,machines ))
|
|
|
|
return u"Machines en rouge = machines avec limitation de services\n" + \
|
|
u"P : paiement année en cours, le fond vert indique le précâblage\n" + \
|
|
u"C : carte d'étudiant année en cours\n" + \
|
|
tableau([5, 30 , 5, 1, 1, '*'], data)
|
|
|
|
def machines_brief(machines) :
|
|
"""
|
|
Formatage sous forme d'un tableau des propriétés de la liste de machine :
|
|
* mid
|
|
* type (fixe ou wifi, born)
|
|
* nom
|
|
* adresse IP
|
|
* adresse MAC
|
|
* si blacklistée
|
|
"""
|
|
data = [ ( u'mid' , u'Type', u'Nom de machine', u'Propriétaire', u'Chbre', u'Limitation' ) ]
|
|
|
|
for m in machines :
|
|
t, bl = __bases_machines(m)
|
|
|
|
# Propriétaire
|
|
a = m.proprietaire()
|
|
p = a.Nom()
|
|
|
|
# A jour administrativement
|
|
if ann_scol not in a.paiement() or ann_scol not in a.carteEtudiant() :
|
|
p = coul(p,'rouge')
|
|
|
|
# Données
|
|
data.append((m.id() , t, m.nom().split('.')[0], p, a.chbre(), bl))
|
|
|
|
return u"Le propriétaire en rouge signale un problème administratif\n" + \
|
|
tableau([5, 4, 18, '*', 5, 10], data)
|
|
|
|
def clubs_brief(clubs) :
|
|
"""
|
|
Formatage sous forme de tableau des infos sur la liste de clubs fournie :
|
|
* cid
|
|
* nom
|
|
* local
|
|
* machines
|
|
"""
|
|
data = [ ( u'cid' , u'Nom ', u'Local',u'P', u'Responsable', u'Machines' ) ]
|
|
|
|
for c in clubs :
|
|
## Etat administratif
|
|
ok = u'\x1b[1;32mo\x1b[1;0m'
|
|
nok = u'\x1b[1;31mn\x1b[1;0m'
|
|
# Paiement
|
|
if ann_scol in c.paiement() : paid = ok
|
|
else : paid = nok
|
|
|
|
# Précablage
|
|
if ann_scol+1 in c.paiement() : paid = coul(paid,'f_vert')
|
|
|
|
machines = ''
|
|
# Récupération des machines
|
|
for machine in c.machines() :
|
|
nom = machine.nom().split('.')[0]
|
|
if machine.blacklist_actif() : k = 'rouge'
|
|
else : k= ''
|
|
if machines : machines += ', ' + coul(nom,k)
|
|
else : machines = coul(nom,k)
|
|
|
|
# Responsable
|
|
resp = c.responsable().Nom()
|
|
|
|
# Données
|
|
data.append((c.id() , c.Nom(), c.local(),paid, resp, machines ))
|
|
|
|
return u"Machines en rouge = machines avec limitation de services\n" + \
|
|
u"P : signature charte année en cours, le fond vert indique le précâblage\n" + \
|
|
tableau([5, '*' , 6, 1, 21, 15], data)
|
|
|
|
|
|
def list_machines(machines) :
|
|
"""
|
|
Formatage sous forme d'un tableau des propriétés de la liste de machine :
|
|
* mid
|
|
* type (fixe ou wifi)
|
|
* nom
|
|
* adresse IP
|
|
* adresse MAC
|
|
* si blacklistée
|
|
"""
|
|
data = [ ( u'mid' , u'Type', u'Nom de machine', u'Adresse IP', u'Adresse MAC', u'Limitation' ) ]
|
|
|
|
for m in machines :
|
|
t, bl = __bases_machines(m)
|
|
|
|
# Données
|
|
data.append((m.id() , t, m.nom().split('.')[0], m.ip(), m.mac(), bl))
|
|
|
|
return tableau([5, 4, '*', 17, 19, 10], data)
|
|
|
|
def list_bornes(bornes) :
|
|
"""
|
|
Formatage sous forme d'un tableau des propriétés de la liste de bornes wifi :
|
|
* mid
|
|
* nom
|
|
* adresse IP
|
|
* adresse MAC
|
|
* État
|
|
* puissance
|
|
* canal
|
|
* lieu (la première remarque en fait)
|
|
"""
|
|
data = [ ( u'mid' , u'Nom', u'Adresse IP', u'Adresse MAC', u'E', u'Can' , u'P', u'Pris', u'Lieu') ]
|
|
|
|
ok = u'\x1b[1;32mu\x1b[1;0m'
|
|
nok = u'\x1b[1;31md\x1b[1;0m'
|
|
for b in bornes :
|
|
t, bl = __bases_machines(b)
|
|
if t != 'born' : continue
|
|
|
|
# Données
|
|
try :
|
|
l = b.info()[0]
|
|
if len(l) > 11 :
|
|
l = l[0:11]
|
|
except :
|
|
l = u'????'
|
|
|
|
if borne_etat(b.nom()):
|
|
etat = ok
|
|
else:
|
|
etat = nok
|
|
|
|
if '-' in b.puissance() :
|
|
puiss = coul(b.puissance(),'rouge')
|
|
else :
|
|
puiss = b.puissance()
|
|
|
|
data.append((b.id() , b.nom().split('.')[0], b.ip(), b.mac(), etat, b.canal(), puiss, b.prise(),l ))
|
|
|
|
return u"Can=canaux, P=puissance, E=état\n" + tableau([4, 13, 15, 17, 1, 5, 3, 4, '*'], data)
|
|
|
|
def adher_details(adher) :
|
|
"""
|
|
Affichage du détail des propriétés d'un adhérent
|
|
"""
|
|
f=''
|
|
# Aid
|
|
f+= coul(u'aid=%s ' % adher.id() ,'bleu')
|
|
# Nom, prenom
|
|
f += coul(u'Nom : ','gras') + "%s\n" % adher.Nom()
|
|
|
|
# Mail
|
|
if adher.mail().find('@')!=-1 :
|
|
f += coul(u'Adresse mail : ','gras') + "%s" % adher.mail()
|
|
else :
|
|
f += coul(u'Login : ','gras') + "%s\t" % adher.mail()
|
|
alias = ', '.join([adher.cannonical_alias()] + adher.alias())
|
|
if alias :
|
|
if alias[0]==',' :
|
|
# Cannonical étéait vide
|
|
alias = alias[2:]
|
|
f += coul(u'Alias : ','gras') + alias
|
|
f+= u'\n'
|
|
|
|
# Etat administratif
|
|
f += coul(u'Etat administratif : ','gras')
|
|
jour=1
|
|
if ann_scol not in adher.carteEtudiant() :
|
|
f += coul(u"manque carte d'étudiant",'violet')
|
|
jour = 0
|
|
if ann_scol not in adher.paiement() :
|
|
if not jour : f += ' et '
|
|
f += coul(u"cotisation %s/%d non réglée"% (ann_scol, ann_scol+1 ),'violet')
|
|
jour = 0
|
|
|
|
if jour :
|
|
f += coul(u"à jour",'vert')
|
|
f += '\n'
|
|
|
|
# Telephone
|
|
tel = adher.tel()
|
|
if tel != 'inconnu' :
|
|
try :
|
|
tel = u'%s %s %s %s %s' % ( tel[:2], tel[2:4], tel[4:6], tel[6:8], tel[8:] )
|
|
except :
|
|
pass
|
|
f += coul(u'Numéro de téléphone : ','gras') + "%s\n" % tel.ljust(12)
|
|
|
|
# Adresse
|
|
chbre = adher.chbre()
|
|
if chbre == 'EXT' :
|
|
# Adhérent extérieur
|
|
addr = adher.adresse()
|
|
if addr[0] :
|
|
f += coul(u'Adresse : ','gras')
|
|
f += addr[0] + u'\n'
|
|
if addr[1] != ' ' : f += u' ' + addr[1] + u'\n'
|
|
f+= u' ' + addr[2] + u' ' + addr[3] + '\n'
|
|
else :
|
|
# Chambre + prise (d'après annuaire)
|
|
f += coul(u'Chambre : ','gras') + u"%s " % chbre
|
|
f += u'(%s)' % prise_etat(adher.chbre())
|
|
f += u'\n'
|
|
|
|
# Etudes
|
|
if adher.etudes(1).isdigit() :
|
|
f += coul(u'Etudes : ','gras')+ "%s %s%s\n" % \
|
|
( adher.etudes(0), adher.etudes(1), adher.etudes(2) )
|
|
elif adher.etudes(0) :
|
|
f += coul(u'Etudes : ','gras')+ "%s %s %s\n" % \
|
|
( adher.etudes(0), adher.etudes(1), adher.etudes(2) )
|
|
|
|
# Solde
|
|
solde = adher.solde()
|
|
if solde :
|
|
f += coul(u'Solde : ','gras')
|
|
if solde < 0 :
|
|
f+= coul(str(solde).replace('.',','),'rouge')
|
|
else :
|
|
f += str(solde).replace('.',',')
|
|
f += u" Euros\n"
|
|
|
|
# Role dans l'assoce
|
|
d = adher.droits()
|
|
if d :
|
|
f += coul(u"Droits sur les serveurs : ",'gras') + ', '.join(d)
|
|
f += u'\n'
|
|
|
|
# Paiement
|
|
if adher.paiement() :
|
|
if len(adher.paiement()) == 1 :
|
|
f += coul(u'Cotisation payée pour l\'année scolaire :','gras')
|
|
else :
|
|
f += coul(u'Cotisation payée pour les années scolaires :','gras')
|
|
g = u''
|
|
for an in adher.paiement() : g += u" %i-%i" % ( an, an+1 )
|
|
if len(g) > 35 : f += '\n\t'
|
|
f += g
|
|
f += u'\n'
|
|
|
|
# Cartes d'étudiant fournie
|
|
if adher.carteEtudiant() :
|
|
if len(adher.carteEtudiant()) == 1 :
|
|
f += coul(u"Carte d'étudiant fournie pour l'année scolaire :",'gras')
|
|
else :
|
|
f += coul(u"Carte d'étudiant fournie pour les années scolaires :",'gras')
|
|
g = u''
|
|
for an in adher.carteEtudiant() : g += u" %i-%i" % ( an, an+1 )
|
|
if len(g) > 25 : f += '\n\t'
|
|
f += g
|
|
f += u'\n'
|
|
|
|
f += _blacklist(adher)
|
|
f += _info(adher)
|
|
f += _hist(adher)
|
|
|
|
# Formatage des machines aussi
|
|
f += coul(u'Machine(s) : ','gras')
|
|
m = adher.machines()
|
|
if m :
|
|
f += u'\n' + list_machines(m)
|
|
else :
|
|
f += u'aucune'
|
|
|
|
return f
|
|
|
|
def machine_details(machine) :
|
|
"""
|
|
Formatage du détail des propriétés d'une machine
|
|
"""
|
|
f = ''
|
|
f+= coul(u'mid=%s ' % machine.id(),'bleu')
|
|
|
|
# Type de machine
|
|
if machine.ipsec() : a='Machine wifi'
|
|
elif machine.canal() : a='Borne wifi'
|
|
else : a='Machine fixe'
|
|
f+= coul(a+' : ' ,'gras')
|
|
|
|
f+= "%s\n" % machine.nom()
|
|
|
|
# Alias ?
|
|
alias = machine.alias()
|
|
if alias :
|
|
f += coul(u'Alias : ' ,'gras') + ', '.join(alias)
|
|
f+= '\n'
|
|
|
|
f+= coul(u'IP : ','gras') + "%s\t\t" %machine.ip()
|
|
f+= coul(u'MAC : ','gras') + "%s\n" %machine.mac()
|
|
|
|
# Propriétaire
|
|
f+= coul(u'Propriétaire : ','gras')
|
|
try :
|
|
f += machine.proprio + coul(' (adhérent détruit)', 'jaune')
|
|
a = crans()
|
|
except :
|
|
a = machine.proprietaire()
|
|
f += "%s" % a.Nom()
|
|
if a.chbre()!='CRA' :
|
|
f += " (%s)" % a.chbre()
|
|
else :
|
|
f += coul(u'\t\tPrise : ','gras') + machine.prise()
|
|
f+= '\n'
|
|
|
|
|
|
# Adhérent blacklisté ?
|
|
bl = a.blacklist_actif()
|
|
if bl :
|
|
f += coul(u'Restrictions sur adhérent : ','gras')
|
|
f += coul(u', '.join(bl),'rouge')
|
|
f += '\n'
|
|
|
|
# Borne wifi
|
|
if machine.puissance() :
|
|
f += coul(u'Puissance : ','gras') + u"%4.d" % int(machine.puissance())
|
|
f += coul(u'\tCanaux : ', 'gras') + machine.canal()
|
|
f += coul(u'\tÉtat : ', 'gras')
|
|
if borne_etat(machine.nom()):
|
|
f += coul(u'borne active', 'vert')
|
|
f += '\n'
|
|
# S'il y a des clients, on les liste
|
|
canal_clients = borne_clients_canal(machine.nom())
|
|
clients = canal_clients["mac-rssi"]
|
|
canal = canal_clients["canal"]
|
|
f += coul(u'\t Canal courant : ', 'gras') + u"%d" % canal
|
|
f += "\n"
|
|
if clients and base:
|
|
f += coul(u'Clients : \n','gras')
|
|
for (client, rssi) in clients:
|
|
# On va chercher le nom correspondant à l'adresse MAC
|
|
res = base.search("mac=%s" % client)['machine']
|
|
if not res:
|
|
client_nom = '????'
|
|
coul_rssi = 'rouge'
|
|
rssi = 0
|
|
else:
|
|
client_nom = ", ".join(["%s [%s]" % (x.nom(), x.proprietaire().Nom()) for x in res])
|
|
# On va choisir la bonne couleur pour le RSSI
|
|
if rssi > -88:
|
|
coul_rssi = 'vert'
|
|
elif rssi > -93:
|
|
coul_rssi = 'jaune'
|
|
else:
|
|
coul_rssi = 'rouge'
|
|
f += u' %s (%s) (RSSI: %s)\n' % (client, client_nom,
|
|
coul("%d" % rssi, coul_rssi))
|
|
else:
|
|
f += coul(u'borne éteinte','rouge')
|
|
f += '\n'
|
|
|
|
|
|
if aff_ipsec and machine.ipsec() :
|
|
f += coul(u'Clef IPsec : ','gras') + machine.ipsec()
|
|
f += '\n'
|
|
|
|
# Ports spéciaux
|
|
if machine.portTCPin() :
|
|
f += coul(u'Ports TCP ouvert ext->machine : ','gras') + machine.portTCPin() + '\n'
|
|
if machine.portTCPout() :
|
|
f += coul(u'Ports TCP ouvert machine->ext : ','gras') + machine.portTCPout() + '\n'
|
|
if machine.portTCPin() :
|
|
f += coul(u'Ports UDP ouvert ext->machine : ','gras') + machine.portUDPin() + '\n'
|
|
if machine.portUDPout() :
|
|
f += coul(u'Ports UDP ouvert machine->ext : ','gras') + machine.portUDPout() + '\n'
|
|
|
|
# Exemption d'upload
|
|
if machine.exempt() :
|
|
f += coul(u'Upload exempté vers : ','gras') + ', '.join(machine.exempt()) + '\n'
|
|
|
|
f += _blacklist(machine)
|
|
f += _info(machine)
|
|
f += _hist(machine)
|
|
|
|
return f
|
|
|
|
def club_details(club) :
|
|
"""
|
|
Affichage du détail des propriétés d'un adhérent
|
|
"""
|
|
f=''
|
|
# Cid
|
|
f+= coul(u'cid=%s ' % club.id() ,'bleu')
|
|
# Nom
|
|
f += coul(u'Nom : ','gras') + "%s\n" % club.Nom()
|
|
|
|
# responsale
|
|
f += coul(u'Responsable : ','gras') + "%s\n" % club.responsable().Nom()
|
|
|
|
# Etat administratif
|
|
f += coul(u'Etat administratif : ','gras')
|
|
jour=1
|
|
if ann_scol not in club.paiement() :
|
|
if not jour : f += ' et '
|
|
f += coul(u"charte %s/%d non signée"% (ann_scol, ann_scol+1 ),'violet')
|
|
jour = 0
|
|
|
|
if jour :
|
|
f += coul(u"à jour",'vert')
|
|
f += '\n'
|
|
|
|
# Chambre + prise
|
|
f += coul(u'Local : ','gras') + "%s " % club.local()
|
|
f += u'(%s)' % prise_etat(club.chbre())
|
|
f += u'\n'
|
|
|
|
# Paiement
|
|
if club.paiement() :
|
|
f += coul(u'Charte signée pour les années scolaires :','gras')
|
|
g = ''
|
|
for an in club.paiement() : g += " %i-%i" % ( an, an+1 )
|
|
if len(g) > 35 : f += '\n\t'
|
|
f += g
|
|
f += '\n'
|
|
|
|
login = club.compte()
|
|
if login :
|
|
f += coul(u'Login : ','gras') + login
|
|
alias = club.alias()
|
|
if alias :
|
|
f += coul(u'\tAlias : ','gras') + ', '.join(alias)
|
|
f+= u'\n'
|
|
|
|
f += _blacklist(club)
|
|
f += _info(club)
|
|
f += _hist(club)
|
|
|
|
# Formatage des machines aussi
|
|
f += coul(u'Machine(s) : ','gras')
|
|
m = club.machines()
|
|
if m :
|
|
f += '\n' + list_machines(m)
|
|
else :
|
|
f += 'aucune'
|
|
|
|
return f
|
|
|
|
###########################################
|
|
# Fonctions annexes de formatage de données
|
|
|
|
def _blacklist(clas) :
|
|
""" Formatage blackliste de la classe fournie """
|
|
f = u''
|
|
for event in clas.blacklist() :
|
|
if is_actif(event) :
|
|
# Colorisation si sanction en cours
|
|
c = 'rouge'
|
|
else :
|
|
c = 'blanc'
|
|
f += u"%s\n\t " % coul(u'du %s au %s : %s, %s' % tuple(event.split(',')) ,c)
|
|
|
|
f = f[:-6] # supression des espaces superflus
|
|
|
|
if f :
|
|
return coul(u'Blackliste : ', 'gras') + f
|
|
else :
|
|
return ''
|
|
|
|
def _info(clas) :
|
|
""" Formatage des remarques de la classe fournie """
|
|
f= u''
|
|
c = clas.info()
|
|
if c :
|
|
f += coul(u'Remarque :\n ' ,'gras')
|
|
f += u'\n '.join(c)
|
|
f += u'\n'
|
|
return f
|
|
|
|
def _hist(clas) :
|
|
""" Formatage de l'historique de la classe fournie """
|
|
if limit_aff_historique==0 : return ''
|
|
f=''
|
|
h = clas.historique()
|
|
h.reverse()
|
|
if h :
|
|
f += coul(u'Historique : ','gras')
|
|
for i in range(0,limit_aff_historique) :
|
|
try :
|
|
a = h[i] # Produit une erreur si i trop grand
|
|
if i !=0 : f += ' '
|
|
f += '%s\n' % a
|
|
except :
|
|
break
|
|
try :
|
|
if h[i+1] : f += ' [...]\n'
|
|
except :
|
|
None
|
|
|
|
return f
|
|
|
|
def __bases_machines(m) :
|
|
""" Retourne [ type de la machines, blacklist ] """
|
|
#Type
|
|
if m.ipsec() : t='wifi'
|
|
elif m.canal() : t='born'
|
|
else : t='fixe'
|
|
|
|
# Déconnectée ?
|
|
b = m.blacklist_actif()
|
|
if not b :
|
|
bl = '-'
|
|
elif len(b) == 1 :
|
|
bl = coul(b[0],'rouge')
|
|
else :
|
|
bl = coul(u'cf détails','rouge')
|
|
|
|
return t , bl
|
|
|
|
def borne_etat(borne) :
|
|
"""Renvoie vrai si la borne est up, faux sinon"""
|
|
# On utilise fping, en cas d'erreur, on considere
|
|
# que la borne est down (alors qu'elle peut simplement
|
|
# ne pas exister)
|
|
try:
|
|
retour = os.system("fping -q -c 1 %s > /dev/null 2> /dev/null" % borne)
|
|
return (retour == 0)
|
|
except:
|
|
return False
|
|
|
|
def borne_clients_canal(borne) :
|
|
"""Renvoie la liste des adresses MAC associées à la borne ainsi que le canal.
|
|
|
|
Chaque adresse MAC est en fait contenue dans un couple comprenant
|
|
l'adresse MAC et le RSSI du client associé.
|
|
|
|
On en profite pour renvoyer également le canal en cours de la
|
|
borne. On fait cela dans la même fonction car cela évite de faire
|
|
deux connexions ssh (ce qui est fort coûteux).
|
|
|
|
Au final, on renvoie un dictionnaire
|
|
- mac-rssi: une liste de couples (MAC, RSSI)
|
|
- canal: le canal en cours
|
|
"""
|
|
macs = []
|
|
canal = -1
|
|
# Uniquement possible pour les admins et si on a la clef
|
|
for clef in ["/etc/wifi/ssh/wifi","/usr/scripts/gestion/clef-wifi"]:
|
|
if os.path.isfile(clef) and user_tests.isadm():
|
|
try:
|
|
wl = popen2.Popen3("ssh -o StrictHostKeyChecking=no -i %s root@%s 'cat /tmp/auth-mac.dump ; echo -n \"CANAL \" ; /usr/sbin/nvram get wl0_channel' 2> /dev/null" % (clef, borne))
|
|
wl.tochild.close()
|
|
for line in wl.fromchild.readlines():
|
|
# Chaque ligne est de la forme
|
|
# 00:11:22:33:44:55 -20
|
|
line = line.strip().split()
|
|
if line[0] == "CANAL":
|
|
canal = int(line[-1])
|
|
else:
|
|
macs.append((line[0].strip(), int(line[1].strip())))
|
|
except:
|
|
pass
|
|
break # Pas la peine d'essayer une autre clef
|
|
return {"canal": canal, "mac-rssi": macs}
|
|
|
|
def prise_etat(chbre) :
|
|
""" Retoune l'état de la prise associée à la chbre """
|
|
f = u''
|
|
try:
|
|
# On met aussi l'état
|
|
from hptools import sw_chbre
|
|
prise = sw_chbre(chbre)
|
|
f += u'prise %s' % prise.prise_brute
|
|
rows, cols = get_screen_size()
|
|
if prise.is_up() :
|
|
f += u', ' + coul(u'machine branchée','vert')
|
|
reste_cols = cols - 45
|
|
if prise.eth_mode().find('10Mbits')!=-1 :
|
|
f+= u', ' + coul(u'prise en 10Mbps','jaune')
|
|
reste_cols -= 17
|
|
f+=', '
|
|
macs = prise.show_prise_mac()
|
|
if len(macs) == 0:
|
|
if reste_cols < 20 :
|
|
# Faut aller à la ligne
|
|
f += u'\n '
|
|
f += coul(u'aucune MAC détectée', 'jaune')
|
|
else:
|
|
if len(macs) == 1 and reste_cols > 25 :
|
|
# Une seule mac et on a assez de place
|
|
f += u"MAC: %s" % macs[0]
|
|
else :
|
|
# On va à la ligne
|
|
# Combien d'adresses MAC peut-on mettre par ligne ?
|
|
# Une adresse MAC =~ 20 caracteres
|
|
cols -= 17 # On met 15espaces devant chaque ligne
|
|
parligne = int(cols/20)
|
|
count = 0
|
|
while len(macs) > 0:
|
|
if count % parligne == 0:
|
|
f += u'\n MACs: '
|
|
else:
|
|
f += u', '
|
|
f += u"%s" % macs.pop()
|
|
count += 1
|
|
elif not prise.is_enable() :
|
|
f+= u', ' + coul(u'prise désactivée','rouge')
|
|
else :
|
|
f+= u', activée, lien non détecté'
|
|
except :
|
|
# Switch non manageable
|
|
f = u'informations prise non disponibles'
|
|
|
|
return f
|
|
|
|
##############################################################################
|
|
## Partie dévolue au système de recherche
|
|
|
|
def __usage_brief(err='') :
|
|
""" Message d'erreur """
|
|
if err : cprint(err,'gras')
|
|
print u"Pour obtenir de l'aide sur l'utilisation de ce programme utilisez l'option -h"
|
|
sys.exit(2)
|
|
|
|
def __usage() :
|
|
""" Comment ca marche ? """
|
|
list = ['']
|
|
for c in base.auto_search_champs.values() :
|
|
for champ in c :
|
|
coul_champ = coul(champ,'bleu')
|
|
if list[-1] == '' :
|
|
list[-1] = coul_champ
|
|
l = len(champ)
|
|
else :
|
|
l += len(champ) + 2
|
|
if l < 80 :
|
|
list[-1] += ', ' + coul_champ
|
|
else :
|
|
list.append(coul_champ)
|
|
l = len(champ)
|
|
|
|
for c in base.non_auto_search_champs.values() :
|
|
for champ in c :
|
|
l += len(champ) + 2
|
|
if l < 80 :
|
|
list[-1] += ', ' + champ
|
|
else :
|
|
list.append(champ)
|
|
l = len(champ)
|
|
|
|
print __doc__ % { 'prog' : sys.argv[0].split('/')[-1].split('.')[0] ,
|
|
'champs_rech' : '\n'.join(list) ,
|
|
'limit_aff_details' : limit_aff_details ,
|
|
'limit_aff_historique' : limit_aff_historique }
|
|
sys.exit(0)
|
|
|
|
def __recherche() :
|
|
"""
|
|
Recherche et affichage des résultats à partir des options founies (sys.argv)
|
|
"""
|
|
global aff_ipsec, limit_aff_details, limit_aff_historique, debug
|
|
|
|
# Récupération des options
|
|
if len(sys.argv) == 1 :
|
|
# Pas d'option fournie
|
|
__usage_brief()
|
|
|
|
try :
|
|
options, arg = getopt.getopt(sys.argv[1:], 'hamctbil:L:', [ 'debug', 'help', 'adherent', 'machine', 'club' , 'tech', 'bornes', 'limit=', 'limit-historique=', 'ipsec', 'crans' ])
|
|
except getopt.error, msg :
|
|
__usage_brief(msg)
|
|
|
|
# Traitement des options
|
|
only_adh=0
|
|
only_mac=0
|
|
only_club=0
|
|
only_bornes=0
|
|
only_crans=0
|
|
mtech = 0
|
|
|
|
for opt, val in options :
|
|
if opt == '-h' or opt=='--help' :
|
|
__usage()
|
|
elif opt =='--debug' :
|
|
# Mode debug
|
|
debug = 1
|
|
elif opt == '-l' or opt =='--limit':
|
|
# Passage mode condensé, mode détaillé
|
|
try : limit_aff_details = int(val)
|
|
except :
|
|
__usage_brief('Valeur du paramètre %s incorecte (doit être un entier positif)' % opt)
|
|
elif opt == '-L' or opt =='--limit-historique':
|
|
# Limitation du nombre de lignes d'historique
|
|
try : limit_aff_historique = int(val)
|
|
except :
|
|
__usage_brief('Valeur du paramètre %s incorecte (doit être un entier positif)' % opt)
|
|
elif opt in [ '-a', '--adherent' ] :
|
|
only_adh = 1
|
|
print u"Affichage limité aux adhérents."
|
|
elif opt in [ '-m', '--machine' ] :
|
|
only_mac = 1
|
|
print u"Affichage limité aux machines."
|
|
elif opt in [ '-c', '--club' ] :
|
|
only_club = 1
|
|
print u"Affichage limité aux clubs."
|
|
elif opt == '--crans' :
|
|
only_crans = 1
|
|
mtech = 1
|
|
print u"Affichage limité aux machines du crans."
|
|
elif opt in [ '-b', '--bornes' ] :
|
|
only_bornes = 1
|
|
print u"Affichage limité aux bornes wifi."
|
|
# On va tenter de limiter un peu la recherche
|
|
if not arg :
|
|
# Recherche initiale sans critère
|
|
arg = [ 'canal=*&host=*.crans.org']
|
|
elif arg[0].find('=')!=-1 :
|
|
# Recherche avec critères
|
|
arg += [ '&canal=*' ]
|
|
elif opt in [ '-t', '--tech' ] :
|
|
# Format affichage des machines
|
|
mtech = 1
|
|
elif opt in [ '-i', '--ipsec' ] :
|
|
# Affichage des clefs ipsec
|
|
aff_ipsec = 1
|
|
|
|
if only_adh + only_mac + only_club + only_bornes > 1 :
|
|
__usage_brief('Options utilisées incompatibles')
|
|
|
|
arg = ' '.join(arg)
|
|
# Cas particulier de recherche sur prise
|
|
if arg.count('=') == 1 and arg.split('=')[0] == 'prise' :
|
|
prise = arg.split('=')[1]
|
|
# Récupération de la chambre
|
|
try :
|
|
from annuaires import reverse
|
|
chbre = reverse(prise[0].lower())[prise[1:]]
|
|
except :
|
|
try :
|
|
chbre = reverse(prise[0].lower())[prise[1:]+'-']
|
|
except :
|
|
print u"Prise inconnue."
|
|
return
|
|
if len(chbre) != 1 :
|
|
print u"Prise correspondante à plusieurs prises %s " % ' '.join(chbre)
|
|
return
|
|
|
|
# On fait la recherche sur la prise
|
|
chbre= prise[0] + chbre[0]
|
|
#print u"Recherche sur chambre %s" % chbre
|
|
arg = 'chbre=%s' % chbre
|
|
|
|
try :
|
|
if only_crans :
|
|
res = { 'machine' : crans().machines() , 'adherent' : [] , 'club' : [] }
|
|
else :
|
|
if not arg :
|
|
# Pas de chaine de recherche fournie
|
|
__usage_brief('Chaine de recherche incorrecte.')
|
|
res = base.search(arg)
|
|
except ValueError, c :
|
|
__usage_brief(c.args[0])
|
|
|
|
# Traitement du résultat
|
|
if not res['adherent'] and not res['machine'] and not res['club']:
|
|
# Pas de résultat dans la base
|
|
# Recherche sur chambre ?
|
|
if arg.count('=') == 1 and arg.split('=')[0] == 'chbre' :
|
|
# Affichage des infos de la chambre
|
|
chbre = arg.split('=')[1]
|
|
print u"Chambre %s inocupée ou invalide (%s)" % (chbre,prise_etat(chbre))
|
|
else :
|
|
print u"Aucun résultat trouvé."
|
|
sys.exit(3)
|
|
# L'affichage souhaité a été précisé ?
|
|
elif only_bornes :
|
|
if not res['machine'] :
|
|
print 'Aucun résultat à afficher'
|
|
sys.exit(4)
|
|
else :
|
|
if len(res['machine']) > limit_aff_details :
|
|
unicode_print(list_bornes(res['machine']))
|
|
else :
|
|
aff(res['machine'])
|
|
elif only_adh :
|
|
if res['adherent'] : aff(res['adherent'])
|
|
elif res['machine'] :
|
|
to_aff=[]
|
|
traite =[]
|
|
for m in res['machine'] :
|
|
a = m.proprietaire()
|
|
if a.idn != 'aid' or a.id() in traite : continue
|
|
traite.append(a.id())
|
|
to_aff.append(m.proprietaire())
|
|
if not(to_aff) :
|
|
print 'Aucun résultat à afficher'
|
|
sys.exit(4)
|
|
aff(to_aff)
|
|
elif res['club'] :
|
|
print 'Aucun résultat à afficher'
|
|
sys.exit(4)
|
|
elif only_mac :
|
|
if res['machine'] : aff(res['machine'],mtech)
|
|
else :
|
|
to_aff = []
|
|
for a in res['adherent'] + res['club'] :
|
|
to_aff += a.machines()
|
|
aff(to_aff)
|
|
elif only_club :
|
|
if res['club'] : aff(res['club'])
|
|
elif res['machine'] :
|
|
to_aff=[]
|
|
traite =[]
|
|
for m in res['machine'] :
|
|
a = m.proprietaire()
|
|
if a.idn != 'cid' or a.id() in traite : continue
|
|
if a.id() in traite : continue
|
|
traite.append(a.id())
|
|
to_aff.append(m.proprietaire())
|
|
if not(to_aff) :
|
|
print 'Aucun résultat à afficher'
|
|
sys.exit(4)
|
|
aff(to_aff)
|
|
elif res['adherent'] :
|
|
print 'Aucun résultat à afficher'
|
|
sys.exit(4)
|
|
# Non : on affiche tout.
|
|
else :
|
|
if res['adherent'] :
|
|
cprint("Résultats trouvés parmi les adhérents :",'cyan')
|
|
aff(res['adherent'])
|
|
if res['machine'] :
|
|
cprint("Résultats trouvés parmi les machines :",'cyan')
|
|
aff(res['machine'],mtech)
|
|
if res['club']:
|
|
cprint("Résultats trouvés parmi les clubs :",'cyan')
|
|
aff(res['club'])
|
|
|
|
if __name__ == '__main__' :
|
|
global debug
|
|
debug = 0
|
|
|
|
import sys, getopt
|
|
|
|
base = crans_ldap()
|
|
|
|
try :
|
|
__recherche()
|
|
except KeyboardInterrupt :
|
|
print u"Recherche interrompue par l'utilisateur."
|
|
sys.exit(255)
|
|
except SystemExit, c :
|
|
# Fin
|
|
sys.exit(c)
|
|
except :
|
|
print u"""Une erreur fatale s'est produite durant l'exécution.
|
|
Pour l'amélioration de ce programme merci de prévenir nounou en spécifiant la
|
|
marche à suivre pour reproduire cette erreur."""
|
|
if debug :
|
|
print '-'*40
|
|
print 'Détails techniques :'
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(1)
|
|
|