[gestion/*.py] Ré-encodage de certains scripts en UTF-8

Ignore-this: dafa22ed56eaf0d816fd089e42672eb5

darcs-hash:20090309212124-0445d-09ac8ae4052b6f333706be1baa1c7f4d94455fd5.gz
This commit is contained in:
Stephane Glondu 2009-03-09 22:21:24 +01:00
parent 7addc503a8
commit cc31727b60
21 changed files with 1351 additions and 1351 deletions

View file

@ -1,15 +1,15 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" Collection de fonction/classe pour avoir un bel affichage """ Collection de fonction/classe pour avoir un bel affichage
Copyright (C) Frédéric Pauget Copyright (C) Frédéric Pauget
Licence : GPLv2 Licence : GPLv2
""" """
import sys, re, os, tempfile import sys, re, os, tempfile
# Détermination de l'encodage # Détermination de l'encodage
encoding = None encoding = None
try: try:
from locale import getpreferredencoding from locale import getpreferredencoding
@ -20,7 +20,7 @@ except:
if not encoding: if not encoding:
encoding = sys.stdin.encoding or "ISO-8859-15" encoding = sys.stdin.encoding or "ISO-8859-15"
# Si aucune locale n'est définie, on se met en ISO-8859-15 # Si aucune locale n'est définie, on se met en ISO-8859-15
if encoding == "ANSI_X3.4-1968": if encoding == "ANSI_X3.4-1968":
encoding = "ISO-8859-15" encoding = "ISO-8859-15"
@ -32,13 +32,13 @@ else:
stdout_atty = sys.stdout.isatty() stdout_atty = sys.stdout.isatty()
def dialog(backtitle,arg,dialogrc='') : def dialog(backtitle,arg,dialogrc='') :
""" Affiche la boite de dialogue défine avec les arguments fournis """ Affiche la boite de dialogue défine avec les arguments fournis
(cf man dialog) (cf man dialog)
si tout se déroule bien retourne : si tout se déroule bien retourne :
[ 0, [ reponse(s) ] ] [ 0, [ reponse(s) ] ]
si annulatin retourne : si annulatin retourne :
[ 1, [] ] [ 1, [] ]
si appui sur ESC demande confirmation de l'abandon et exécute sys.exit(0) si appui sur ESC demande confirmation de l'abandon et exécute sys.exit(0)
si erreur dans les arguments raise RuntimeError si erreur dans les arguments raise RuntimeError
""" """
f = tempfile.NamedTemporaryFile() f = tempfile.NamedTemporaryFile()
@ -49,7 +49,7 @@ def dialog(backtitle,arg,dialogrc='') :
# Annuler # Annuler
f.close() f.close()
return [ 1, [] ] return [ 1, [] ]
# Lecture du fichier de résultat et effacement # Lecture du fichier de résultat et effacement
try: try:
result=f.readlines() result=f.readlines()
f.close() f.close()
@ -62,7 +62,7 @@ def dialog(backtitle,arg,dialogrc='') :
raise RuntimeError( arg, result[1].strip() ) raise RuntimeError( arg, result[1].strip() )
elif res==65280 : elif res==65280 :
# Appui sur ESC # Appui sur ESC
arg1 = u'--title "Annulation" --yesno "Quitter ?\nLes dernières modifications seront perdues." 6 48' arg1 = u'--title "Annulation" --yesno "Quitter ?\nLes dernières modifications seront perdues." 6 48'
print backtitle print backtitle
cmd = u'%s /usr/bin/dialog --backtitle "%s" %s' % (dialogrc, backtitle,arg1) cmd = u'%s /usr/bin/dialog --backtitle "%s" %s' % (dialogrc, backtitle,arg1)
res = os.system(cmd.encode('iso-8859-15','ignore') ) res = os.system(cmd.encode('iso-8859-15','ignore') )
@ -73,8 +73,8 @@ def dialog(backtitle,arg,dialogrc='') :
def coul(txt, col=None): def coul(txt, col=None):
""" """
Retourne la chaine donnée encadrée des séquences qui Retourne la chaine donnée encadrée des séquences qui
vont bien pour obtenir la couleur souhaitée vont bien pour obtenir la couleur souhaitée
Les couleur sont celles de codecol Les couleur sont celles de codecol
Il est possible de changer la couleur de fond grace aux couleur f_<couleur> Il est possible de changer la couleur de fond grace aux couleur f_<couleur>
""" """
@ -123,7 +123,7 @@ def cprint(txt, col='blanc', newline=True):
def tableau(data, titre=None, largeur=None, alignement=None, format=None): def tableau(data, titre=None, largeur=None, alignement=None, format=None):
""" """
Retourne une chaine formatée repésentant un tableau. Retourne une chaine formatée repésentant un tableau.
data : liste de listes, chacune contenant les valeurs d'une ligne data : liste de listes, chacune contenant les valeurs d'une ligne
@ -132,7 +132,7 @@ def tableau(data, titre=None, largeur=None, alignement=None, format=None):
largeur : liste des largeurs des colonnes, '*' met la plus grande largeur : liste des largeurs des colonnes, '*' met la plus grande
largeur possible. largeur possible.
Si None, réduit aux max chaque colonne Si None, réduit aux max chaque colonne
alignement : liste des alignements : c = centrer alignement : liste des alignements : c = centrer
g = gauche g = gauche
@ -149,7 +149,7 @@ def tableau(data, titre=None, largeur=None, alignement=None, format=None):
elif titre : elif titre :
nbcols = len(titre) nbcols = len(titre)
else : else :
return u'Aucune donnée' return u'Aucune donnée'
# Formats # Formats
######### #########
@ -195,12 +195,12 @@ def tableau(data, titre=None, largeur=None, alignement=None, format=None):
# Alignement # Alignement
if l > largeur : if l > largeur :
# découpage d'une chaine trop longue # découpage d'une chaine trop longue
regexp = re.compile('\x1b\[1;([0-9]|[0-9][0-9])m') regexp = re.compile('\x1b\[1;([0-9]|[0-9][0-9])m')
new_data = u'' new_data = u''
new_len = 0 new_len = 0
# On laisse la mise en forme et on coupe les caratères affichés # On laisse la mise en forme et on coupe les caratères affichés
while True : while True :
s = regexp.search(data) s = regexp.search(data)
if s and not s.start() : if s and not s.start() :
@ -208,12 +208,12 @@ def tableau(data, titre=None, largeur=None, alignement=None, format=None):
new_data += data[:s.end()] new_data += data[:s.end()]
data = data[s.end():] data = data[s.end():]
elif new_len < largeur - 1 : elif new_len < largeur - 1 :
# c'est un caratère normal, et il y a la place # c'est un caratère normal, et il y a la place
new_data += data[0] new_data += data[0]
data = data[1:] data = data[1:]
new_len += 1 new_len += 1
else : else :
# c'est un caratère normal mais on a dépassé le max # c'est un caratère normal mais on a dépassé le max
data = data[1:] data = data[1:]
if not data : if not data :
return new_data + '*' return new_data + '*'
@ -237,19 +237,19 @@ def tableau(data, titre=None, largeur=None, alignement=None, format=None):
if titre : if titre :
# ligne de titre # ligne de titre
chaine = sep_col + sep_col.join([aligne(titre[i],'c',largeur[i]) for i in range(nbcols)]) + sep_col + u'\n' chaine = sep_col + sep_col.join([aligne(titre[i],'c',largeur[i]) for i in range(nbcols)]) + sep_col + u'\n'
# ligne de séparation # ligne de séparation
chaine += sep_col + u'+'.join([u'-'*largeur[i] for i in range(nbcols)]) + sep_col + u'\n' chaine += sep_col + u'+'.join([u'-'*largeur[i] for i in range(nbcols)]) + sep_col + u'\n'
else : else :
chaine = u'' chaine = u''
# Les données # Les données
############# #############
chaine += u'\n'.join([sep_col + sep_col.join([ligne[i] for i in range(nbcols)]) + sep_col for ligne in data]) chaine += u'\n'.join([sep_col + sep_col.join([ligne[i] for i in range(nbcols)]) + sep_col for ligne in data])
return chaine return chaine
def get_screen_size(): def get_screen_size():
"""Retourne la taille de l'écran. """Retourne la taille de l'écran.
Sous la forme d'un tuble (lignes, colonnes)""" Sous la forme d'un tuble (lignes, colonnes)"""
@ -265,7 +265,7 @@ def get_screen_size():
def prompt(prompt, defaut='', couleur='gras'): def prompt(prompt, defaut='', couleur='gras'):
u""" u"""
Pose la question prompt en couleur (défaut gras), retourne la réponse. Pose la question prompt en couleur (défaut gras), retourne la réponse.
""" """
sys.stdout.write(coul(prompt, couleur).encode(encoding)) sys.stdout.write(coul(prompt, couleur).encode(encoding))
if defaut : if defaut :
@ -276,12 +276,12 @@ def prompt(prompt, defaut='', couleur='gras'):
return v return v
class anim : class anim :
""" Permet de créer une animation : """ Permet de créer une animation :
truc................./ truc................./
truc.................- truc.................-
truc.................\ truc.................\
truc.................| truc.................|
ou une barre de progression si le nombre total d'itérations est founi. ou une barre de progression si le nombre total d'itérations est founi.
""" """
def __init__(self,truc,iter=0) : def __init__(self,truc,iter=0) :
""" Affichage de : """ Affichage de :
@ -304,7 +304,7 @@ class anim :
def cycle(self) : def cycle(self) :
""" Efface la ligne courrante et """ Efface la ligne courrante et
affiche : truc..................? affiche : truc..................?
? caratère variant à chaque appel """ ? caratère variant à chaque appel """
sys.stdout.write(el + self.txt) sys.stdout.write(el + self.txt)
if self.iter!=0 : if self.iter!=0 :
sys.stdout.write('[') sys.stdout.write('[')

View file

@ -1,5 +1,5 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
# #
# $Id: ajoute_chambre.py,v 1.2 2007-02-24 01:08:45 dimino Exp $ # $Id: ajoute_chambre.py,v 1.2 2007-02-24 01:08:45 dimino Exp $
# #
@ -25,7 +25,7 @@
# #
# #
# Description: # Description:
# Ajoute une chambre sur une prise libre (fait pour le batiment g à la base) # Ajoute une chambre sur une prise libre (fait pour le batiment g à la base)
# #
import sys, os import sys, os
@ -35,14 +35,14 @@ sys.path.append('/usr/scripts/gestion')
from annuaires import chbre_prises, reverse, bat_switchs from annuaires import chbre_prises, reverse, bat_switchs
from affich_tools import cprint from affich_tools import cprint
# C'est juste pour le déboggage # C'est juste pour le déboggage
__fichier_annuaire = "/usr/scripts/gestion/annuaires.py" __fichier_annuaire = "/usr/scripts/gestion/annuaires.py"
def assigne_chambre(prise, chbre): def assigne_chambre(prise, chbre):
""" Assigne une chambre à une prise. """ Assigne une chambre à une prise.
prise doit être de la forme bnnn[g/d], ou nnn[g/d], dans ce dernier cas le bâtiment est le g. prise doit être de la forme bnnn[g/d], ou nnn[g/d], dans ce dernier cas le bâtiment est le g.
""" """
if len(chbre) != 3 or not chbre.isdigit(): if len(chbre) != 3 or not chbre.isdigit():
@ -75,7 +75,7 @@ prise doit
# if chambre != 'XXX': # if chambre != 'XXX':
# return 'prise_utilisee' # return 'prise_utilisee'
# Ajout effectif de la chambre sur la prise donnée # Ajout effectif de la chambre sur la prise donnée
annuaire = open(__fichier_annuaire, 'r') annuaire = open(__fichier_annuaire, 'r')
tampon = annuaire.read() tampon = annuaire.read()
@ -109,15 +109,15 @@ prise doit
if not user: if not user:
user = os.getenv('USER') or "inconnu" user = os.getenv('USER') or "inconnu"
# Vu que ça va être mis dans la ligne de commande éxécuter après, # Vu que ça va être mis dans la ligne de commande éxécuter après,
# autant être parano. # autant être parano.
for c in user: for c in user:
if not (c.isalnum or c in [ '-', '_' ]): if not (c.isalnum or c in [ '-', '_' ]):
user = "(uid=%d)" % (os.getuid()) user = "(uid=%d)" % (os.getuid())
break break
os.system('cd /usr/scripts/gestion && /usr/bin/cvs commit %s \ os.system('cd /usr/scripts/gestion && /usr/bin/cvs commit %s \
-m "ajoute_chambre.py: chambre %s%s ajouté sur la prise %s%s par %s"' % -m "ajoute_chambre.py: chambre %s%s ajouté sur la prise %s%s par %s"' %
(__fichier_annuaire, bat, chbre, bat, prise, user)) (__fichier_annuaire, bat, chbre, bat, prise, user))
@ -133,18 +133,18 @@ def __aide():
""" Aide """ """ Aide """
cprint(u"""Usage: %s [OPTIONS] <prise> <chambre> cprint(u"""Usage: %s [OPTIONS] <prise> <chambre>
Ajoute une chambre sur une prise qui n'était pas encore utilisé. Ajoute une chambre sur une prise qui n'était pas encore utilisé.
Options: Options:
-h, --help affiche cette aide -h, --help affiche cette aide
<prise> doit être de la forme bnnn ou nnn : <prise> doit être de la forme bnnn ou nnn :
- B est le batiment (g si non spécifié) - B est le batiment (g si non spécifié)
- nnn est le numéro de la prise - nnn est le numéro de la prise
<chambre> doit être de la forme nnn <chambre> doit être de la forme nnn
Rapporter toutes anomalies à <dimino@crans.org>.""" % sys.argv[0].split('/')[-1].split('.')[0]) Rapporter toutes anomalies à <dimino@crans.org>.""" % sys.argv[0].split('/')[-1].split('.')[0])
sys.exit(0) sys.exit(0)
@ -173,7 +173,7 @@ if __name__ == '__main__':
__usage(u"Format de la chambre invalide") __usage(u"Format de la chambre invalide")
elif resultat == 'chambre_deja_cablee': elif resultat == 'chambre_deja_cablee':
__usage(u"La chambre est déjà cablée") __usage(u"La chambre est déjà cablée")
elif resultat == 'batiment_inconnu': elif resultat == 'batiment_inconnu':
__usage(u"Le batiment n'existe pas") __usage(u"Le batiment n'existe pas")
@ -182,11 +182,11 @@ if __name__ == '__main__':
__usage(u"La prise n'existe pas") __usage(u"La prise n'existe pas")
elif resultat == 'prise_utilisee': elif resultat == 'prise_utilisee':
__usage(u"La prise est déjà utilisée") __usage(u"La prise est déjà utilisée")
elif resultat == 'prise_introuvable': elif resultat == 'prise_introuvable':
cprint(u"""La prise n'a pas été trouvé dans l'annuaire. cprint(u"""La prise n'a pas été trouvé dans l'annuaire.
Vérifiez que vous avez bien mis le numéro de prise et de chambre.""") Vérifiez que vous avez bien mis le numéro de prise et de chambre.""")
elif resultat == 'fichier_annuaire_invalide': elif resultat == 'fichier_annuaire_invalide':
cprint(u"Le fichier d'annuaire n'est pas reconnu, envoyer un mail à dimino@crans.org") cprint(u"Le fichier d'annuaire n'est pas reconnu, envoyer un mail à dimino@crans.org")

View file

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
# Liste des bâtiments avec switch manageables # Liste des bâtiments avec switch manageables
bat_switchs = [ 'a' , 'b' , 'c' , 'h' , 'i' , 'j' , 'm' , 'p'] bat_switchs = [ 'a' , 'b' , 'c' , 'h' , 'i' , 'j' , 'm' , 'p']
bat_manuels = [ 'o' , 'r' ] # Y en a plus aucun :) ou presque bat_manuels = [ 'o' , 'r' ] # Y en a plus aucun :) ou presque
@ -9,8 +9,8 @@ aide={
'g' : "appart du RDC=G901" 'g' : "appart du RDC=G901"
} }
# Toute chambre ne commencant pas par 3 chiffres sera considéré comme un local club # Toute chambre ne commencant pas par 3 chiffres sera considéré comme un local club
# En conséquence les locaux club ne devront pas commencer par 3 chiffres. # En conséquence les locaux club ne devront pas commencer par 3 chiffres.
#Pour le G : #Pour le G :
# le signe - indique un cable 10 Mbps # le signe - indique un cable 10 Mbps
@ -52,8 +52,8 @@ chbre_prises={ 'a' :
'603d':'301', '608d':'302', 'cl6':'303'}, '603d':'301', '608d':'302', 'cl6':'303'},
# Le local club du 6ème et les chambres A608d, A603d sont sur la # Le local club du 6ème et les chambres A608d, A603d sont sur la
# prise 202 (switch au 6ème dans le local technique à coté de # prise 202 (switch au 6ème dans le local technique à coté de
# l'ascensseur # l'ascensseur
'b' : 'b' :
@ -465,11 +465,11 @@ chbre_prises={ 'a' :
'XXX':'641' , 'XXX':'642' , 'XXX':'643' , 'XXX':'644' , 'XXX':'641' , 'XXX':'642' , 'XXX':'643' , 'XXX':'644' ,
'XXX':'645' , 'XXX':'646', 'XXX':'647' , 'XXX':'648' , 'XXX':'645' , 'XXX':'646', 'XXX':'647' , 'XXX':'648' ,
# Ce switch n'est pas au bâtiment G comme on pourrait le croire # Ce switch n'est pas au bâtiment G comme on pourrait le croire
'999':'701' , '998':'702' , '997':'703' , '996':'704'} '999':'701' , '998':'702' , '997':'703' , '996':'704'}
} }
# Prises d'uplink, de machines du crans / Prises d'utilité CRANS # Prises d'uplink, de machines du crans / Prises d'utilité CRANS
uplink_prises={ 'a' : uplink_prises={ 'a' :
{ 49 : 'uplink->backbone', 50 : 'uplink->bata-1', { 49 : 'uplink->backbone', 50 : 'uplink->bata-1',
149 : 'uplink->bata-0', 150 : 'uplink->bata-2', 149 : 'uplink->bata-0', 150 : 'uplink->bata-2',
@ -535,8 +535,8 @@ def reverse(bat) :
def all_switchs(bat=None): def all_switchs(bat=None):
"""Retourne la liste des switchs pour un batiment. """Retourne la liste des switchs pour un batiment.
Si bat est donné, seulement pour le bâtiment demandé, sinon pour Si bat est donné, seulement pour le bâtiment demandé, sinon pour
tous les bâtiments. bat peut être une liste aussi. Le backbone n'est tous les bâtiments. bat peut être une liste aussi. Le backbone n'est
pas pris en compte. La convention est batx-y sauf si y=0 et on a donc pas pris en compte. La convention est batx-y sauf si y=0 et on a donc
simplement batx""" simplement batx"""
def cmp(x,y): def cmp(x,y):
@ -568,7 +568,7 @@ def locaux_clubs() :
'Mcl0' : 'Shape', 'Mcl0' : 'Shape',
'Mcl1' : 'Krobot', 'Mcl1' : 'Krobot',
'EXT' : 'EXT' } 'EXT' : 'EXT' }
# Ajout des locaux d'étage A, B et C # Ajout des locaux d'étage A, B et C
for b in 'ABC' : for b in 'ABC' :
for i in range(2,7) : for i in range(2,7) :
locaux_clubs['%scl%i' % ( b, i)] = '%i@%s' % (i, b) locaux_clubs['%scl%i' % ( b, i)] = '%i@%s' % (i, b)

View file

@ -1,9 +1,9 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
# Serveur SSL qui renvoie la MAC correspondant à une IP # Serveur SSL qui renvoie la MAC correspondant à une IP
# Ce serveur est utilisé sur Nectaris par les bornes wifi pour faire # Ce serveur est utilisé sur Nectaris par les bornes wifi pour faire
# les requêtes ARP. # les requêtes ARP.
# Lancement : twistd -n -y arp.py --pidfile=/var/run/arp.pid # Lancement : twistd -n -y arp.py --pidfile=/var/run/arp.pid
# Pas de -n pour qu'il passe en fond # Pas de -n pour qu'il passe en fond
@ -29,18 +29,18 @@ import re
class ServerContextFactory(ContextFactory): class ServerContextFactory(ContextFactory):
def getContext(self): def getContext(self):
"""Création d'un contexte SSL côté serveur.""" """Création d'un contexte SSL côté serveur."""
ctx = SSL.Context(SSL.SSLv23_METHOD) ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_certificate_file('/etc/ssl/certs/nectaris.pem') ctx.use_certificate_file('/etc/ssl/certs/nectaris.pem')
ctx.use_privatekey_file('/etc/ssl/private/nectaris.pem') ctx.use_privatekey_file('/etc/ssl/private/nectaris.pem')
return ctx return ctx
class ARPProtocol(basic.LineReceiver): class ARPProtocol(basic.LineReceiver):
"""Protocole de communication pour récupérer une adresse MAC. """Protocole de communication pour récupérer une adresse MAC.
Chaque lignee reçue contient une adresse IP et le serveur répond Chaque lignee reçue contient une adresse IP et le serveur répond
avec l'adresse MAC correspondante ou avec `unknown' si celle-ci avec l'adresse MAC correspondante ou avec `unknown' si celle-ci
est inconnue (ou non autorisée). est inconnue (ou non autorisée).
""" """
def lineReceived(self, IP): def lineReceived(self, IP):
self.factory.getMac(IP self.factory.getMac(IP
@ -51,7 +51,7 @@ class ARPProtocol(basic.LineReceiver):
def answerMac(self, m): def answerMac(self, m):
"""Renvoie au client la bonne adresse MAC. """Renvoie au client la bonne adresse MAC.
`m' peut être None. `m' peut être None.
""" """
if m: if m:
return self.transport.write(str(m) + "\r\n") return self.transport.write(str(m) + "\r\n")
@ -59,7 +59,7 @@ class ARPProtocol(basic.LineReceiver):
return self.transport.write("unknown\r\n") return self.transport.write("unknown\r\n")
class ARPFactory(protocol.ServerFactory): class ARPFactory(protocol.ServerFactory):
"""Backend du serveur. Effectue la résolution IP/MAC.""" """Backend du serveur. Effectue la résolution IP/MAC."""
protocol = ARPProtocol protocol = ARPProtocol
def __init__(self, network='0.0.0.0/0'): def __init__(self, network='0.0.0.0/0'):
@ -70,26 +70,26 @@ class ARPFactory(protocol.ServerFactory):
return defer.succeed(self._getMac(IP)) return defer.succeed(self._getMac(IP))
def _getMac(self, IP): def _getMac(self, IP):
"""Fonction réelle, synchrone, qui obtient l'adresse MAC.""" """Fonction réelle, synchrone, qui obtient l'adresse MAC."""
try: try:
if AddrInNet(IP, self.network): if AddrInNet(IP, self.network):
results = self.ldap.search('ip=%s' % IP)['machine'] results = self.ldap.search('ip=%s' % IP)['machine']
if results: if results:
# On a au moins un résultat, on retourne le premier # On a au moins un résultat, on retourne le premier
return results[0].mac().strip() return results[0].mac().strip()
else: else:
# On a rien # On a rien
return None return None
else: else:
# L'IP n'est pas autorisée # L'IP n'est pas autorisée
return None return None
except ValueError: except ValueError:
# A priori, ce n'était pas une IP # A priori, ce n'était pas une IP
return None return None
# Corps du programme # Corps du programme
# On écoute sur le port 5243 et on ne répond qu'aux requêtes concernant le # On écoute sur le port 5243 et on ne répond qu'aux requêtes concernant le
# sous-réseau wifi # sous-réseau wifi
application = service.Application('arp') application = service.Application('arp')
factory = ARPFactory('138.231.148.0/21') factory = ARPFactory('138.231.148.0/21')
# Remplacer SSL par TCP pour ne pas utiliser SSL et virer ServerContextFactory # Remplacer SSL par TCP pour ne pas utiliser SSL et virer ServerContextFactory

View file

@ -1,5 +1,5 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" """
Script de changement de mots de passe LDAP Script de changement de mots de passe LDAP
@ -7,14 +7,14 @@ Script de changement de mots de passe LDAP
Utilisation : Utilisation :
* cas 1 : sans arguements par un utlisateur lambda : * cas 1 : sans arguements par un utlisateur lambda :
changement de son propre mdp changement de son propre mdp
* cas 2 : avec argument par un utilisateur ayant accès * cas 2 : avec argument par un utilisateur ayant accès
total à la base LDAP (respbats) mais PAS ROOT : total à la base LDAP (respbats) mais PAS ROOT :
changement du mdp de l'adhérent fourni en argument, changement du mdp de l'adhérent fourni en argument,
impossibilité de modifier le mdp d'un compte privilégié impossibilité de modifier le mdp d'un compte privilégié
* cas 3 : lancé par root : possibilité de modifier * cas 3 : lancé par root : possibilité de modifier
tous les mots de passe LDAP tous les mots de passe LDAP
Copyright (C) Frédéric Pauget Copyright (C) Frédéric Pauget
Licence : GPLv2 Licence : GPLv2
""" """
@ -33,17 +33,17 @@ uri = 'ldap://ldap.adm.crans.org'
syslog.openlog('chgpass',syslog.LOG_PID,syslog.LOG_AUTH) syslog.openlog('chgpass',syslog.LOG_PID,syslog.LOG_AUTH)
def decode64(chaine): def decode64(chaine):
""" Décode une chaine de caratère utf8/64 et retourne un unicode """ """ Décode une chaine de caratère utf8/64 et retourne un unicode """
try: try:
return base64.decodestring(chaine).decode('utf8','ignore') return base64.decodestring(chaine).decode('utf8','ignore')
except: except:
return chaine.decode('utf8','ignore') return chaine.decode('utf8','ignore')
def chgpass(dn) : def chgpass(dn) :
cprint(u"""Le nouveau mot de passe doit comporter au minimum 6 caractères. cprint(u"""Le nouveau mot de passe doit comporter au minimum 6 caractères.
Il ne doit pas être basé sur un mot du dictionnaire.""", 'jaune') Il ne doit pas être basé sur un mot du dictionnaire.""", 'jaune')
print "Il est conseillé d'utiliser une combinaison de minuscules, majuscules,\nde chiffres et d'au moins un caractère spécial." print "Il est conseillé d'utiliser une combinaison de minuscules, majuscules,\nde chiffres et d'au moins un caractère spécial."
print "Le mot de passe tapé ne sera pas écrit à l'écran." print "Le mot de passe tapé ne sera pas écrit à l'écran."
print "Taper Ctrl-D pour abandonner" print "Taper Ctrl-D pour abandonner"
try : try :
@ -60,17 +60,17 @@ Il ne doit pas
try: try:
mdp = mdp.encode('ascii') mdp = mdp.encode('ascii')
except UnicodeEncodeError: except UnicodeEncodeError:
cprint(u'Les accents ou caractères bizarres ne sont pas autorisés (mais #!@*&%{}| le sont !)', cprint(u'Les accents ou caractères bizarres ne sont pas autorisés (mais #!@*&%{}| le sont !)',
'rouge') 'rouge')
continue continue
## 2bis - On évite une attaque de type injection de code shell ## 2bis - On évite une attaque de type injection de code shell
if "'" in mdp: if "'" in mdp:
cprint(u'Les accents ou caractères bizarres ne sont pas autorisés (mais #!@*&%{}| le sont !)', cprint(u'Les accents ou caractères bizarres ne sont pas autorisés (mais #!@*&%{}| le sont !)',
'rouge') 'rouge')
continue continue
## 3 - assez de caractères de types différents ? ## 3 - assez de caractères de types différents ?
chiffres = 0 chiffres = 0
majuscules = 0 majuscules = 0
minuscules = 0 minuscules = 0
@ -94,9 +94,9 @@ Il ne doit pas
test = commands.getoutput("echo '%s' | /usr/sbin/crack_testlib" % mdp) test = commands.getoutput("echo '%s' | /usr/sbin/crack_testlib" % mdp)
if test.split(':')[-1] != ' ok' : if test.split(':')[-1] != ' ok' :
commentaire = { commentaire = {
' it does not contain enough DIFFERENT characters': u'Il y a trop de caractères identiques.' , ' it does not contain enough DIFFERENT characters': u'Il y a trop de caractères identiques.' ,
' it is based on a dictionary word': u'Le mot de passe est basé sur un mot du dictionnaire' , ' it is based on a dictionary word': u'Le mot de passe est basé sur un mot du dictionnaire' ,
' it is too simplistic/systematic': u'Le mot de passe est trop simple/répétitif' ' it is too simplistic/systematic': u'Le mot de passe est trop simple/répétitif'
}.get(test.split(':')[-1],test.split(':')[-1]) }.get(test.split(':')[-1],test.split(':')[-1])
cprint(commentaire, 'rouge') cprint(commentaire, 'rouge')
continue continue
@ -104,7 +104,7 @@ Il ne doit pas
### On redemande le mot de passe ### On redemande le mot de passe
mdp1 = getpass.getpass('Retaper mot de passe : ') mdp1 = getpass.getpass('Retaper mot de passe : ')
if mdp != mdp1 : if mdp != mdp1 :
cprint(u'Les deux mots de passe entrés sont différents, réesayer', 'rouge') cprint(u'Les deux mots de passe entrés sont différents, réesayer', 'rouge')
continue continue
break break
@ -114,7 +114,7 @@ Il ne doit pas
cprint(u'Erreur lors du changement de mot de passe', 'rouge') cprint(u'Erreur lors du changement de mot de passe', 'rouge')
syslog.syslog("LDAP password changed for dn=%s" % dn) syslog.syslog("LDAP password changed for dn=%s" % dn)
else : else :
cprint(u'Changement effectué avec succès', u'vert') cprint(u'Changement effectué avec succès', u'vert')
except KeyboardInterrupt : except KeyboardInterrupt :
cprint(u'\nAbandon', 'rouge') cprint(u'\nAbandon', 'rouge')
@ -125,7 +125,7 @@ Il ne doit pas
pass pass
if __name__ == '__main__' : if __name__ == '__main__' :
sys.stdout.write('\r \r') # Pour esthétique lors de l'utilisation par sudo sys.stdout.write('\r \r') # Pour esthétique lors de l'utilisation par sudo
if len(sys.argv) == 1 : if len(sys.argv) == 1 :
# Changement de son mot de passe # Changement de son mot de passe
login = getuser() login = getuser()
@ -136,7 +136,7 @@ if __name__ == '__main__' :
print "Changement du mot de passe du compte choisi." print "Changement du mot de passe du compte choisi."
sys.exit(255) sys.exit(255)
else : else :
# Changement du mot de passe par un câbleur ou une nounou # Changement du mot de passe par un câbleur ou une nounou
login = sys.argv[1] login = sys.argv[1]
self_mode = False self_mode = False
for c in login[:] : for c in login[:] :
@ -153,12 +153,12 @@ if __name__ == '__main__' :
else : else :
s = commands.getoutput("/usr/bin/ldapsearch -D cn=readonly,dc=crans,dc=org -y/etc/ldap/readonly -x -LLL '(&(objectClass=posixAccount)(uid=%s))' dn nom prenom droits | grep -v MultiMachines" % login).strip() s = commands.getoutput("/usr/bin/ldapsearch -D cn=readonly,dc=crans,dc=org -y/etc/ldap/readonly -x -LLL '(&(objectClass=posixAccount)(uid=%s))' dn nom prenom droits | grep -v MultiMachines" % login).strip()
if not s : if not s :
cprint(u'Login non trouvé dans la base LDAP', 'rouge') cprint(u'Login non trouvé dans la base LDAP', 'rouge')
sys.exit(3) sys.exit(3)
# Ca a l'air bon # Ca a l'air bon
if s.find('\n\n') != -1 : if s.find('\n\n') != -1 :
# Plusieurs trouvé : pas normal # Plusieurs trouvé : pas normal
cprint(u'Erreur lors de la recherche du login : plusieurs occurences !', 'rouge') cprint(u'Erreur lors de la recherche du login : plusieurs occurences !', 'rouge')
sys.exit(4) sys.exit(4)
@ -174,7 +174,7 @@ if __name__ == '__main__' :
sys.exit(5) sys.exit(5)
if self_mode : if self_mode :
# Il faut vérifier l'ancien mot de passe # Il faut vérifier l'ancien mot de passe
ldap_auth_dn = dn ldap_auth_dn = dn
ldap_password = getpass.getpass('Mot de passe actuel : ') ldap_password = getpass.getpass('Mot de passe actuel : ')
s = commands.getoutput("/usr/bin/ldapwhoami -H '%s' -x -D '%s' -w '%s'" % ( uri, ldap_auth_dn, ldap_password ) ).strip() s = commands.getoutput("/usr/bin/ldapwhoami -H '%s' -x -D '%s' -w '%s'" % ( uri, ldap_auth_dn, ldap_password ) ).strip()
@ -188,7 +188,7 @@ if __name__ == '__main__' :
sys.exit(8) sys.exit(8)
elif len(s) > 3 and os.getuid()!=0 : elif len(s) > 3 and os.getuid()!=0 :
# Adhérent avec droits et on est pas root # Adhérent avec droits et on est pas root
From = 'roots@crans.org' From = 'roots@crans.org'
To = 'roots@crans.org' To = 'roots@crans.org'
mail = """From: Root <%s> mail = """From: Root <%s>
@ -203,7 +203,7 @@ Tentative de changement du mot de passe de %s par %s.
conn = smtplib.SMTP('localhost') conn = smtplib.SMTP('localhost')
conn.sendmail(From, To , mail ) conn.sendmail(From, To , mail )
conn.quit() conn.quit()
cprint(u'Impossible de changer le mot de passe de cet adhérent : compte privilégié', 'rouge') cprint(u'Impossible de changer le mot de passe de cet adhérent : compte privilégié', 'rouge')
sys.exit(6) sys.exit(6)
# Finalement ! # Finalement !

View file

@ -1,10 +1,10 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" Changement du shell de l'utilisateur lancant le programme """ Changement du shell de l'utilisateur lancant le programme
DOIT ETRE LANCE PAR SUDO DOIT ETRE LANCE PAR SUDO
Copyright (C) Frédéric Pauget Copyright (C) Frédéric Pauget
Licence : GPLv2 Licence : GPLv2
""" """
import os, sys import os, sys
@ -15,18 +15,18 @@ from ldap_crans import crans_ldap
db = crans_ldap() db = crans_ldap()
uid = os.getenv('SUDO_UID') uid = os.getenv('SUDO_UID')
if not uid : if not uid :
print "Impossible de déterminer l'utilisateur" print "Impossible de déterminer l'utilisateur"
sys.exit(1) sys.exit(1)
s = db.search('uidNumber=%s' % os.getenv('SUDO_UID'),'w') s = db.search('uidNumber=%s' % os.getenv('SUDO_UID'),'w')
# On vérifie que c'est pas un club # On vérifie que c'est pas un club
club = s['club'] club = s['club']
if len(club) == 1 : if len(club) == 1 :
print 'Pas de changement de shell pour les clubs' print 'Pas de changement de shell pour les clubs'
sys.exit(2) sys.exit(2)
# On regarde si on a des résultats dans les adhérents # On regarde si on a des résultats dans les adhérents
adh = s['adherent'] adh = s['adherent']
if len(adh) != 1 : if len(adh) != 1 :
print 'Erreur fatale lors de la consultation de la base LDAP' print 'Erreur fatale lors de la consultation de la base LDAP'

View file

@ -1,34 +1,34 @@
# -*- python -*- # -*- python -*-
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
############################################ ############################################
## Définition du comportement des scripts ## ## Définition du comportement des scripts ##
############################################ ############################################
from time import localtime from time import localtime
# Administratif # Administratif
caution = 0 caution = 0
#Précablage possible ? #Précablage possible ?
precab = False precab = False
# Année scolaire en cours # Année scolaire en cours
dat = localtime() dat = localtime()
if dat[1]<9 : ann_scol = dat[0]-1 if dat[1]<9 : ann_scol = dat[0]-1
else : ann_scol = dat[0] else : ann_scol = dat[0]
# Bloquage si carte d'étudiants manquante pour l'année en cours # Bloquage si carte d'étudiants manquante pour l'année en cours
# Au niveau du Squid # Au niveau du Squid
bl_carte_et_actif = True bl_carte_et_actif = True
# L'adhérent est considéré comme paiement pas ok # L'adhérent est considéré comme paiement pas ok
bl_carte_et_definitif = False bl_carte_et_definitif = False
# Gel des cableurs pas a jour de cotisation # Gel des cableurs pas a jour de cotisation
# Les droits ne sont pas retires mais il n'y a plus de sudo # Les droits ne sont pas retires mais il n'y a plus de sudo
bl_vieux_cableurs = False bl_vieux_cableurs = False
##Création de comptes ##Création de comptes
# Gid des comptes créés # Gid des comptes créés
gid=100 gid=100
club_gid=120 club_gid=120
# Shell # Shell
@ -37,7 +37,7 @@ club_login_shell='/usr/bin/rssh'
# Longueur maximale d'un login # Longueur maximale d'un login
maxlen_login=15 maxlen_login=15
## Répertoire de stockage des objets détruits ## Répertoire de stockage des objets détruits
cimetiere = '/home/cimetiere' cimetiere = '/home/cimetiere'
## Adresses mac utiles ## Adresses mac utiles
@ -47,7 +47,7 @@ mac_titanic = 'aa:73:65:63:6f:76'
## Serveur principal de bcfg2 ## Serveur principal de bcfg2
bcfg2_main = "vert.adm.crans.org" bcfg2_main = "vert.adm.crans.org"
## Compatibilité inverse ## Compatibilité inverse
cfengine_main = bcfg2_main cfengine_main = bcfg2_main
## Fichier de mapping lun/nom de volume iscsi ## Fichier de mapping lun/nom de volume iscsi
@ -58,10 +58,10 @@ class impression:
"""Cette classe contient toutes les variables """Cette classe contient toutes les variables
de prix concernant l'impression""" de prix concernant l'impression"""
# Découvert autorisé (en euro) # Découvert autorisé (en euro)
decouvert = 0. decouvert = 0.
###### Variables de prix (tout est exprimé en centimes) ###### ###### Variables de prix (tout est exprimé en centimes) ######
# Cout imprimante : 9150,60 euros # Cout imprimante : 9150,60 euros
# 200.000 pages par mois, garantie 1an # 200.000 pages par mois, garantie 1an
@ -91,13 +91,13 @@ class impression:
# 1406.50 les 3 tambours couleurs pour 40.000 passages # 1406.50 les 3 tambours couleurs pour 40.000 passages
c_tambour_coul = 3.51624 c_tambour_coul = 3.51624
# Une feuille à 5% = 5 unites # Une feuille à 5% = 5 unites
# Cout de 1 unité de noir # Cout de 1 unité de noir
# 1 toner fait 125.000 unites et coute 203.32euros # 1 toner fait 125.000 unites et coute 203.32euros
# 1 kit de nettoyage fait 250.000 unites et coute 63.30euros # 1 kit de nettoyage fait 250.000 unites et coute 63.30euros
c_noir = 0.18798 c_noir = 0.18798
# Cout de 1 unité de couleur # Cout de 1 unité de couleur
# 1 tonner fait 125.000 unites et coute 328.90euros # 1 tonner fait 125.000 unites et coute 328.90euros
c_coul = 0.78936 c_coul = 0.78936
@ -105,7 +105,7 @@ class impression:
c_agrafe = 4800. / 5000. / 3. c_agrafe = 4800. / 5000. / 3.
# Prix de la facture # Prix de la facture
# 2500 feuilles rouges à 40.07 euros (pour l'instant l'encre # 2500 feuilles rouges à 40.07 euros (pour l'instant l'encre
# de la facture est gracieusement offerte) # de la facture est gracieusement offerte)
# fact = 1.6028 # fact = 1.6028
fact = 0 fact = 0
@ -118,7 +118,7 @@ class impression:
## Pour le controle d'upload ## Pour le controle d'upload
class upload: class upload:
# liste des exemptations générales # liste des exemptations générales
exempt = [ ['138.231.136.0/21', '138.231.0.0/16'], exempt = [ ['138.231.136.0/21', '138.231.0.0/16'],
['138.231.148.0/22', '138.231.0.0/16'] ] ['138.231.148.0/22', '138.231.0.0/16'] ]
@ -128,11 +128,11 @@ class upload:
# limite hard # limite hard
hard = 700 hard = 700
# envoi des mails à disconnect@ # envoi des mails à disconnect@
disconnect_mail_soft = False disconnect_mail_soft = False
disconnect_mail_hard = True disconnect_mail_hard = True
# expéditeur des mails de déconnexion # expéditeur des mails de déconnexion
expediteur = "disconnect@crans.org" expediteur = "disconnect@crans.org"
# textes des mails # textes des mails
@ -143,33 +143,33 @@ Content-Type: text/plain; charset="iso-8859-15"
Bonjour %(proprio)s, Bonjour %(proprio)s,
Nous t'informons que ta (tes) machine(s) envoie(nt) une quantité Nous t'informons que ta (tes) machine(s) envoie(nt) une quantité
importante de données vers l'extérieur (%(upload)s Mo en 24 heures). importante de données vers l'extérieur (%(upload)s Mo en 24 heures).
*Ce message t'est envoyé à titre informatif, il ne te sanctionne pas.* *Ce message t'est envoyé à titre informatif, il ne te sanctionne pas.*
Il signifie que tu as envoyé plus de 100 Mo au cours des dernières 24 Il signifie que tu as envoyé plus de 100 Mo au cours des dernières 24
heures. Cela peut venir du fait que, *par exemple*, tu essaies heures. Cela peut venir du fait que, *par exemple*, tu essaies
d'envoyer des fichiers de grosse taille à l'extérieur de la zone d'envoyer des fichiers de grosse taille à l'extérieur de la zone
crans, ou encore que tu as fait une utilisation importante de crans, ou encore que tu as fait une utilisation importante de
logiciels envoyant une très grande quantité de petites données logiciels envoyant une très grande quantité de petites données
(vidéo-conférence par exemple). Il peut y avoir d'autres raisons. (vidéo-conférence par exemple). Il peut y avoir d'autres raisons.
Si cela continuait, et que tu dépassais la limite acceptable des 700 Si cela continuait, et que tu dépassais la limite acceptable des 700
Mo sur 24 heures, tu serais automatiquement déconnecté du réseau pour Mo sur 24 heures, tu serais automatiquement déconnecté du réseau pour
une durée de 24 heures. Il t'appartient donc de surveiller cela de une durée de 24 heures. Il t'appartient donc de surveiller cela de
plus près et de faire en sorte que tes machines n'uploadent pas de plus près et de faire en sorte que tes machines n'uploadent pas de
manière excessive à l'avenir. manière excessive à l'avenir.
Pour plus d'informations, tu peux consulter la page: Pour plus d'informations, tu peux consulter la page:
http://wiki.crans.org/VieCrans/DéconnexionPourUpload http://wiki.crans.org/VieCrans/DéconnexionPourUpload
Si tu as des questions, contacte disconnect@crans.org Si tu as des questions, contacte disconnect@crans.org
NB : L'upload consiste en l'envoi de données vers des machines n'étant NB : L'upload consiste en l'envoi de données vers des machines n'étant
pas branchées sur le CRANS. pas branchées sur le CRANS.
-- --
Disconnect team""" Disconnect team"""
@ -181,23 +181,23 @@ Content-Type: text/plain; charset="iso-8859-15"
Bonjour %(proprio)s, Bonjour %(proprio)s,
Tu as temporairement été déconnecté du réseau en raison de l'envoi Tu as temporairement été déconnecté du réseau en raison de l'envoi
trop important de données vers l'extérieur (%(upload)s Mo en 24h). trop important de données vers l'extérieur (%(upload)s Mo en 24h).
Tu as toujours accés au web ainsi qu'à tes mails crans mais tous les Tu as toujours accés au web ainsi qu'à tes mails crans mais tous les
autres services te sont suspendus. Si cela devait se renouveller trop autres services te sont suspendus. Si cela devait se renouveller trop
souvent, tu serais déconnecté complétement pour une durée plus souvent, tu serais déconnecté complétement pour une durée plus
importante. Il t'appartient donc de surveiller cela de plus près et de importante. Il t'appartient donc de surveiller cela de plus près et de
faire en sorte que ta machine n'uploade plus de manière excessive à faire en sorte que ta machine n'uploade plus de manière excessive à
l'avenir. l'avenir.
Pour plus d'informations, tu peux consulter la page : Pour plus d'informations, tu peux consulter la page :
http://wiki.crans.org/VieCrans/DéconnexionPourUpload http://wiki.crans.org/VieCrans/DéconnexionPourUpload
Si tu as des questions, contacte disconnect@crans.org Si tu as des questions, contacte disconnect@crans.org
NB: L'upload consiste en l'envoi de données vers des machines n'étant NB: L'upload consiste en l'envoi de données vers des machines n'étant
pas branchées sur le CRANS. pas branchées sur le CRANS.
-- --
Disconnect team""" Disconnect team"""
@ -211,17 +211,17 @@ Content-Type: text/plain; charset="iso-8859-15"
%(proprio)s uploade actuellement %(upload)s Mo. %(proprio)s uploade actuellement %(upload)s Mo.
-- --
Message créé par deconnexion.py""" Message créé par deconnexion.py"""
message_disconnect_hard = u"""From: %(from)s message_disconnect_hard = u"""From: %(from)s
To: %(to)s To: %(to)s
Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20d=E9connect=E9?= Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20d=E9connect=E9?=
Content-Type: text/plain; charset="iso-8859-15" Content-Type: text/plain; charset="iso-8859-15"
%(proprio)s a été déconnecté pour upload (%(upload)s Mo). %(proprio)s a été déconnecté pour upload (%(upload)s Mo).
-- --
Message créé par deconnexion.py""" Message créé par deconnexion.py"""
message_disconnect_multi = u"""From: %(from)s message_disconnect_multi = u"""From: %(from)s
To: %(to)s To: %(to)s
@ -229,13 +229,13 @@ Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20d=E9connect=E9?=
%(nbdeco)d fois pour upload en un mois ! %(nbdeco)d fois pour upload en un mois !
Content-Type: text/plain; charset="iso-8859-15" Content-Type: text/plain; charset="iso-8859-15"
L'adhérent %(proprio)s a été déconnecté %(nbdeco)d fois pour upload en un mois ! L'adhérent %(proprio)s a été déconnecté %(nbdeco)d fois pour upload en un mois !
Le PS a été généré et se trouve sur zamok : Le PS a été généré et se trouve sur zamok :
%(ps)s %(ps)s
-- --
Message créé par deconnexion.py""" Message créé par deconnexion.py"""
message_demenagement = u"""From: %(from)s message_demenagement = u"""From: %(from)s
@ -245,9 +245,9 @@ Content-Type: text/plain; charset="iso-8859-15"
Bonjour, Bonjour,
Il semble que tu étais inscrit dans la chambre %(chambre), mais un Il semble que tu étais inscrit dans la chambre %(chambre), mais un
autre adhérent s'y est inscrit, ce qui suppose que tu n'y es plus. autre adhérent s'y est inscrit, ce qui suppose que tu n'y es plus.
Pourrais tu nous préciser ta nouvelle chambre ou adresse stp ? Pourrais tu nous préciser ta nouvelle chambre ou adresse stp ?
Si tu es parti du campus, souhaites-tu garder tes machines ? Si tu es parti du campus, souhaites-tu garder tes machines ?
-- --
@ -255,7 +255,7 @@ Merci par avance,
Les membres actifs du Crans""" Les membres actifs du Crans"""
# Classe pour les paramètres du firewall # # Classe pour les paramètres du firewall #
########################################## ##########################################
class conf_fw: class conf_fw:
mark = { 'https-radin': '0x3', mark = { 'https-radin': '0x3',
@ -263,25 +263,25 @@ class conf_fw:
'proxy' : '0x2', 'proxy' : '0x2',
'bittorrent' : '0x1' } 'bittorrent' : '0x1' }
# Valeur du masque utilisé pour créer un arbre dans les filtres # Valeur du masque utilisé pour créer un arbre dans les filtres
mask = [24] mask = [24]
# Classe pour la détection des virus # # Classe pour la détection des virus #
###################################### ######################################
class virus: class virus:
# Nombre de Flood Par heure # Nombre de Flood Par heure
flood = 100 flood = 100
virus = 10 virus = 10
# Classe pour la détection du p2p # # Classe pour la détection du p2p #
################################### ###################################
class p2p : class p2p :
# Limite de débit pour l'ensemble du p2p classifié, en octets/s # Limite de débit pour l'ensemble du p2p classifié, en octets/s
# identique en upload et download # identique en upload et download
debit_max = 1000000 # = 1 Mb/s = 125 ko/s debit_max = 1000000 # = 1 Mb/s = 125 ko/s
debit_adh = 12000 # = 12 Kb/s = 1500 o/s (>= MTU [1500 bytes]) debit_adh = 12000 # = 12 Kb/s = 1500 o/s (>= MTU [1500 bytes])
# Limite de paquets acceptés par protocole P2P en deux heures # Limite de paquets acceptés par protocole P2P en deux heures
limite = {'Bittorrent': 20, limite = {'Bittorrent': 20,
'AppleJuice': 50, 'AppleJuice': 50,
'SoulSeek': 500, 'SoulSeek': 500,
@ -291,10 +291,10 @@ class p2p :
'KaZaa': 50, 'KaZaa': 50,
'Ares': 50, 'Ares': 50,
'GNUtella': 50 } 'GNUtella': 50 }
# Envoi des mails à disconnect@ # Envoi des mails à disconnect@
disconnect_mail = True disconnect_mail = True
# Expéditeur des mails de déconnexion # Expéditeur des mails de déconnexion
expediteur = "disconnect@crans.org" expediteur = "disconnect@crans.org"
avertissement = u"""From: %(From)s avertissement = u"""From: %(From)s
@ -302,35 +302,35 @@ To: %(To)s
Subject: =?iso-8859-1?Q?D=E9tection?= de p2p sur la machine %(hostname)s Subject: =?iso-8859-1?Q?D=E9tection?= de p2p sur la machine %(hostname)s
Content-Type: text/plain; charset="iso-8859-15" Content-Type: text/plain; charset="iso-8859-15"
La machine %(hostname)s a été déconnectée pendant 24h pour La machine %(hostname)s a été déconnectée pendant 24h pour
utilisation du protocole %(protocole)s. utilisation du protocole %(protocole)s.
Nombre de paquets : %(nb_paquets)s paquets depuis le %(datedebut)s. Nombre de paquets : %(nb_paquets)s paquets depuis le %(datedebut)s.
-- --
Message créé par deconnexion.py""" Message créé par deconnexion.py"""
deconnexion = u"""From: %(From)s deconnexion = u"""From: %(From)s
To: %(To)s To: %(To)s
Subject: Avis de =?iso-8859-15?Q?D=E9connexion?= Subject: Avis de =?iso-8859-15?Q?D=E9connexion?=
Content-Type: text/plain; charset="iso-8859-15" Content-Type: text/plain; charset="iso-8859-15"
Bonjour, Bonjour,
Nous avons détecté que ta machine, %(hostname)s utilisait le Nous avons détecté que ta machine, %(hostname)s utilisait le
*protocole* %(protocole)s. *protocole* %(protocole)s.
Cela signifie : Cela signifie :
- Ou bien que tu utilises le logiciel qui a le même nom - Ou bien que tu utilises le logiciel qui a le même nom
que ce protocole, que ce protocole,
- Ou bien que tu utilises un logiciel qui utilise le - Ou bien que tu utilises un logiciel qui utilise le
protocole en question pour partager des fichiers. protocole en question pour partager des fichiers.
Or l'usage de *protocoles* de type peer to peer est interdit Or l'usage de *protocoles* de type peer to peer est interdit
sur notre réseau, conformément aux documents que tu as acceptés sur notre réseau, conformément aux documents que tu as acceptés
en adhérant au CR@NS. en adhérant au CR@NS.
Lorsqu'un seul des adhérents du CR@NS utilise des protocoles interdits, Lorsqu'un seul des adhérents du CR@NS utilise des protocoles interdits,
il pénalise l'ensemble des adhérents de l'association. il pénalise l'ensemble des adhérents de l'association.
Tu seras donc déconnecté 24h. Tu seras donc déconnecté 24h.
-- --
Disconnect Team""" Disconnect Team"""
@ -340,29 +340,29 @@ To: %(to)s
Subject: %(proprio)s a =?iso-8859-15?Q?=E9t=E9=20d=E9connect=E9?= %(nbdeco)d fois pour p2p en un an ! Subject: %(proprio)s a =?iso-8859-15?Q?=E9t=E9=20d=E9connect=E9?= %(nbdeco)d fois pour p2p en un an !
Content-Type: text/plain; charset="iso-8859-15" Content-Type: text/plain; charset="iso-8859-15"
L'adhérent %(proprio)s a été déconnecté %(nbdeco)d fois pour p2p en un an ! L'adhérent %(proprio)s a été déconnecté %(nbdeco)d fois pour p2p en un an !
Le PS a été généré et se trouve sur zamok : Le PS a été généré et se trouve sur zamok :
%(ps)s %(ps)s
-- --
Message créé par deconnexion.py""" Message créé par deconnexion.py"""
############################# #############################
## Paramètres des machines ## ## Paramètres des machines ##
############################# #############################
## >>>>>>>>>>>>>>> La modification des paramètres suivants doit se ## >>>>>>>>>>>>>>> La modification des paramètres suivants doit se
## >> ATTENTION >> faire avec précaution, il faut mettre la base à ## >> ATTENTION >> faire avec précaution, il faut mettre la base à
## >>>>>>>>>>>>>>> jour en parralèle de ces modifs. ## >>>>>>>>>>>>>>> jour en parralèle de ces modifs.
# Sous réseaux alloués à chaque type de machine ou bâtiment # Sous réseaux alloués à chaque type de machine ou bâtiment
# Pour la zone wifi, il faut penser à modifier le /etc/network/interfaces # Pour la zone wifi, il faut penser à modifier le /etc/network/interfaces
# de sable, zamok et komaz pour ajouter les zones en plus (et de # de sable, zamok et komaz pour ajouter les zones en plus (et de
# faire en sorte qu'ils prennent effet immédiatement ; c'est important pour # faire en sorte qu'ils prennent effet immédiatement ; c'est important pour
# komaz car c'est la route par défaut mais aussi pour zamok et sable # komaz car c'est la route par défaut mais aussi pour zamok et sable
# à cause de leur firewall et de leur patte wifi. # à cause de leur firewall et de leur patte wifi.
NETs = { 'serveurs' : [ '138.231.136.0/28' ], NETs = { 'serveurs' : [ '138.231.136.0/28' ],
'adherents' : [ '138.231.137.0/24', 'adherents' : [ '138.231.137.0/24',
'138.231.138.0/24', '138.231.138.0/24',
@ -381,7 +381,7 @@ NETs = { 'serveurs' : [ '138.231.136.0/28' ],
NETs_regexp = { 'all' : '^138\.231\.1(3[6789]|4[0123456789]|5[01])\.\d+$' } NETs_regexp = { 'all' : '^138\.231\.1(3[6789]|4[0123456789]|5[01])\.\d+$' }
# Domaines dans lesquels les machines sont placées suivant leur type # Domaines dans lesquels les machines sont placées suivant leur type
domains = { 'machineFixe': 'crans.org', domains = { 'machineFixe': 'crans.org',
'machineCrans': 'crans.org', 'machineCrans': 'crans.org',
'machineWifi': 'wifi.crans.org', 'machineWifi': 'wifi.crans.org',
@ -420,24 +420,24 @@ To: %(To)s
Subject: [CRANS] Bienvenue au Cr@ns ! Subject: [CRANS] Bienvenue au Cr@ns !
Content-Type: text/plain; charset="iso-8859-15" Content-Type: text/plain; charset="iso-8859-15"
Si tu lis ce mail, c'est que ton inscription à l'association est effective ! Si tu lis ce mail, c'est que ton inscription à l'association est effective !
Rappel : Le site web de l'association est http://www.crans.org. Rappel : Le site web de l'association est http://www.crans.org.
Par ailleurs, toutes les informations concernant l'association sont Par ailleurs, toutes les informations concernant l'association sont
disponibles sur le WIKI à l'adresse http://wiki.crans.org disponibles sur le WIKI à l'adresse http://wiki.crans.org
Notamment, il est important de prendre le temps de lire la page : Notamment, il est important de prendre le temps de lire la page :
http://wiki.crans.org/CransPratique http://wiki.crans.org/CransPratique
Elle regroupe toutes les informations nécessaires à l'utilisation des Elle regroupe toutes les informations nécessaires à l'utilisation des
ressources de l'association. ressources de l'association.
Sans lire attentivement ce document, l'accès au Web peut ne pas Sans lire attentivement ce document, l'accès au Web peut ne pas
fonctionner. fonctionner.
----- -----
L'accés aux news et au wiki sont limités à un usage interne au CRANS. L'accés aux news et au wiki sont limités à un usage interne au CRANS.
Pour y avoir accés depuis l'extérieur il faut utiliser un mot de passe: Pour y avoir accés depuis l'extérieur il faut utiliser un mot de passe:
- Pour les news : - Pour les news :
* Utilisateur : Vivelapa * Utilisateur : Vivelapa
* Mot de passe : ranoia! * Mot de passe : ranoia!
@ -448,7 +448,7 @@ Pour y avoir acc
Sur ce, bienvenue au Cr@ns ! Sur ce, bienvenue au Cr@ns !
PS: Il t'est conseillé de conserver ce mail à toutes fin utiles PS: Il t'est conseillé de conserver ce mail à toutes fin utiles
-- --
Les membres actifs.""" Les membres actifs."""
@ -460,14 +460,14 @@ Content-Type: text/plain; charset="iso-8859-15"
Bonjour, Bonjour,
Tu viens d'être doté des droits %(Droit)s au Cr@ns. Tu viens d'être doté des droits %(Droit)s au Cr@ns.
Une description de ces droits et de la manière Une description de ces droits et de la manière
de les utiliser est disponible sur la page : de les utiliser est disponible sur la page :
%(Page)s %(Page)s
Si tu as des questions, n'hésite pas à les poser Si tu as des questions, n'hésite pas à les poser
à d'autres câbleurs ou aux nounous. à d'autres câbleurs ou aux nounous.
-- --
Les nounous""" Les nounous"""
@ -487,10 +487,10 @@ Content-Type: text/plain; charset="iso-8859-1"
Bonjour, Bonjour,
Il semble que tu es membre actif du CRANS et que tu n'as pas Il semble que tu es membre actif du CRANS et que tu n'as pas
signé la charte des membres actifs. Si tu n'es pas membre actif signé la charte des membres actifs. Si tu n'es pas membre actif
ou si tu as signé la charte des membres actifs, merci de nous le ou si tu as signé la charte des membres actifs, merci de nous le
signaler. Sinon, il faudrait signer la charte et nous la rendre signaler. Sinon, il faudrait signer la charte et nous la rendre
rapidement. Tu peux l'imprimer à partir du fichier suivant : rapidement. Tu peux l'imprimer à partir du fichier suivant :
https://wiki.crans.org/CransAdministratif?action=AttachFile&do=get&target=charte_ma.pdf https://wiki.crans.org/CransAdministratif?action=AttachFile&do=get&target=charte_ma.pdf
@ -506,11 +506,11 @@ Content-Type: text/plain; charset="iso-8859-1"
Bonjour, Bonjour,
Les droits que tu avais sur ton compte CRANS ont été retirés Les droits que tu avais sur ton compte CRANS ont été retirés
car tu ne cotises pas cette année et que tes droits ne semblent car tu ne cotises pas cette année et que tes droits ne semblent
pas être utiles pour une utilisation à distance. Si nous avons pas être utiles pour une utilisation à distance. Si nous avons
commis une erreur, nous te prions de nous en excuser. Si tu commis une erreur, nous te prions de nous en excuser. Si tu
souhaites par la suite retrouver des droits, nous serons bien sûr souhaites par la suite retrouver des droits, nous serons bien sûr
heureux de te les remettre. heureux de te les remettre.
Cordialement, Cordialement,

View file

@ -1,12 +1,12 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso8859-15 -*- # -*- coding: utf-8 -*-
############################################################################### ###############################################################################
# config_mail : gestion du .forward et .procmailrc des adhérents # config_mail : gestion du .forward et .procmailrc des adhérents
############################################################################### ###############################################################################
# The authors of this code are # The authors of this code are
# Etienne Chové <etienne.chove@crans.org> # Etienne Chové <etienne.chove@crans.org>
# #
# Copyright (C) 2006 Etienne Chové # Copyright (C) 2006 Etienne Chové
# All rights reserved. # All rights reserved.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -28,7 +28,7 @@
## Chaines de formatage pour le procmailrc ## Chaines de formatage pour le procmailrc
""" """
Script permetant de gérer sa configuration mail Script permetant de gérer sa configuration mail
Usage : ConfigMail.py [--forward=(|<mail>)] [--spam=(accepte|marque|supprime)] Usage : ConfigMail.py [--forward=(|<mail>)] [--spam=(accepte|marque|supprime)]
Retourne : Retourne :
@ -37,7 +37,7 @@ Retourne :
""" """
procmail_warning = """################################################################ procmail_warning = """################################################################
# Ce fichier de configuration a été automatiquement généré par # # Ce fichier de configuration a été automatiquement généré par #
# l'intranet. # # l'intranet. #
# # # #
# ATTENTION : ne le modifiez que si vous savez ce que vous # # ATTENTION : ne le modifiez que si vous savez ce que vous #
@ -51,7 +51,7 @@ procmail_mark = """# Passage des mails dans spamassassin
* < 256000 * < 256000
| spamc | spamc
# Serveur blacklisté # Serveur blacklisté
:0 :0
* ^X-Reject: 554 * ^X-Reject: 554
* !^X-Spam-Status: Yes * !^X-Spam-Status: Yes
@ -100,7 +100,7 @@ def _IsMail(mail):
def _Clean(texte): def _Clean(texte):
""" """
Nettoie une chaine de caractère/liste en supprimant les lignes vides/commentés, Nettoie une chaine de caractère/liste en supprimant les lignes vides/commentés,
et retourne une liste et retourne une liste
""" """
if type(texte) != list: if type(texte) != list:
@ -126,7 +126,7 @@ def _GetConfig():
# utilisation de procmail # utilisation de procmail
if fic_forward != _Clean(forward_procmail)[0]: if fic_forward != _Clean(forward_procmail)[0]:
raise MailConfigError, 'Fichier forward non compréhensible' raise MailConfigError, 'Fichier forward non compréhensible'
## lecture du .procmailrc ## lecture du .procmailrc
fic_procmail = _Clean( open('%s/.procmailrc'%home).readlines() ) fic_procmail = _Clean( open('%s/.procmailrc'%home).readlines() )
@ -145,7 +145,7 @@ def _GetConfig():
# marquage des spams # marquage des spams
tmp = _Clean( procmail_mark ) tmp = _Clean( procmail_mark )
if fic_procmail[:len(tmp)] != tmp: if fic_procmail[:len(tmp)] != tmp:
raise MailConfigError, 'Fichier de procmail non compréhensible' raise MailConfigError, 'Fichier de procmail non compréhensible'
fic_procmail = fic_procmail[len(tmp):] fic_procmail = fic_procmail[len(tmp):]
# suppression des spams ? # suppression des spams ?
@ -154,7 +154,7 @@ def _GetConfig():
elif fic_procmail == _Clean(procmail_delete_spam): elif fic_procmail == _Clean(procmail_delete_spam):
return {'forward':forward, 'spam':'supprime'} return {'forward':forward, 'spam':'supprime'}
else: else:
raise MailConfigError, 'Fichier de procmail non compréhensible' raise MailConfigError, 'Fichier de procmail non compréhensible'
def _SetConfig(forward = None, spam= None): def _SetConfig(forward = None, spam= None):
""" Modifie la configuration de l'utilisateur courant """ """ Modifie la configuration de l'utilisateur courant """
@ -165,7 +165,7 @@ def _SetConfig(forward = None, spam= None):
elif spam == None: elif spam == None:
new_spam = _GetConfig()['spam'] new_spam = _GetConfig()['spam']
else: else:
raise ValueError, 'Valeur interdite pour le paramètre spam' raise ValueError, 'Valeur interdite pour le paramètre spam'
# variable forward # variable forward
if forward == None: if forward == None:
@ -175,7 +175,7 @@ def _SetConfig(forward = None, spam= None):
else: else:
raise ValueError, 'Adresse mail invalide' raise ValueError, 'Adresse mail invalide'
# génération des fichiers # génération des fichiers
if new_spam=='accepte': if new_spam=='accepte':
# suppression du .procmailrc # suppression du .procmailrc
try: try:
@ -188,14 +188,14 @@ def _SetConfig(forward = None, spam= None):
else: else:
os.remove('%s/.forward'%home) os.remove('%s/.forward'%home)
else: else:
# écriture du .procmailc # écriture du .procmailc
txt = procmail_warning + procmail_mark txt = procmail_warning + procmail_mark
if new_spam=='supprime': if new_spam=='supprime':
txt += procmail_delete_spam txt += procmail_delete_spam
if new_forward: if new_forward:
txt += procmail_forward % new_forward txt += procmail_forward % new_forward
open('%s/.procmailrc'%home,'w').write(txt) open('%s/.procmailrc'%home,'w').write(txt)
# écriture du .forward # écriture du .forward
open('%s/.forward'%home,'w').write(forward_procmail) open('%s/.forward'%home,'w').write(forward_procmail)
def _Sudo(uid, forward=None, spam=None): def _Sudo(uid, forward=None, spam=None):
@ -234,9 +234,9 @@ def _Sudo(uid, forward=None, spam=None):
def MailConfig(uid=None, forward=None, spam=None): def MailConfig(uid=None, forward=None, spam=None):
""" Modifie ou retourne la configuration mail de l'utilisateur """ Modifie ou retourne la configuration mail de l'utilisateur
user = utilisateur à configurer, si None configure l'utilisateur courant user = utilisateur à configurer, si None configure l'utilisateur courant
forward = adresse vers laquelle rediriger les mails, chaine vide si pas de redirection forward = adresse vers laquelle rediriger les mails, chaine vide si pas de redirection
spam = action à effectuer sur les spams (accepte, supprime, marque) spam = action à effectuer sur les spams (accepte, supprime, marque)
Pour les champs forward et spam, la valeur None ne touche pas au champ. Pour les champs forward et spam, la valeur None ne touche pas au champ.
@ -275,7 +275,7 @@ if __name__=="__main__":
## execution de MailConfig ## execution de MailConfig
res = MailConfig(forward=forward, spam=spam) res = MailConfig(forward=forward, spam=spam)
## affichage des résultats ## affichage des résultats
for i in res.items(): for i in res.items():
print "%s=%s" % i print "%s=%s" % i

View file

@ -1,14 +1,14 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
# Copyright (C) Stéphane Glondu + ??? # Copyright (C) Stéphane Glondu + ???
# Licence : ??? # Licence : ???
""" """
Envoi de mails textes encodés et bien formatés (encodages spécifiés il faut). Envoi de mails textes encodés et bien formatés (encodages spécifiés il faut).
Autres outils relatifs aux mails. Autres outils relatifs aux mails.
format_sender et send_email adaptés depuis /usr/scripts/impression/crans_backend.py. format_sender et send_email adaptés depuis /usr/scripts/impression/crans_backend.py.
""" """
import re import re
@ -103,12 +103,12 @@ def send_email(sender, recipient, subject, body, server='localhost', cc=None, de
def parse_mail_template(fichier): def parse_mail_template(fichier):
""" """
Lit fichier et renvoie le couple sujet, corps en unicode. Lit fichier et renvoie le couple sujet, corps en unicode.
Les trois premières lignes de fichier doivent être : Les trois premières lignes de fichier doivent être :
Encoding: <encodage du fichier> Encoding: <encodage du fichier>
Subject: <sujet du mail> Subject: <sujet du mail>
<ligne vide> <ligne vide>
Le reste forme le corps du mail. Le reste forme le corps du mail.
L'argument fichier peut être un nom de fichier, ou directement une L'argument fichier peut être un nom de fichier, ou directement une
instance de file. instance de file.
""" """
if not isinstance(fichier, file): if not isinstance(fichier, file):

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" """
Fichier de base d'interface avec les switchs manageables. Fichier de base d'interface avec les switchs manageables.
Donne la classe switch qui permet d'effectuer les opérations Donne la classe switch qui permet d'effectuer les opérations
élémentaires sur les switchs manageable HP 26xx. élémentaires sur les switchs manageable HP 26xx.
Frédéric PAUGET Frédéric PAUGET
""" """
from time import sleep from time import sleep
from popen2 import popen3 from popen2 import popen3
@ -28,13 +28,13 @@ try:
from secrets import config_snmp_secrete, reconf_snmp from secrets import config_snmp_secrete, reconf_snmp
except: except:
# Si a pas le droit de lire config_snmp_secrete # Si a pas le droit de lire config_snmp_secrete
# on va tenter de tout faire en snmpv1 et communauté public # on va tenter de tout faire en snmpv1 et communauté public
def config_snmp_secrete(snmp,switch) : def config_snmp_secrete(snmp,switch) :
snmp = snmp(switch,version='1',community='public') snmp = snmp(switch,version='1',community='public')
return snmp.get, snmp.set, snmp.walk return snmp.get, snmp.set, snmp.walk
############################################################################################# #############################################################################################
### Définitions de classes utiles ### Définitions de classes utiles
# Quelques exceptions # Quelques exceptions
class ConnectionTimout(Exception) : class ConnectionTimout(Exception) :
@ -50,7 +50,7 @@ class ConversationError(Exception) :
import pexpect import pexpect
class ssh : class ssh :
""" Ouverture d'une connexion ssh, envoi de commandes et récupération du résultat """ """ Ouverture d'une connexion ssh, envoi de commandes et récupération du résultat """
def __init__(self,host) : def __init__(self,host) :
@ -77,13 +77,13 @@ class ssh :
self.ssh.close() self.ssh.close()
def send_cmd(self,cmd,timeout=15): def send_cmd(self,cmd,timeout=15):
""" Envoi une commande, attend le prompt et retourne la réponse """ """ Envoi une commande, attend le prompt et retourne la réponse """
# Envoi de la commande # Envoi de la commande
self.ssh.sendline(cmd) self.ssh.sendline(cmd)
self.__sshout = '' self.__sshout = ''
try: try:
# Attente de la réponse # Attente de la réponse
while 1: while 1:
index = self.ssh.expect([' \[y/n\]\? ', index = self.ssh.expect([' \[y/n\]\? ',
'%s\(config\)# ' % self.switch, '%s\(config\)# ' % self.switch,
@ -92,7 +92,7 @@ class ssh :
self.__sshout = self.__sshout + self.ssh.before self.__sshout = self.__sshout + self.ssh.before
if index == 0: if index == 0:
# On répond oui # On répond oui
self.ssh.send("y") self.ssh.send("y")
elif index == 1: elif index == 1:
# On est revenu au prompt # On est revenu au prompt
@ -112,13 +112,13 @@ class ssh :
class snmp : class snmp :
""" Classe de communication SNMP """ """ Classe de communication SNMP """
def __init__(self,host,version=None,community=None,authentication_protocol=None, authentication_pass=None, username=None, privacy_pass=None) : def __init__(self,host,version=None,community=None,authentication_protocol=None, authentication_pass=None, username=None, privacy_pass=None) :
""" host doit être la machine sur laquelle se connecter """ host doit être la machine sur laquelle se connecter
version est la verion du protocole snmp à utiliser : 1, 2c ou 3 version est la verion du protocole snmp à utiliser : 1, 2c ou 3
le reste des données doit être ou non fourni suivant la version le reste des données doit être ou non fourni suivant la version
pour v1 et v2c seule la communauté est prise en compte pour v1 et v2c seule la communauté est prise en compte
pour v3 authentication_protocol, authentication_pass et username sont requis si accès en authNoPriv pour v3 authentication_protocol, authentication_pass et username sont requis si accès en authNoPriv
si privacy_pass est fourni accès en authPriv si privacy_pass est fourni accès en authPriv
""" """
self.host = host self.host = host
self.version = version self.version = version
@ -150,11 +150,11 @@ class snmp :
return r return r
def get(self,oid) : def get(self,oid) :
""" Retourne le résultat correspondant à l'oid demandé """ """ Retourne le résultat correspondant à l'oid demandé """
return self.__exec('snmpget -O vq %s %s ' % ( self.options, oid ) ) return self.__exec('snmpget -O vq %s %s ' % ( self.options, oid ) )
def get_string(self,oid) : def get_string(self,oid) :
""" Retourne le resultat convertit en String correspondant à l'oid demandé. Fonctionne avec les types de depart String, Integer, Hex-String. Raise ValueError sinon. """ """ Retourne le resultat convertit en String correspondant à l'oid demandé. Fonctionne avec les types de depart String, Integer, Hex-String. Raise ValueError sinon. """
s= self.__exec('snmpget -O v %s %s ' % ( self.options, oid ) ) s= self.__exec('snmpget -O v %s %s ' % ( self.options, oid ) )
if s=="\"\"": if s=="\"\"":
return "" return ""
@ -170,14 +170,14 @@ class snmp :
raise ValueError('Type inconnu') raise ValueError('Type inconnu')
def set(self,oid,typ,val) : def set(self,oid,typ,val) :
""" Change la valeur le l'oid donné. """ Change la valeur le l'oid donné.
type est le type de la valeur type est le type de la valeur
val est la valeur à écrire val est la valeur à écrire
""" """
return self.__exec('snmpset -O vq %s %s %s %s' % (self.options, oid, typ, val ) ) return self.__exec('snmpset -O vq %s %s %s %s' % (self.options, oid, typ, val ) )
def walk(self,base_oid) : def walk(self,base_oid) :
""" Retourne le résultat de snmpwalk """ Retourne le résultat de snmpwalk
le retour est un dictionnaire { oid : valeur } le retour est un dictionnaire { oid : valeur }
""" """
lignes = self.__exec('snmpwalk -O q %s %s' % (self.options, base_oid ) ).split('\n') lignes = self.__exec('snmpwalk -O q %s %s' % (self.options, base_oid ) ).split('\n')
@ -204,7 +204,7 @@ class hpswitch :
__conn_ssh = None __conn_ssh = None
def __init__(self,switch) : def __init__(self,switch) :
""" Switch doit être le nom du switch """ """ Switch doit être le nom du switch """
if self.__debug : self.__logDest.write("HP DEBUG : __init__(switch=%s)\n" % switch ) if self.__debug : self.__logDest.write("HP DEBUG : __init__(switch=%s)\n" % switch )
self.switch = switch.lower() self.switch = switch.lower()
@ -219,20 +219,20 @@ class hpswitch :
return self.__conn_ssh.send_cmd(cmd,timout) return self.__conn_ssh.send_cmd(cmd,timout)
def show_prise_mac(self,prise='') : def show_prise_mac(self,prise='') :
""" Retourne le(s) adresse(s) MAC présentes sur la prise.""" """ Retourne le(s) adresse(s) MAC présentes sur la prise."""
if not prise : prise = self.prise if not prise : prise = self.prise
if self.__debug : self.__logDest.write("HP DEBUG : show_prise_mac(prise=%s)\n" % prise) if self.__debug : self.__logDest.write("HP DEBUG : show_prise_mac(prise=%s)\n" % prise)
try: try:
data = self.walk('STATISTICS-MIB::hpSwitchPortFdbAddress.%d' % int(prise)) data = self.walk('STATISTICS-MIB::hpSwitchPortFdbAddress.%d' % int(prise))
return map(lambda x:findall('".*"',":".join(x.lower().split(' ')))[0][1:-2],data.values()) return map(lambda x:findall('".*"',":".join(x.lower().split(' ')))[0][1:-2],data.values())
except ValueError: except ValueError:
# Pas de MAC trouvée # Pas de MAC trouvée
return [] return []
def where_is_mac(self, mac) : def where_is_mac(self, mac) :
"""Retrouve la prise correspondant à une adresse MAC donnée""" """Retrouve la prise correspondant à une adresse MAC donnée"""
if self.__debug : self.__logDest.write("HP DEBUG : where_is_mac(mac=%s)\n" % mac) if self.__debug : self.__logDest.write("HP DEBUG : where_is_mac(mac=%s)\n" % mac)
# On va transformer l'adresse MAC cherchée pour la mettre au format 0A 0A 0A 0A 0A 0A # On va transformer l'adresse MAC cherchée pour la mettre au format 0A 0A 0A 0A 0A 0A
mac = mac.upper() mac = mac.upper()
mac = filter(lambda x: x in "0123456789ABCDEF", mac) # 0A0A0A0A0A0A mac = filter(lambda x: x in "0123456789ABCDEF", mac) # 0A0A0A0A0A0A
mac = "%s %s %s %s %s %s" % (mac[0:2], mac[2:4], mac[4:6], mac = "%s %s %s %s %s %s" % (mac[0:2], mac[2:4], mac[4:6],
@ -246,7 +246,7 @@ class hpswitch :
if onemac[1:-2] == mac: if onemac[1:-2] == mac:
return int(onesnmp.split(".")[1]) return int(onesnmp.split(".")[1])
# On a rien trouvé # On a rien trouvé
return None return None
def __scp(self,destination,fichier) : def __scp(self,destination,fichier) :
@ -272,8 +272,8 @@ class hpswitch :
self.scp('ssh/mgr_keys',file) self.scp('ssh/mgr_keys',file)
def multicast(self,ip='') : def multicast(self,ip='') :
""" Donne la liste des ports du swich inscrits au flux multicast donné """ Donne la liste des ports du swich inscrits au flux multicast donné
Si aucun flux donné teste tous les flux multicast possibles. Si aucun flux donné teste tous les flux multicast possibles.
Retourne un dictionnaire : { adresse du flux : [ ports inscrits ] } Retourne un dictionnaire : { adresse du flux : [ ports inscrits ] }
""" """
@ -311,7 +311,7 @@ class hpswitch :
return self.set('IF-MIB::ifAdminStatus.%d' % int(prise), 'i', 1) return self.set('IF-MIB::ifAdminStatus.%d' % int(prise), 'i', 1)
def disable(self,prise=0) : def disable(self,prise=0) :
""" Désactive une prise """ """ Désactive une prise """
if not prise : prise = self.prise if not prise : prise = self.prise
if self.__debug : self.__logDest.write("HP DEBUG : disable(prise=%s)\n" % prise) if self.__debug : self.__logDest.write("HP DEBUG : disable(prise=%s)\n" % prise)
return self.set('IF-MIB::ifAdminStatus.%d' % int(prise), 'i', 2) return self.set('IF-MIB::ifAdminStatus.%d' % int(prise), 'i', 2)
@ -323,15 +323,15 @@ class hpswitch :
nb = 0 nb = 0
for oid,etat in self.walk(oid).items() : for oid,etat in self.walk(oid).items() :
if etat == 'up' and int(oid.split('.')[1])<51 : if etat == 'up' and int(oid.split('.')[1])<51 :
# Le <51 est ici pour éviter de compter les ports fictifs # Le <51 est ici pour éviter de compter les ports fictifs
nb += 1 nb += 1
return nb return nb
prise = prise.replace('-','') prise = prise.replace('-','')
return self.get(oid + '.' + prise) == 'up' return self.get(oid + '.' + prise) == 'up'
def is_enable(self,prise=0) : def is_enable(self,prise=0) :
""" Retoune True ou False suivant si la prise est activée ou non """ Retoune True ou False suivant si la prise est activée ou non
Si prise=all retourne le nombre de prises activées sur le switch """ Si prise=all retourne le nombre de prises activées sur le switch """
if prise != 'all': prise = int(prise) if prise != 'all': prise = int(prise)
return self.__is('IF-MIB::ifAdminStatus',prise) return self.__is('IF-MIB::ifAdminStatus',prise)
@ -342,7 +342,7 @@ class hpswitch :
return self.__is('IF-MIB::ifOperStatus',prise) return self.__is('IF-MIB::ifOperStatus',prise)
def nom(self,nom=None,prise=0) : def nom(self,nom=None,prise=0) :
""" Retourne ou attribue le nom à la prise fournie """ """ Retourne ou attribue le nom à la prise fournie """
if not prise : prise = self.prise if not prise : prise = self.prise
oid = 'IF-MIB::ifAlias.%d' % int(prise) oid = 'IF-MIB::ifAlias.%d' % int(prise)
if nom==None : if nom==None :
@ -377,7 +377,7 @@ class hpswitch :
self.set(oid,'i',code) self.set(oid,'i',code)
def vlans(self, prise = None): def vlans(self, prise = None):
"""Récupère les vlans activés sur la prise 'prise'""" """Récupère les vlans activés sur la prise 'prise'"""
if not prise: if not prise:
prise = self.prise prise = self.prise
prise = int(prise) prise = int(prise)
@ -461,7 +461,7 @@ if __name__ == '__main__' :
for opt, val in options : for opt, val in options :
if opt == '-h' or opt=='--help' : if opt == '-h' or opt=='--help' :
print "Usage : %s [[-c commande1] -c commande2...] [-U firmware] [--snmp] regex " print "Usage : %s [[-c commande1] -c commande2...] [-U firmware] [--snmp] regex "
print "Envoi les commandes données au switchs matchant la regex" print "Envoi les commandes données au switchs matchant la regex"
print "si aucune commande est founie lit l'entree standart" print "si aucune commande est founie lit l'entree standart"
print "L'envoi de firmware ne fait pas rebooter le switch" print "L'envoi de firmware ne fait pas rebooter le switch"
print "L'option --snmp ajoute les commandes de reconfiguration snmp" print "L'option --snmp ajoute les commandes de reconfiguration snmp"
@ -486,7 +486,7 @@ if __name__ == '__main__' :
switchs.append(sw) switchs.append(sw)
if not switchs : if not switchs :
print "Aucun switch trouvé" print "Aucun switch trouvé"
print "Note : il faut une _regex_ (!= wilcards au sens du shell)" print "Note : il faut une _regex_ (!= wilcards au sens du shell)"
sys.exit(3) sys.exit(3)
@ -499,7 +499,7 @@ if __name__ == '__main__' :
print print
try: try:
raw_input("Appuyer sur entrée pour continuer") raw_input("Appuyer sur entrée pour continuer")
except EOFError: except EOFError:
# On lisait depuis un pipe # On lisait depuis un pipe
print '\r'+' '*33+'\r' print '\r'+' '*33+'\r'
@ -507,7 +507,7 @@ if __name__ == '__main__' :
for sw in switchs : for sw in switchs :
print sw print sw
try: try:
# Au cas ou le switch ne répondrai pas # Au cas ou le switch ne répondrai pas
s = hpswitch(sw) s = hpswitch(sw)
if firmware : if firmware :
s.upgrade(firmware) s.upgrade(firmware)

View file

@ -1,21 +1,21 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" """
Manipulation d'IPv4 Manipulation d'IPv4
Copyright (C) Frédéric Pauget Copyright (C) Frédéric Pauget
Licence : GPLv2 Licence : GPLv2
""" """
import re import re
from config import NETs_regexp from config import NETs_regexp
# Pour accélérer QuadToDec... # Pour accélérer QuadToDec...
__QuadToDecDone = {} __QuadToDecDone = {}
def QuadToDec(ip) : def QuadToDec(ip) :
""" """
Retourne la représentation décimale d'une ip Retourne la représentation décimale d'une ip
ip est de la forme xxx.xxx.xxx.xxx ip est de la forme xxx.xxx.xxx.xxx
""" """
if ip in __QuadToDecDone: if ip in __QuadToDecDone:
@ -31,12 +31,12 @@ def QuadToDec(ip) :
__QuadToDecDone[ip] = ip_dec __QuadToDecDone[ip] = ip_dec
return ip_dec return ip_dec
# Pour accélérer DecToQuad # Pour accélérer DecToQuad
__DecToQuadDone = {} __DecToQuadDone = {}
def DecToQuad(ip_dec) : def DecToQuad(ip_dec) :
""" """
Retourne la représentation habituelle d'une ip (xxx.xxx.xxx.xxx) Retourne la représentation habituelle d'une ip (xxx.xxx.xxx.xxx)
ip_dec est l'IP en base 10 ip_dec est l'IP en base 10
""" """
if ip_dec in __DecToQuadDone: if ip_dec in __DecToQuadDone:
@ -56,14 +56,14 @@ __paramDone = {}
def param(net, raw=False) : def param(net, raw=False) :
""" """
net est un résau fourni sous la forme xxx.xxx.xxx.xxx/yy net est un résau fourni sous la forme xxx.xxx.xxx.xxx/yy
si donnée valide retourne un dictionnaire : si donnée valide retourne un dictionnaire :
{ 'network' : xxx.xxx.xxx.xxx , { 'network' : xxx.xxx.xxx.xxx ,
'netmask' : yyy.yyy.yyy.yyy , 'netmask' : yyy.yyy.yyy.yyy ,
'broadcast' : zzz.zzz.zzz.zzz } 'broadcast' : zzz.zzz.zzz.zzz }
sinon retourne {} sinon retourne {}
Si raw = False, alors, on ne convertit pas les résultats sous forme pointée. Si raw = False, alors, on ne convertit pas les résultats sous forme pointée.
Ils restent sous forme d'un entier. Ils restent sous forme d'un entier.
""" """
if raw and net in __paramDone: if raw and net in __paramDone:
@ -96,9 +96,9 @@ def AddrInNet(ip,net) :
""" """
ip est de la forme xxx.xxx.xxx.xxx ip est de la forme xxx.xxx.xxx.xxx
net est de la forme xxx.xxx.xxx.xxx/yy net est de la forme xxx.xxx.xxx.xxx/yy
net peut être une liste de chaînes ci-dessus net peut être une liste de chaînes ci-dessus
Retourne True si l'ip est dans un des réseaux. Retourne True si l'ip est dans un des réseaux.
Note : retourne False si l'IP est une adresse de réseau ou broadcast Note : retourne False si l'IP est une adresse de réseau ou broadcast
""" """
if type(net)==str : net = [ net ] if type(net)==str : net = [ net ]
@ -113,7 +113,7 @@ def AddrInNet(ip,net) :
return r return r
def AddrInNets(ip,nets) : def AddrInNets(ip,nets) :
""" Vérifie si l'ip est au moins dans un des réseaux """ Vérifie si l'ip est au moins dans un des réseaux
de la liste nets (voir AddrInNet) """ de la liste nets (voir AddrInNet) """
for net in nets : for net in nets :
if AddrInNet(ip,net) : if AddrInNet(ip,net) :
@ -121,7 +121,7 @@ def AddrInNets(ip,nets) :
return False return False
def is_crans(ip): def is_crans(ip):
""" Vérifie que l'ip est dans le réseau CRANS """ Vérifie que l'ip est dans le réseau CRANS
""" """
# Pour prove le temps du point rencontre # Pour prove le temps du point rencontre
if ip == '138.231.136.19' : if ip == '138.231.136.19' :
@ -131,7 +131,7 @@ def is_crans(ip):
return False return False
def netmask(mask, dec=True) : def netmask(mask, dec=True) :
""" On génère le sous réseau /bits """ On génère le sous réseau /bits
""" """
non_dec_netmask = (1L<<(32-mask)) - 1 non_dec_netmask = (1L<<(32-mask)) - 1
dec_netmask = (1L<<32) - 1 - non_dec_netmask dec_netmask = (1L<<32) - 1 - non_dec_netmask
@ -148,25 +148,25 @@ def IpSubnet(ip, mask) :
return subnet return subnet
def NetSubnets(net, subnet_mask) : def NetSubnets(net, subnet_mask) :
""" On construit une liste des sous réseaux /subnet_mask """ On construit une liste des sous réseaux /subnet_mask
compris dans le sous réseau /mask comprenant l'ip ip compris dans le sous réseau /mask comprenant l'ip ip
""" """
subnets = [] subnets = []
# On récupère une ip du réseau indiqué # On récupère une ip du réseau indiqué
ip = net.split('/')[0] ip = net.split('/')[0]
# On récupère la valeur du masque # On récupère la valeur du masque
mask = int(net.split('/')[1]) mask = int(net.split('/')[1])
# On transforme les valeurs d'entrées en valeurs décimales # On transforme les valeurs d'entrées en valeurs décimales
# On définit la valeur du sous réseau initial # On définit la valeur du sous réseau initial
dec_netmask = netmask(mask) dec_netmask = netmask(mask)
dec_ip = QuadToDec(ip) dec_ip = QuadToDec(ip)
dec_subnet_netmask = netmask(subnet_mask) dec_subnet_netmask = netmask(subnet_mask)
# On calcule la première ip du sous réseau indiqué # On calcule la première ip du sous réseau indiqué
start_ip = dec_ip & dec_netmask start_ip = dec_ip & dec_netmask
seq_ip = start_ip seq_ip = start_ip
# On fait une itération sur toutes les ip du sous réseau # On fait une itération sur toutes les ip du sous réseau
while (seq_ip & dec_netmask) == start_ip: while (seq_ip & dec_netmask) == start_ip:
# On récupère le sous réseau de la taille demandée # On récupère le sous réseau de la taille demandée
subnet = DecToQuad(seq_ip & dec_subnet_netmask) + "/%s" % subnet_mask subnet = DecToQuad(seq_ip & dec_subnet_netmask) + "/%s" % subnet_mask
if not subnets.count(subnet) : if not subnets.count(subnet) :
subnets.append(subnet) subnets.append(subnet)

File diff suppressed because it is too large Load diff

View file

@ -1,14 +1,14 @@
# -*- coding: iso8859-15 -*- # -*- coding: utf-8 -*-
############################################################################### ###############################################################################
# ldap_passwd.py : manipulation des mots de passes LDAP # ldap_passwd.py : manipulation des mots de passes LDAP
# $Id: ldap_passwd.py,v 1.7 2006-05-04 17:46:58 chove Exp $ # $Id: ldap_passwd.py,v 1.7 2006-05-04 17:46:58 chove Exp $
############################################################################### ###############################################################################
# The authors of this code are # The authors of this code are
# Bjorn Ove Grotan <bgrotan@grotan.com> # Bjorn Ove Grotan <bgrotan@grotan.com>
# Etienne Chové <etienne.chove@crans.org> # Etienne Chové <etienne.chove@crans.org>
# #
# Copyright (C) 2005 Bjorn Ove Grotan # Copyright (C) 2005 Bjorn Ove Grotan
# Copyright (C) 2006 Etienne Chové # Copyright (C) 2006 Etienne Chové
# All rights reserved. # All rights reserved.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify

View file

@ -1,9 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" Gestion de lock """ Gestion de lock
Copyright (C) Frédéric Pauget Copyright (C) Frédéric Pauget
Licence : GPLv2 Licence : GPLv2
""" """
@ -14,10 +14,10 @@ from fcntl import lockf, LOCK_EX, LOCK_NB, LOCK_UN
import errno, random import errno, random
def wait_lock(lock_name, lock_comment='', d=None, retry=0.2): def wait_lock(lock_name, lock_comment='', d=None, retry=0.2):
"""Attend la disponibilité d'un lock en utilisant le framework Twisted. """Attend la disponibilité d'un lock en utilisant le framework Twisted.
Si d est de type Deferred, on est en mode asynchrone. Si d est de type Deferred, on est en mode asynchrone.
retry permet de réessayer dans `retry' secondes. retry permet de réessayer dans `retry' secondes.
""" """
from twisted.internet import reactor, defer from twisted.internet import reactor, defer
try: try:
@ -30,7 +30,7 @@ def wait_lock(lock_name, lock_comment='', d=None, retry=0.2):
import traceback import traceback
traceback.print_exc() traceback.print_exc()
# On a sans doute pas le lock et c'est pas moi qui me tape # On a sans doute pas le lock et c'est pas moi qui me tape
# à debugguer les trucs à Fred. # à debugguer les trucs à Fred.
raise AssertionError raise AssertionError
# On a le lock # On a le lock
@ -51,8 +51,8 @@ def wait_lock(lock_name, lock_comment='', d=None, retry=0.2):
return d return d
def make_lock(lock_name, lock_comment='',nowait=0, quiet=False) : def make_lock(lock_name, lock_comment='',nowait=0, quiet=False) :
""" Création d'un lock """ Création d'un lock
si nowait=1 fait un sys.exit(254) quand un ancien lock actif est rencontré si nowait=1 fait un sys.exit(254) quand un ancien lock actif est rencontré
""" """
return return
lock_dir = '/var/lock/gestion' lock_dir = '/var/lock/gestion'
@ -62,7 +62,7 @@ def make_lock(lock_name, lock_comment='',nowait=0, quiet=False) :
pass pass
lock_file = "%s/%s" % (lock_dir, lock_name) lock_file = "%s/%s" % (lock_dir, lock_name)
# On créé une zone d'exclusion # On créé une zone d'exclusion
lock_fd_dl=open("%s-dotlock" % lock_file, "w") lock_fd_dl=open("%s-dotlock" % lock_file, "w")
# On demande un verrou exclusif # On demande un verrou exclusif
try: try:
@ -75,12 +75,12 @@ def make_lock(lock_name, lock_comment='',nowait=0, quiet=False) :
# On va plutot lever une exception # On va plutot lever une exception
raise AssertionError('In critical section') raise AssertionError('In critical section')
else: else:
sys.stderr.write('\tpropriétaire : inconnu\n\tpid : inconnu\n\tdémarré depuis inconnu\n') sys.stderr.write('\tpropriétaire : inconnu\n\tpid : inconnu\n\tdémarré depuis inconnu\n')
sys.exit(254) sys.exit(254)
else: else:
# La procédure de lock est deja en cours d'execution, on essaie un peu plus tard # La procédure de lock est deja en cours d'execution, on essaie un peu plus tard
time.sleep(0.5) time.sleep(0.5)
# On enleve le verrou système # On enleve le verrou système
lockf(lock_fd_dl, LOCK_UN) lockf(lock_fd_dl, LOCK_UN)
lock_fd_dl.close() lock_fd_dl.close()
return make_lock(lock_name, lock_comment) return make_lock(lock_name, lock_comment)
@ -124,7 +124,7 @@ def make_lock(lock_name, lock_comment='',nowait=0, quiet=False) :
data[-1]=txt data[-1]=txt
if not quiet: if not quiet:
sys.stderr.write('\tpropriétaire : %s\n\tpid : %s\n\tdémarré depuis %s\n' % tuple(data) ) sys.stderr.write('\tpropriétaire : %s\n\tpid : %s\n\tdémarré depuis %s\n' % tuple(data) )
sys.exit(254) sys.exit(254)
else: else:
# On va plutot lever une exception # On va plutot lever une exception
@ -136,7 +136,7 @@ def make_lock(lock_name, lock_comment='',nowait=0, quiet=False) :
time.sleep(1) time.sleep(1)
a.cycle() a.cycle()
sys.stdout.write('\r') sys.stdout.write('\r')
# On enleve le verrou système # On enleve le verrou système
lockf(lock_fd_dl, LOCK_UN) lockf(lock_fd_dl, LOCK_UN)
lock_fd_dl.close() lock_fd_dl.close()
return make_lock(lock_name, lock_comment) return make_lock(lock_name, lock_comment)
@ -150,7 +150,7 @@ def make_lock(lock_name, lock_comment='',nowait=0, quiet=False) :
lock_fd.write("%s\n%s\n%s" % (os.getpid(), utilisateur, lock_comment) ) lock_fd.write("%s\n%s\n%s" % (os.getpid(), utilisateur, lock_comment) )
lock_fd.close() lock_fd.close()
# On enleve le verrou système # On enleve le verrou système
lockf(lock_fd_dl, LOCK_UN) lockf(lock_fd_dl, LOCK_UN)
lock_fd_dl.close() lock_fd_dl.close()
@ -158,7 +158,7 @@ def make_lock(lock_name, lock_comment='',nowait=0, quiet=False) :
def remove_lock( lock_name ) : def remove_lock( lock_name ) :
""" Destruction du lock """ """ Destruction du lock """
return return
# On créé une zone d'exclusion # On créé une zone d'exclusion
lock_dir = '/var/lock/gestion' lock_dir = '/var/lock/gestion'
lock_file = "%s/%s" % (lock_dir, lock_name) lock_file = "%s/%s" % (lock_dir, lock_name)
@ -169,7 +169,7 @@ def remove_lock( lock_name ) :
except IOError, e: except IOError, e:
if e.errno not in [errno.EACCES, errno.EAGAIN]: if e.errno not in [errno.EACCES, errno.EAGAIN]:
raise raise
# Déjà locké # Déjà locké
time.sleep(0.5) time.sleep(0.5)
return remove_lock(lock_name) return remove_lock(lock_name)
try : try :
@ -180,6 +180,6 @@ def remove_lock( lock_name ) :
except : except :
pass pass
# On enleve le verrou système # On enleve le verrou système
lockf(lock_fd_dl, LOCK_UN) lockf(lock_fd_dl, LOCK_UN)
lock_fd_dl.close() lock_fd_dl.close()

View file

@ -1,8 +1,8 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- encoding: iso-8859-15 -*- # -*- encoding: utf-8 -*-
# Envoi d'un mail donné à certains adherents # Envoi d'un mail donné à certains adherents
# Premier parametre : critere de recherche # Premier parametre : critere de recherche
# Second parametre, fichier à envoyer # Second parametre, fichier à envoyer
import smtplib import smtplib
import sys,os import sys,os
@ -32,7 +32,7 @@ def reconf_postfix():
limit="no" limit="no"
for line in lines: for line in lines:
if line == LIMIT_CONF: if line == LIMIT_CONF:
nlines+=u"## mail_all.py a commenté la ligne suivante" nlines+=u"## mail_all.py a commenté la ligne suivante"
nlines+="# smtpd_client_message_rate_limit = 10\n" nlines+="# smtpd_client_message_rate_limit = 10\n"
limit="yes" limit="yes"
else: else:
@ -43,14 +43,14 @@ def reconf_postfix():
sys.exit(1) sys.exit(1)
if limit == "yes": if limit == "yes":
# Si oui, on demande à l'utilisateur si on y touche # Si oui, on demande à l'utilisateur si on y touche
negatif = ["N", "n", ""] negatif = ["N", "n", ""]
positif = ["O", "o", "Y", "y"] positif = ["O", "o", "Y", "y"]
poursuivre = "x" poursuivre = "x"
while not (poursuivre in negatif + positif): while not (poursuivre in negatif + positif):
poursuivre = raw_input("Il y a trop de destinataires, il faut réécrire la conf de postfix [o/N] ") poursuivre = raw_input("Il y a trop de destinataires, il faut réécrire la conf de postfix [o/N] ")
if poursuivre in negatif: if poursuivre in negatif:
print "Ok, on ne touche pas au fichier..." print "Ok, on ne touche pas au fichier..."
@ -58,14 +58,14 @@ def reconf_postfix():
assert (poursuivre in positif) assert (poursuivre in positif)
# On réécrit la conf # On réécrit la conf
try: try:
nconf_fd = open (POSTFIX_CONF, "w") nconf_fd = open (POSTFIX_CONF, "w")
print u"Réécriture de la configuration de postfix" print u"Réécriture de la configuration de postfix"
nconf_fd.writelines(nlines) nconf_fd.writelines(nlines)
nconf_fd.close () nconf_fd.close ()
except IOError: except IOError:
print u"Je n'arrive pas à réécrire la conf de postfix, es-tu root ?" print u"Je n'arrive pas à réécrire la conf de postfix, es-tu root ?"
sys.exit(1) sys.exit(1)
reload_postfix() reload_postfix()
@ -76,50 +76,50 @@ if __name__ == "__main__":
if len(sys.argv) != 3: if len(sys.argv) != 3:
print """Usage: print """Usage:
Ce script permet d'envoyer un mail à toute une catégorie d'adhérents. Ce script permet d'envoyer un mail à toute une catégorie d'adhérents.
Le premier paramètre est le critère de recherche : Le premier paramètre est le critère de recherche :
paiement=ok pour les adhérents en règle paiement=ok pour les adhérents en règle
paiement=ok&paiement!=2004 pour ceux qui n'ont pas encore payé pour cette année paiement=ok&paiement!=2004 pour ceux qui n'ont pas encore payé pour cette année
chbre=????&paiement=ok pour ceux dont la chambre est inconnue chbre=????&paiement=ok pour ceux dont la chambre est inconnue
paiement=ok&carteEtudiant!=2004 pour ceux qui n'ont pas de carte d'étudiant paiement=ok&carteEtudiant!=2004 pour ceux qui n'ont pas de carte d'étudiant
Le second paramètre est un fichier texte qui contient le message à envoyer. Il Le second paramètre est un fichier texte qui contient le message à envoyer. Il
doit également contenir les entêtes, à l'exception du destinataire qui sera rajouté doit également contenir les entêtes, à l'exception du destinataire qui sera rajouté
par le script. par le script.
/!\ Ce script ne demande aucune confirmation, il faut veiller à /!\ Ce script ne demande aucune confirmation, il faut veiller à
vérifier avec who que l'on cible bien les utilisateurs que l'on vérifier avec who que l'on cible bien les utilisateurs que l'on
veut. Et si on veut vérifier que le mail a une bonne tête on se veut. Et si on veut vérifier que le mail a une bonne tête on se
l'envoie d'abord en mettant login=machin comme critère de l'envoie d'abord en mettant login=machin comme critère de
recherche. recherche.
/!\ Ce script a pour but de spammer, et spammer c'est mal. Il faut /!\ Ce script a pour but de spammer, et spammer c'est mal. Il faut
donc contourner les limitations qui ont été mises en place au donc contourner les limitations qui ont été mises en place au
Cr@ns. Si plus de 10 mails doivent être envoyés, il faut le faire Cr@ns. Si plus de 10 mails doivent être envoyés, il faut le faire
depuis rouge, et ce en root. depuis rouge, et ce en root.
""" """
sys.exit(0) sys.exit(0)
# On en est là # On en est là
# On ouvre la base et on cherche # On ouvre la base et on cherche
adherents = ldap_crans.crans_ldap().search(sys.argv[1])['adherent'] adherents = ldap_crans.crans_ldap().search(sys.argv[1])['adherent']
card= len(adherents) card= len(adherents)
print "%d adhérent(s) a/ont été trouvé(s)..." % card print "%d adhérent(s) a/ont été trouvé(s)..." % card
time.sleep(3) # On dort un peu, ctrl-c welcome time.sleep(3) # On dort un peu, ctrl-c welcome
limit="no" limit="no"
if card >= 10: if card >= 10:
(limit, backup_conf) = reconf_postfix() (limit, backup_conf) = reconf_postfix()
# Il faudra quoiqu'il arrive rétablir la conf de postfix # Il faudra quoiqu'il arrive rétablir la conf de postfix
# try capture-t-il les SIGTERM ?! # try capture-t-il les SIGTERM ?!
try: try:
try: try:
texte = "".join(file(sys.argv[2], "r").readlines()) texte = "".join(file(sys.argv[2], "r").readlines())
except IOError: except IOError:
print "Impossible d'ouvrir le fichier à envoyer, merci, au revoir." print "Impossible d'ouvrir le fichier à envoyer, merci, au revoir."
sys.exit(1) sys.exit(1)
echecs = [] echecs = []
@ -129,14 +129,14 @@ par le script.
mail = adherent.mail().encode("iso-8859-15", "ignore") mail = adherent.mail().encode("iso-8859-15", "ignore")
if "@" not in mail: if "@" not in mail:
mail = mail + "@crans.org" mail = mail + "@crans.org"
print "Envoi du mail à %s <%s>..." % (adherent.Nom().encode("iso-8859-15","ignore"), mail) print "Envoi du mail à %s <%s>..." % (adherent.Nom().encode("iso-8859-15","ignore"), mail)
try: try:
recipient = format_sender(u'"%s" <%s>\n' % (adherent.Nom(), mail)) recipient = format_sender(u'"%s" <%s>\n' % (adherent.Nom(), mail))
s.sendmail('bulk+%s@crans.org' % mail.replace("@",'-at-'), s.sendmail('bulk+%s@crans.org' % mail.replace("@",'-at-'),
(mail,), (mail,),
"To: %s\n%s" % (recipient, texte)) "To: %s\n%s" % (recipient, texte))
except: except:
print "Erreur lors de l'envoi à %s <%s>..." % (adherent.Nom().encode("iso-8859-15","ignore"), mail) print "Erreur lors de l'envoi à %s <%s>..." % (adherent.Nom().encode("iso-8859-15","ignore"), mail)
echecs.append(mail) echecs.append(mail)
else: else:
# Tout va bien # Tout va bien
@ -148,7 +148,7 @@ par le script.
s.close() s.close()
# On rétablit la conf de postfix # On rétablit la conf de postfix
finally: finally:
if limit == "yes": if limit == "yes":
try: try:

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" """
Script de mise a jour des firmwares de switchs Script de mise a jour des firmwares de switchs
@ -17,7 +17,7 @@ import os
if sys.argv[1] == '-h' or sys.argv[1]=='--help' : if sys.argv[1] == '-h' or sys.argv[1]=='--help' :
print "Usage : %s <ip du serveur tftp> <fichier sur le tftp> regex " % sys.argv[0] print "Usage : %s <ip du serveur tftp> <fichier sur le tftp> regex " % sys.argv[0]
print "Envoi les commandes données au switchs matchant la regex" print "Envoi les commandes données au switchs matchant la regex"
sys.exit(0) sys.exit(0)
ip_tftp=sys.argv[1] ip_tftp=sys.argv[1]
@ -40,16 +40,16 @@ print switchs
print "---------------" print "---------------"
if not switchs : if not switchs :
print "Aucun switch trouvé" print "Aucun switch trouvé"
print "Note : il faut une _regex_ (!= wilcards au sens du shell)" print "Note : il faut une _regex_ (!= wilcards au sens du shell)"
sys.exit(1) sys.exit(1)
if not ip_tftp : if not ip_tftp :
print "Pas de serveur tftp donné" print "Pas de serveur tftp donné"
sys.exit(1) sys.exit(1)
if not file_tftp : if not file_tftp :
print "Pas de fichier donné" print "Pas de fichier donné"
sys.exit(1) sys.exit(1)
# On fait les tests uniquement sur batv-3 # On fait les tests uniquement sur batv-3
@ -127,7 +127,7 @@ for bestiole in switchs :
i=i+1 i=i+1
sleep(1) sleep(1)
if i==300 : if i==300 :
print "Le switch n'a tjs pas rebooté" print "Le switch n'a tjs pas rebooté"
echecs.append(bestiole) echecs.append(bestiole)
aie=1 aie=1
break break
@ -136,8 +136,8 @@ for bestiole in switchs :
print "---------------" print "---------------"
continue continue
print "Reboot commencé" print "Reboot commencé"
print "Attente de réponse au ping" print "Attente de réponse au ping"
i=0 i=0
aie=0 aie=0
@ -154,7 +154,7 @@ for bestiole in switchs :
print "---------------" print "---------------"
continue continue
print "Le switch répond au ping" print "Le switch répond au ping"
print "Connexion ssh" print "Connexion ssh"

View file

@ -1,5 +1,5 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" """
Mise a jour periodique des listes d'ip et d'id disponibles. Mise a jour periodique des listes d'ip et d'id disponibles.
@ -42,7 +42,7 @@ def lister_ip_utilisees():
def update_ip(plage, occupees): def update_ip(plage, occupees):
net = NETs[plage] net = NETs[plage]
pool_ip = [] # Pool d'IP à tester pool_ip = [] # Pool d'IP à tester
for ne in net: for ne in net:
ip = ne.split('/')[0] ip = ne.split('/')[0]
ip = ip.split('.') ip = ip.split('.')
@ -58,7 +58,7 @@ def update_ip(plage, occupees):
if n[2] == 255: break if n[2] == 255: break
ip = "%d.%d.%d.%d" % tuple(n) ip = "%d.%d.%d.%d" % tuple(n)
if not AddrInNet(ip, ne): if not AddrInNet(ip, ne):
# On est allé trop loin # On est allé trop loin
break break
pool_ip.append(ip) pool_ip.append(ip)

View file

@ -1,10 +1,10 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" """
Restauration d'un objet précédement détruit dans la base. Restauration d'un objet précédement détruit dans la base.
Copyright (C) Frédéric Pauget Copyright (C) Frédéric Pauget
Licence : GPLv2 Licence : GPLv2
""" """
@ -17,21 +17,21 @@ from gest_crans import modif_adher, set_machine, modif_club
from ldap_crans import mailexist from ldap_crans import mailexist
def load(file) : def load(file) :
""" Charge l'objet (adhérent, machine ou club contenu dans le fichier fourni """ """ Charge l'objet (adhérent, machine ou club contenu dans le fichier fourni """
try : try :
fd=open(file,'rb') fd=open(file,'rb')
except : except :
print "Impossible d'ouvrir le fichier demandé." print "Impossible d'ouvrir le fichier demandé."
sys.exit(1) sys.exit(1)
obj = cPickle.load(fd) obj = cPickle.load(fd)
try : try :
# Si machine vérif si le proprio est encore dans la base # Si machine vérif si le proprio est encore dans la base
test_proprio = obj.proprietaire() test_proprio = obj.proprietaire()
if test_proprio.Nom() != obj.proprio : if test_proprio.Nom() != obj.proprio :
raise raise
# Propriétaire encore dans la base => on récupère les infos de la base # Propriétaire encore dans la base => on récupère les infos de la base
del obj.proprio del obj.proprio
except : except :
pass pass
@ -47,7 +47,7 @@ def load(file) :
if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) != 2 : if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) != 2 :
print "%s <fichier>" % sys.argv[0].split('/')[-1].split('.')[0] print "%s <fichier>" % sys.argv[0].split('/')[-1].split('.')[0]
print "Restauration ou visualisation d'un objet précédement détruit dans la base." print "Restauration ou visualisation d'un objet précédement détruit dans la base."
print "Les fichiers de sauvegarde sont dans %s" % config.cimetiere print "Les fichiers de sauvegarde sont dans %s" % config.cimetiere
sys.exit(255) sys.exit(255)
@ -56,17 +56,17 @@ aff(obj)
def restore_adher(adh) : def restore_adher(adh) :
if adh.compte() and mailexist(adh.compte()) : if adh.compte() and mailexist(adh.compte()) :
print "AVERTISSEMENT : le login %s à déja été réattribué." % adh.compte() print "AVERTISSEMENT : le login %s à déja été réattribué." % adh.compte()
print " il faudra recréer un compte avec un login différent" print " il faudra recréer un compte avec un login différent"
prompt(u'Appuyez sur ENTREE pour continuer') prompt(u'Appuyez sur ENTREE pour continuer')
adh._data['mail'] = [] adh._data['mail'] = []
modif_adher(adh) modif_adher(adh)
def restore_machine(machine) : def restore_machine(machine) :
try : try :
obj.proprio # crash si l'adhérent est encore dans la base obj.proprio # crash si l'adhérent est encore dans la base
# L'adhérent est plus dans la base # L'adhérent est plus dans la base
t = prompt(u"Ratacher la machine à un [C]lub ou un [A]dhérent ?") t = prompt(u"Ratacher la machine à un [C]lub ou un [A]dhérent ?")
t = t.lower() t = t.lower()
if t in 'ac' : if t in 'ac' :
i = prompt(u"Entrez l'%sid auquel ratacher la machine : %sid =" % (t,t) ) i = prompt(u"Entrez l'%sid auquel ratacher la machine : %sid =" % (t,t) )
@ -79,11 +79,11 @@ def restore_club(club) :
modif_club(club) modif_club(club)
# Restauration ? # Restauration ?
q = prompt(u'Restaurer cette entrée ? [O/N]') q = prompt(u'Restaurer cette entrée ? [O/N]')
if q not in 'oO' : if q not in 'oO' :
sys.exit(0) sys.exit(0)
obj.connect() # Reconnection à la base LDAP obj.connect() # Reconnection à la base LDAP
if obj.idn == 'aid' : if obj.idn == 'aid' :
restore_adher(obj) restore_adher(obj)
elif obj.idn == 'mid' : elif obj.idn == 'mid' :

View file

@ -1,9 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
""" Fonctions de tests sur l'utilisateur """ Fonctions de tests sur l'utilisateur
Copyright (C) Frédéric Pauget Copyright (C) Frédéric Pauget
Licence : GPLv2 Licence : GPLv2
""" """
@ -18,7 +18,7 @@ def getuser() :
def groups(login='') : def groups(login='') :
""" Retourne la liste des droits qu'a l'utilisateur fourni, si aucun """ Retourne la liste des droits qu'a l'utilisateur fourni, si aucun
utilisateur n'est fourni prend l'utilisateur loggué """ utilisateur n'est fourni prend l'utilisateur loggué """
if login == '': if login == '':
login = getuser() login = getuser()
@ -43,15 +43,15 @@ def groups(login='') :
def isadm(login='') : def isadm(login='') :
""" Retourne True si l'utilisateur est dans le groupe 4 (adm) """ Retourne True si l'utilisateur est dans le groupe 4 (adm)
Si login='', prend l'utilisateur loggué """ Si login='', prend l'utilisateur loggué """
return u'Nounou' in groups(login) or '0' in groups(login) return u'Nounou' in groups(login) or '0' in groups(login)
def isdeconnecteur(login='') : def isdeconnecteur(login='') :
""" Retourne True si l'utilisateur est dans le groupe 611 (bureau) """ Retourne True si l'utilisateur est dans le groupe 611 (bureau)
Si login='', prend l'utilisateur loggué """ Si login='', prend l'utilisateur loggué """
return isadm(login) or u'Bureau' in groups(login) return isadm(login) or u'Bureau' in groups(login)
def iscableur(login=''): def iscableur(login=''):
""" Retourne True si l'utilisateur est dans le groupe 604 (respbat) """ Retourne True si l'utilisateur est dans le groupe 604 (respbat)
Si login='', prend l'utilisateur loggué """ Si login='', prend l'utilisateur loggué """
return isadm(login) or u'Cableur' in groups(login) return isadm(login) or u'Cableur' in groups(login)

View file

@ -1,19 +1,19 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
# Copyright (C) Frédéric Pauget # Copyright (C) Frédéric Pauget
# Licence : GPLv2 # Licence : GPLv2
u"""Ce script permet de recherche et d'afficher le détail d'une machine ou u"""Ce script permet de recherche et d'afficher le détail d'une machine ou
d'un adhérent. d'un adhérent.
Usage: %(prog)s [options] <chaine de recherche> Usage: %(prog)s [options] <chaine de recherche>
La chaine de recherche peut être : La chaine de recherche peut être :
* soit un terme unique, dans ce cas la recherche sera effectuée sur les * soit un terme unique, dans ce cas la recherche sera effectuée sur les
champs en bleu ci-dessous. champs en bleu ci-dessous.
* soit du type "champ1=valeur1&champ2!=valeur2 ...", les résultats seront * soit du type "champ1=valeur1&champ2!=valeur2 ...", les résultats seront
alors limités aux entrées correspondantes à tous les critères. alors limités aux entrées correspondantes à tous les critères.
Les champs de recherche possibles sont : Les champs de recherche possibles sont :
%(champs_rech)s %(champs_rech)s
@ -22,19 +22,19 @@ Recherche sur prise possible (utiliser uniquement ce champ dans ce cas).
Les options de recherches sont : Les options de recherches sont :
* limitations sur l'affichage : * limitations sur l'affichage :
-a ou --adherent : limitation de l'affichage aux adhérents -a ou --adherent : limitation de l'affichage aux adhérents
-m ou --machine : limitation de l'affichage aux machines -m ou --machine : limitation de l'affichage aux machines
-c ou --club : limitation de l'affichage aux clubs -c ou --club : limitation de l'affichage aux clubs
-b ou --bornes : limitation de l'affichage aux bornes wifi -b ou --bornes : limitation de l'affichage aux bornes wifi
--crans : recherche uniquement les machines du crans --crans : recherche uniquement les machines du crans
* options d'affichage : * options d'affichage :
-t ou --tech : affichages des infos techniques des machines -t ou --tech : affichages des infos techniques des machines
à la place des infos administratives dans les résumés. à la place des infos administratives dans les résumés.
-i ou --ipsec : montre la clef ipsec des machines wifi -i ou --ipsec : montre la clef ipsec des machines wifi
-l <num> ou --limit=<num> : limite du nombre de résultats pour utiliser -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) 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 -L <num> ou --limit-historique=<num> : limitation du nombre de lignes
d'historique affichées (défaut %(limit_aff_historique)i) d'historique affichées (défaut %(limit_aff_historique)i)
""" """
try: try:
@ -63,14 +63,14 @@ aff_ipsec = 0
def aff(qqch,mtech=0) : def aff(qqch,mtech=0) :
""" Affichage de qqch. """ Affichage de qqch.
qqch peut être une liste d'instances des classes adhérent ou machine qqch peut être une liste d'instances des classes adhérent ou machine
(un seul type dans la liste) dans ce cas : (un seul type dans la liste) dans ce cas :
* si la longueur de la liste est inférieure à limit_aff_details * si la longueur de la liste est inférieure à limit_aff_details
affiche les propriétés détaillées de chaque élément. affiche les propriétés détaillées de chaque élément.
* sinon résume dans un tabeau des principales propriétés * 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 qqch est une instance seul la traité comme une liste à une élément
Si mtech = 1 affiches les infomations techniques des machines plutot Si mtech = 1 affiches les infomations techniques des machines plutot
qu'administratives dans le tableau des propriétés qu'administratives dans le tableau des propriétés
""" """
if type(qqch) != list : if type(qqch) != list :
qqch = [ qqch ] qqch = [ qqch ]
@ -99,26 +99,26 @@ def aff(qqch,mtech=0) :
elif t == 'cid': elif t == 'cid':
cprint(club_details(c).strip()) cprint(club_details(c).strip())
# affiche le nombre de résultats # affiche le nombre de résultats
if len(qqch) > 1: if len(qqch) > 1:
cprint(u"Total: %d" % len(qqch)) cprint(u"Total: %d" % len(qqch))
def adhers_brief(adhers) : def adhers_brief(adhers) :
""" """
Formatage sous forme de tableau des infos sur la liste d'adhérent fournie : Formatage sous forme de tableau des infos sur la liste d'adhérent fournie :
* aid * aid
* prénom nom * prénom nom
* chambre * chambre
* machines * machines
""" """
data = [] data = []
# Copie locale triée par (nom, prenom) # Copie locale triée par (nom, prenom)
adhers = adhers[:] adhers = adhers[:]
adhers.sort(lambda x, y: cmp((x.nom(), x.prenom()), (y.nom(), y.prenom()))) adhers.sort(lambda x, y: cmp((x.nom(), x.prenom()), (y.nom(), y.prenom())))
for a in adhers: for a in adhers:
## État administratif ## État administratif
ok = u'\x1b[1;32mo\x1b[1;0m' ok = u'\x1b[1;32mo\x1b[1;0m'
ook = u'\x1b[1;32mO\x1b[1;0m' ook = u'\x1b[1;32mO\x1b[1;0m'
nok = u'\x1b[1;31mn\x1b[1;0m' nok = u'\x1b[1;31mn\x1b[1;0m'
@ -129,17 +129,17 @@ def adhers_brief(adhers) :
elif isinstance(a,Adherent) and not a.adherentPayant(): paid = coul('G', 'bleu') elif isinstance(a,Adherent) and not a.adherentPayant(): paid = coul('G', 'bleu')
else: paid = nok else: paid = nok
# Précablage # Précablage
if ann_scol+1 in a.paiement() : paid = coul(paid,'f_vert') if ann_scol+1 in a.paiement() : paid = coul(paid,'f_vert')
# Carte d'étudiant # Carte d'étudiant
if ann_scol in a.carteEtudiant(): if ann_scol in a.carteEtudiant():
if 'c' in a.controle(): carte = ook if 'c' in a.controle(): carte = ook
else: carte = ok else: carte = ok
else : carte = nok else : carte = nok
machines = '' machines = ''
# Récupération des machines # Récupération des machines
if len(adhers) <= limit_aff_machines: if len(adhers) <= limit_aff_machines:
for machine in a.machines() : for machine in a.machines() :
nom = machine.nom().split('.')[0] nom = machine.nom().split('.')[0]
@ -150,7 +150,7 @@ def adhers_brief(adhers) :
else : machines = coul(nom,k) else : machines = coul(nom,k)
else: else:
machines = None machines = None
# Données # Données
if len(adhers) <= limit_aff_machines: if len(adhers) <= limit_aff_machines:
data.append([a.id(), a.Nom(), a.chbre(), paid, carte, machines]) data.append([a.id(), a.Nom(), a.chbre(), paid, carte, machines])
else: else:
@ -158,41 +158,41 @@ def adhers_brief(adhers) :
if len(adhers) <= limit_aff_machines: if len(adhers) <= limit_aff_machines:
return u"Machines en rouge = machines avec limitation de services\n" + \ 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 (G bleu = inscription gratuite)\n" + \ u"P : paiement année en cours, le fond vert indique le précâblage (G bleu = inscription gratuite)\n" + \
u"C : carte d'étudiant année en cours\n" + \ u"C : carte d'étudiant année en cours\n" + \
tableau(data, tableau(data,
titre = [u'aid', u'Prénom Nom', u'Chbre', u'P', u'C', u'Machines'], titre = [u'aid', u'Prénom Nom', u'Chbre', u'P', u'C', u'Machines'],
largeur = [5, 30, 5, 1, 1, '*'], largeur = [5, 30, 5, 1, 1, '*'],
alignement = ['d', 'c', 'g', 'c', 'c', 'c']) alignement = ['d', 'c', 'g', 'c', 'c', 'c'])
else: else:
return u"Machines en rouge = machines avec limitation de services\n" + \ 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 (G bleu = inscription gratuite)\n" + \ u"P : paiement année en cours, le fond vert indique le précâblage (G bleu = inscription gratuite)\n" + \
u"C : carte d'étudiant année en cours\n" + \ u"C : carte d'étudiant année en cours\n" + \
tableau(data, tableau(data,
titre = [u'aid', u'Prénom Nom', u'Chbre', u'P', u'C'], titre = [u'aid', u'Prénom Nom', u'Chbre', u'P', u'C'],
largeur = [5, '*', 5, 1, 1], largeur = [5, '*', 5, 1, 1],
alignement = ['d', 'c', 'g', 'c', 'c']) alignement = ['d', 'c', 'g', 'c', 'c'])
def machines_brief(machines) : def machines_brief(machines) :
""" """
Formatage sous forme d'un tableau des propriétés de la liste de machine : Formatage sous forme d'un tableau des propriétés de la liste de machine :
* mid * mid
* type (fixe ou wifi, born) * type (fixe ou wifi, born)
* nom * nom
* adresse IP * adresse IP
* adresse MAC * adresse MAC
* si blacklistée * si blacklistée
""" """
data = [] data = []
# Copie locale triée par nom # Copie locale triée par nom
machines = machines[:] machines = machines[:]
machines.sort(lambda x, y: cmp(x.nom(), y.nom())) machines.sort(lambda x, y: cmp(x.nom(), y.nom()))
for m in machines : for m in machines :
t, bl = __bases_machines(m) t, bl = __bases_machines(m)
# Propriétaire # Propriétaire
a = m.proprietaire() a = m.proprietaire()
p = a.Nom() p = a.Nom()
@ -203,12 +203,12 @@ def machines_brief(machines) :
else: else:
p = coul(p,'rouge') p = coul(p,'rouge')
# Données # Données
data.append([m.id() , t, m.nom().split('.')[0], p, a.chbre(), bl]) 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, en bleu une inscription gratuite\n" + \ return u"Le propriétaire en rouge signale un problème administratif, en bleu une inscription gratuite\n" + \
tableau(data, tableau(data,
titre = [u'mid', u'Type', u'Nom de machine', u'Propriétaire', u'Chbre', u'Limitation'], titre = [u'mid', u'Type', u'Nom de machine', u'Propriétaire', u'Chbre', u'Limitation'],
largeur = [5, 4, 18, '*', 5, 10], largeur = [5, 4, 18, '*', 5, 10],
alignement = ['d', 'c', 'c', 'c', 'g', 'c']) alignement = ['d', 'c', 'c', 'c', 'g', 'c'])
@ -222,12 +222,12 @@ def clubs_brief(clubs) :
""" """
data = [] data = []
# Copie locale triée par Nom # Copie locale triée par Nom
clubs = clubs[:] clubs = clubs[:]
clubs.sort(lambda x, y: cmp(x.Nom(), y.Nom())) clubs.sort(lambda x, y: cmp(x.Nom(), y.Nom()))
for c in clubs : for c in clubs :
## État administratif ## État administratif
ok = u'\x1b[1;32mo\x1b[1;0m' ok = u'\x1b[1;32mo\x1b[1;0m'
ook = u'\x1b[1;32mO\x1b[1;0m' ook = u'\x1b[1;32mO\x1b[1;0m'
nok = u'\x1b[1;31mn\x1b[1;0m' nok = u'\x1b[1;31mn\x1b[1;0m'
@ -237,11 +237,11 @@ def clubs_brief(clubs) :
else: paid = ok else: paid = ok
else : paid = nok else : paid = nok
# Précablage # Précablage
if ann_scol+1 in c.paiement() : paid = coul(paid,'f_vert') if ann_scol+1 in c.paiement() : paid = coul(paid,'f_vert')
machines = '' machines = ''
# Récupération des machines # Récupération des machines
for machine in c.machines() : for machine in c.machines() :
nom = machine.nom().split('.')[0] nom = machine.nom().split('.')[0]
if machine.blacklist_actif() : k = 'rouge' if machine.blacklist_actif() : k = 'rouge'
@ -252,11 +252,11 @@ def clubs_brief(clubs) :
# Responsable # Responsable
resp = c.responsable().Nom() resp = c.responsable().Nom()
# Données # Données
data.append([c.id() , c.Nom(), c.local(), paid, resp, machines]) data.append([c.id() , c.Nom(), c.local(), paid, resp, machines])
return u"Machines en rouge = machines avec limitation de services\n" + \ 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" + \ u"P : signature charte année en cours, le fond vert indique le précâblage\n" + \
tableau(data, tableau(data,
titre = [u'cid', u'Nom ', u'Local', u'P', u'Responsable', u'Machines'], titre = [u'cid', u'Nom ', u'Local', u'P', u'Responsable', u'Machines'],
largeur = [5, '*', 6, 1, 21, 15], largeur = [5, '*', 6, 1, 21, 15],
@ -265,24 +265,24 @@ def clubs_brief(clubs) :
def list_machines(machines) : def list_machines(machines) :
""" """
Formatage sous forme d'un tableau des propriétés de la liste de machine : Formatage sous forme d'un tableau des propriétés de la liste de machine :
* mid * mid
* type (fixe ou wifi) * type (fixe ou wifi)
* nom * nom
* adresse IP * adresse IP
* adresse MAC * adresse MAC
* si blacklistée * si blacklistée
""" """
data = [] data = []
# Copie locale triée par nom # Copie locale triée par nom
machines = machines[:] machines = machines[:]
machines.sort(lambda x, y: cmp(x.nom(), y.nom())) machines.sort(lambda x, y: cmp(x.nom(), y.nom()))
for m in machines : for m in machines :
t, bl = __bases_machines(m) t, bl = __bases_machines(m)
# Données # Données
data.append([m.id(), t, m.nom().split('.')[0], m.ip(), m.mac(), bl]) data.append([m.id(), t, m.nom().split('.')[0], m.ip(), m.mac(), bl])
return tableau(data, return tableau(data,
@ -292,19 +292,19 @@ def list_machines(machines) :
def list_bornes(bornes) : def list_bornes(bornes) :
""" """
Formatage sous forme d'un tableau des propriétés de la liste de bornes wifi : Formatage sous forme d'un tableau des propriétés de la liste de bornes wifi :
* mid * mid
* nom * nom
* adresse IP * adresse IP
* adresse MAC * adresse MAC
* État * État
* puissance * puissance
* canal * canal
* lieu (la première remarque en fait) * lieu (la première remarque en fait)
""" """
data = [] data = []
# Copie locale triée par nom # Copie locale triée par nom
bornes = bornes[:] bornes = bornes[:]
bornes.sort(lambda x, y: cmp(x.nom(), y.nom())) bornes.sort(lambda x, y: cmp(x.nom(), y.nom()))
@ -314,7 +314,7 @@ def list_bornes(bornes) :
t, bl = __bases_machines(b) t, bl = __bases_machines(b)
if t != 'born' : continue if t != 'born' : continue
# Données # Données
try : try :
l = [x for x in b.info() if not x[0]=='<'][0] l = [x for x in b.info() if not x[0]=='<'][0]
if len(l) > 11 : if len(l) > 11 :
@ -334,7 +334,7 @@ def list_bornes(bornes) :
data.append([b.id(), b.nom().split('.')[0], b.ip(), b.mac(), etat, b.canal(), puiss, b.prise(), l]) 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" + \ return u"Can=canaux, P=puissance, E=état\n" + \
tableau(data, tableau(data,
titre = [u'mid', u'Nom', u'Adresse IP', u'Adresse MAC', u'E', u'Can', u'P', u'Pris', u'Lieu'], titre = [u'mid', u'Nom', u'Adresse IP', u'Adresse MAC', u'E', u'Can', u'P', u'Pris', u'Lieu'],
largeur = [5, 13, 15, 17, 1, 5, 3, 4, '*'], largeur = [5, 13, 15, 17, 1, 5, 3, 4, '*'],
@ -342,7 +342,7 @@ def list_bornes(bornes) :
def adher_details(adher) : def adher_details(adher) :
""" """
Affichage du détail des propriétés d'un adhérent Affichage du détail des propriétés d'un adhérent
""" """
f=u'' f=u''
# Aid # Aid
@ -370,12 +370,12 @@ def adher_details(adher) :
if not adher.contourneGreylist(): if not adher.contourneGreylist():
GL = u' (%s)'%coul(u'GreyList','gris') GL = u' (%s)'%coul(u'GreyList','gris')
if adher.rewriteMailHeaders(): if adher.rewriteMailHeaders():
RMH = u' (%s)'%coul(u'réécriture en-têtes mail','gris') RMH = u' (%s)'%coul(u'réécriture en-têtes mail','gris')
alias = u', '.join([adher.canonical_alias()] + adher.alias()) alias = u', '.join([adher.canonical_alias()] + adher.alias())
if alias: if alias:
if alias[0] == u',': if alias[0] == u',':
# Canonical étéait vide # Canonical étéait vide
alias = alias[2:] alias = alias[2:]
f += coul(u'Alias : ','gras') + alias f += coul(u'Alias : ','gras') + alias
f += GL f += GL
@ -390,9 +390,9 @@ def adher_details(adher) :
if forward: if forward:
f += coul(u'Redirection : ', 'gras') + forward f += coul(u'Redirection : ', 'gras') + forward
except IOError, e: except IOError, e:
# Pas de .forward, ou .forward privé... on laisse tomber # Pas de .forward, ou .forward privé... on laisse tomber
pass pass
f += coul(u'Dernière connexion : ', 'gras') f += coul(u'Dernière connexion : ', 'gras')
timestamp = adher.derniereConnexion() timestamp = adher.derniereConnexion()
if timestamp == 0: if timestamp == 0:
f += coul(u'Jamais', 'rouge') f += coul(u'Jamais', 'rouge')
@ -401,24 +401,24 @@ def adher_details(adher) :
time()-timestamp > 32*24*3600 and 'rouge' or '') time()-timestamp > 32*24*3600 and 'rouge' or '')
f += u"\n" f += u"\n"
# État administratif # État administratif
f += coul("Date d'inscription : ", "gras") f += coul("Date d'inscription : ", "gras")
f += strftime('%d/%m/%Y %H:%M', localtime(adher.dateInscription())) f += strftime('%d/%m/%Y %H:%M', localtime(adher.dateInscription()))
f += coul(u'\nÉtat administratif : ','gras') f += coul(u'\nÉtat administratif : ','gras')
jour=1 jour=1
if ann_scol not in adher.carteEtudiant() : if ann_scol not in adher.carteEtudiant() :
f += coul(u"manque carte d'étudiant",'violet') f += coul(u"manque carte d'étudiant",'violet')
jour = 0 jour = 0
if ann_scol not in adher.paiement() : if ann_scol not in adher.paiement() :
if not jour : f += ' et ' if not jour : f += ' et '
if isinstance(adher, Adherent) and not adher.adherentPayant(): if isinstance(adher, Adherent) and not adher.adherentPayant():
f += coul(u"inscription gratuite", 'bleu') f += coul(u"inscription gratuite", 'bleu')
else: else:
f += coul(u"cotisation %s/%d non réglée"% (ann_scol, ann_scol+1 ),'violet') f += coul(u"cotisation %s/%d non réglée"% (ann_scol, ann_scol+1 ),'violet')
jour = 0 jour = 0
if jour : if jour :
f += coul(u"à jour",'vert') f += coul(u"à jour",'vert')
f += '\n' f += '\n'
# Telephone # Telephone
@ -428,12 +428,12 @@ def adher_details(adher) :
tel = u'%s %s %s %s %s' % ( tel[:2], tel[2:4], tel[4:6], tel[6:8], tel[8:] ) tel = u'%s %s %s %s %s' % ( tel[:2], tel[2:4], tel[4:6], tel[6:8], tel[8:] )
except : except :
pass pass
f += coul(u'Numéro de téléphone : ','gras') + "%s\n" % tel.ljust(12) f += coul(u'Numéro de téléphone : ','gras') + "%s\n" % tel.ljust(12)
# Adresse # Adresse
chbre = adher.chbre() chbre = adher.chbre()
if chbre == 'EXT' : if chbre == 'EXT' :
# Adhérent extérieur # Adhérent extérieur
addr = adher.adresse() addr = adher.adresse()
if addr[0] : if addr[0] :
f += coul(u'Adresse : ','gras') f += coul(u'Adresse : ','gras')
@ -443,7 +443,7 @@ def adher_details(adher) :
elif chbre == '????' : elif chbre == '????' :
f += coul(u'Chambre invalide\n','violet') f += coul(u'Chambre invalide\n','violet')
else : else :
# Chambre + prise (d'après annuaire) # Chambre + prise (d'après annuaire)
etat, vlans = prise_etat(adher.chbre()) etat, vlans = prise_etat(adher.chbre())
f += coul(u'Chambre : ','gras') + u"%s " % chbre f += coul(u'Chambre : ','gras') + u"%s " % chbre
f += u'(%s)' % etat f += u'(%s)' % etat
@ -453,12 +453,12 @@ def adher_details(adher) :
f += coul(u'VLAN : ','gras') + u'%s' % vlans f += coul(u'VLAN : ','gras') + u'%s' % vlans
f += u'\n' f += u'\n'
# Études # Études
if adher.etudes(1).isdigit() : if adher.etudes(1).isdigit() :
f += coul(u'Études : ','gras')+ "%s %s%s\n" % \ f += coul(u'Études : ','gras')+ "%s %s%s\n" % \
( adher.etudes(0), adher.etudes(1), adher.etudes(2) ) ( adher.etudes(0), adher.etudes(1), adher.etudes(2) )
elif adher.etudes(0) : elif adher.etudes(0) :
f += coul(u'Études : ','gras')+ "%s %s %s\n" % \ f += coul(u'Études : ','gras')+ "%s %s %s\n" % \
( adher.etudes(0), adher.etudes(1), adher.etudes(2) ) ( adher.etudes(0), adher.etudes(1), adher.etudes(2) )
# Solde # Solde
@ -476,15 +476,15 @@ def adher_details(adher) :
if d : if d :
f += coul(u"Droits sur les serveurs : ",'gras') + ', '.join(d) f += coul(u"Droits sur les serveurs : ",'gras') + ', '.join(d)
if adher.droitsGeles(): if adher.droitsGeles():
f += coul(u" (droits gelés car pas cotisé cette année)",'bleu') f += coul(u" (droits gelés car pas cotisé cette année)",'bleu')
f += u'\n' f += u'\n'
# Paiement # Paiement
if adher.paiement() : if adher.paiement() :
if len(adher.paiement()) == 1 : if len(adher.paiement()) == 1 :
f += coul(u'Cotisation payée pour l\'année scolaire :','gras') f += coul(u'Cotisation payée pour l\'année scolaire :','gras')
else : else :
f += coul(u'Cotisation payée pour les années scolaires :','gras') f += coul(u'Cotisation payée pour les années scolaires :','gras')
g = u'' g = u''
for an in adher.paiement() : g += u" %i-%i" % ( an, an+1 ) for an in adher.paiement() : g += u" %i-%i" % ( an, an+1 )
if len(g) > 35 : f += '\n\t' if len(g) > 35 : f += '\n\t'
@ -492,12 +492,12 @@ def adher_details(adher) :
if 'p' in adher.controle(): f += coul(u' (OK)', 'vert') if 'p' in adher.controle(): f += coul(u' (OK)', 'vert')
f += u'\n' f += u'\n'
# Cartes d'étudiant fournie # Cartes d'étudiant fournie
if adher.carteEtudiant() : if adher.carteEtudiant() :
if len(adher.carteEtudiant()) == 1 : if len(adher.carteEtudiant()) == 1 :
f += coul(u"Carte d'étudiant fournie pour l'année scolaire :",'gras') f += coul(u"Carte d'étudiant fournie pour l'année scolaire :",'gras')
else : else :
f += coul(u"Carte d'étudiant fournie pour les années scolaires :",'gras') f += coul(u"Carte d'étudiant fournie pour les années scolaires :",'gras')
g = u'' g = u''
for an in adher.carteEtudiant() : g += u" %i-%i" % ( an, an+1 ) for an in adher.carteEtudiant() : g += u" %i-%i" % ( an, an+1 )
if len(g) > 25 : f += '\n\t' if len(g) > 25 : f += '\n\t'
@ -521,7 +521,7 @@ def adher_details(adher) :
clients_ipsec = None clients_ipsec = None
def ipsec_ok(machine) : def ipsec_ok(machine) :
"""Indique si une machine est correctement authentifiée""" """Indique si une machine est correctement authentifiée"""
prefix="" prefix=""
if hostname != "ragnarok": if hostname != "ragnarok":
if not os.path.isfile("/usr/scripts/gestion/clef-encap"): if not os.path.isfile("/usr/scripts/gestion/clef-encap"):
@ -535,7 +535,7 @@ def ipsec_ok(machine) :
def machine_details(machine) : def machine_details(machine) :
""" """
Formatage du détail des propriétés d'une machine Formatage du détail des propriétés d'une machine
""" """
f = '' f = ''
f+= coul(u'mid=%s ' % machine.id(),'bleu') f+= coul(u'mid=%s ' % machine.id(),'bleu')
@ -557,10 +557,10 @@ def machine_details(machine) :
f+= coul(u'IP : ','gras') + "%s\t\t" %machine.ip() f+= coul(u'IP : ','gras') + "%s\t\t" %machine.ip()
f+= coul(u'MAC : ','gras') + "%s\n" %machine.mac() f+= coul(u'MAC : ','gras') + "%s\n" %machine.mac()
# Propriétaire # Propriétaire
f+= coul(u'Propriétaire : ','gras') f+= coul(u'Propriétaire : ','gras')
try : try :
f += machine.proprio + coul(' (adhérent détruit)', 'jaune') f += machine.proprio + coul(' (adhérent détruit)', 'jaune')
a = AssociationCrans() a = AssociationCrans()
except : except :
a = machine.proprietaire() a = machine.proprietaire()
@ -579,10 +579,10 @@ def machine_details(machine) :
f += coul(u'Nombre de prises : ', 'gras') f += coul(u'Nombre de prises : ', 'gras')
f += "%d\n" % n f += "%d\n" % n
# Adhérent blacklisté ? # Adhérent blacklisté ?
bl = a.blacklist_actif() bl = a.blacklist_actif()
if bl : if bl :
f += coul(u'Restrictions sur adhérent : ','gras') f += coul(u'Restrictions sur adhérent : ','gras')
f += coul(u', '.join(bl),'rouge') f += coul(u', '.join(bl),'rouge')
f += '\n' f += '\n'
@ -592,8 +592,8 @@ def machine_details(machine) :
f += machine.hotspot() and 'oui' or 'non' f += machine.hotspot() and 'oui' or 'non'
position = machine.position() position = machine.position()
if position: if position:
f += coul(u'\t\t\tCoordonnées : ', 'gras') f += coul(u'\t\t\tCoordonnées : ', 'gras')
f += u'%s°N, %s°E\n' % position f += u'%s°N, %s°E\n' % position
else: else:
f += '\n' f += '\n'
@ -608,7 +608,7 @@ def machine_details(machine) :
f += coul(u'Puissance : ','gras') + u"%4.d" % int(machine.puissance()) f += coul(u'Puissance : ','gras') + u"%4.d" % int(machine.puissance())
f += coul(u'\tCanaux : ', 'gras') + machine.canal() f += coul(u'\tCanaux : ', 'gras') + machine.canal()
f += coul(u'\tÉtat : ', 'gras') f += coul(u'\tÉtat : ', 'gras')
if borne_etat(machine.nom()): if borne_etat(machine.nom()):
f += coul(u'borne active', 'vert') f += coul(u'borne active', 'vert')
f += '\n' f += '\n'
@ -621,7 +621,7 @@ def machine_details(machine) :
if clients and base: if clients and base:
f += coul(u'Clients : \n','gras') f += coul(u'Clients : \n','gras')
for (client, rssi) in clients: for (client, rssi) in clients:
# On va chercher le nom correspondant à l'adresse MAC # On va chercher le nom correspondant à l'adresse MAC
res = base.search("mac=%s" % client)['machine'] res = base.search("mac=%s" % client)['machine']
authentification="" authentification=""
if not res: if not res:
@ -630,7 +630,7 @@ def machine_details(machine) :
else: else:
client_nom = ", ".join(["%s [%s]" % (x.nom().split(".")[0], client_nom = ", ".join(["%s [%s]" % (x.nom().split(".")[0],
x.proprietaire().Nom()) for x in res]) x.proprietaire().Nom()) for x in res])
# On va regarder si le client est authentifié # On va regarder si le client est authentifié
auth_ok = ipsec_ok(x) auth_ok = ipsec_ok(x)
if auth_ok != None: if auth_ok != None:
if auth_ok: if auth_ok:
@ -649,7 +649,7 @@ def machine_details(machine) :
coul("%d" % rssi, coul_rssi), coul("%d" % rssi, coul_rssi),
authentification) authentification)
else: else:
f += coul(u'borne éteinte','rouge') f += coul(u'borne éteinte','rouge')
f += '\n' f += '\n'
if machine.nvram(): if machine.nvram():
f += coul(u'NVRAM : ', 'gras') f += coul(u'NVRAM : ', 'gras')
@ -659,7 +659,7 @@ def machine_details(machine) :
f += coul(u'Clef IPsec : ','gras') + machine.ipsec() f += coul(u'Clef IPsec : ','gras') + machine.ipsec()
f += '\n' f += '\n'
# Ports spéciaux # Ports spéciaux
if machine.portTCPin(): if machine.portTCPin():
f += coul(u'Ports TCP ouvert ext->machine : ','gras') + ' '.join(machine.portTCPin()) + '\n' f += coul(u'Ports TCP ouvert ext->machine : ','gras') + ' '.join(machine.portTCPin()) + '\n'
if machine.portTCPout(): if machine.portTCPout():
@ -671,7 +671,7 @@ def machine_details(machine) :
# Exemption d'upload # Exemption d'upload
if machine.exempt() : if machine.exempt() :
f += coul(u'Upload exempté vers : ','gras') + ', '.join(machine.exempt()) + '\n' f += coul(u'Upload exempté vers : ','gras') + ', '.join(machine.exempt()) + '\n'
f += _blacklist(machine) f += _blacklist(machine)
f += _info(machine) f += _info(machine)
@ -681,7 +681,7 @@ def machine_details(machine) :
def club_details(club) : def club_details(club) :
""" """
Affichage du détail des propriétés d'un club Affichage du détail des propriétés d'un club
""" """
f='' f=''
# Cid # Cid
@ -697,16 +697,16 @@ def club_details(club) :
f += (coul(u'Imprimeurs : ', 'gras') + "%s\n" % ', '.join(map(lambda x: f += (coul(u'Imprimeurs : ', 'gras') + "%s\n" % ', '.join(map(lambda x:
club.search("aid=%s" % x)['adherent'][0].Nom(), club.imprimeurs()))) club.search("aid=%s" % x)['adherent'][0].Nom(), club.imprimeurs())))
# État administratif # État administratif
f += coul(u'État administratif : ','gras') f += coul(u'État administratif : ','gras')
jour=1 jour=1
if ann_scol not in club.paiement() : if ann_scol not in club.paiement() :
if not jour : f += ' et ' if not jour : f += ' et '
f += coul(u"charte %s/%d non signée"% (ann_scol, ann_scol+1 ),'violet') f += coul(u"charte %s/%d non signée"% (ann_scol, ann_scol+1 ),'violet')
jour = 0 jour = 0
if jour : if jour :
f += coul(u"à jour",'vert') f += coul(u"à jour",'vert')
f += '\n' f += '\n'
# Chambre + prise # Chambre + prise
@ -721,7 +721,7 @@ def club_details(club) :
# Paiement # Paiement
if club.paiement() : if club.paiement() :
f += coul(u'Charte signée pour les années scolaires :','gras') f += coul(u'Charte signée pour les années scolaires :','gras')
g = '' g = ''
for an in club.paiement() : g += " %i-%i" % ( an, an+1 ) for an in club.paiement() : g += " %i-%i" % ( an, an+1 )
if len(g) > 35 : f += '\n\t' if len(g) > 35 : f += '\n\t'
@ -762,7 +762,7 @@ def club_details(club) :
return f return f
########################################### ###########################################
# Fonctions annexes de formatage de données # Fonctions annexes de formatage de données
def _blacklist(clas): def _blacklist(clas):
""" Formatage blackliste de la classe fournie """ """ Formatage blackliste de la classe fournie """
@ -776,7 +776,7 @@ def _blacklist(clas):
event = event.split('$') event = event.split('$')
dates = strftime('%d/%m/%Y %H:%M', localtime(int(event[0]))) dates = strftime('%d/%m/%Y %H:%M', localtime(int(event[0])))
if event[1] == '-': if event[1] == '-':
dates = u'à partir du %s' % dates dates = u'à partir du %s' % dates
else: else:
dates = u'du %s au ' % dates dates = u'du %s au ' % dates
dates += strftime('%d/%m/%Y %H:%M', localtime(int(event[1]))) dates += strftime('%d/%m/%Y %H:%M', localtime(int(event[1])))
@ -836,14 +836,14 @@ def __bases_machines(m) :
elif isinstance(m, BorneWifi): t = 'born' elif isinstance(m, BorneWifi): t = 'born'
else : t='fixe' else : t='fixe'
# Déconnectée ? # Déconnectée ?
b = m.blacklist_actif() b = m.blacklist_actif()
if not b : if not b :
bl = '-' bl = '-'
elif len(b) == 1 : elif len(b) == 1 :
bl = coul(b[0],'rouge') bl = coul(b[0],'rouge')
else : else :
bl = coul(u'cf détails','rouge') bl = coul(u'cf détails','rouge')
return t , bl return t , bl
@ -859,14 +859,14 @@ def borne_etat(borne) :
return False return False
def borne_clients_canal(borne) : def borne_clients_canal(borne) :
"""Renvoie la liste des adresses MAC associées à la borne ainsi que le canal. """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 Chaque adresse MAC est en fait contenue dans un couple comprenant
l'adresse MAC et le RSSI du client associé. l'adresse MAC et le RSSI du client associé.
On en profite pour renvoyer également le canal en cours de la 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 borne. On fait cela dans la même fonction car cela évite de faire
deux connexions ssh (ce qui est fort coûteux). deux connexions ssh (ce qui est fort coûteux).
Au final, on renvoie un dictionnaire Au final, on renvoie un dictionnaire
- mac-rssi: une liste de couples (MAC, RSSI) - mac-rssi: une liste de couples (MAC, RSSI)
@ -894,18 +894,18 @@ def borne_clients_canal(borne) :
return {"canal": canal, "mac-rssi": macs} return {"canal": canal, "mac-rssi": macs}
def prise_etat(chbre) : def prise_etat(chbre) :
""" Retoune un doublet contenant l'état de la prise associée à la chbre et les VLANs actives""" """ Retoune un doublet contenant l'état de la prise associée à la chbre et les VLANs actives"""
f = u'' f = u''
vlans = u'' vlans = u''
try: try:
# On met aussi l'état # On met aussi l'état
from hptools import sw_chbre, ConversationError from hptools import sw_chbre, ConversationError
prise = sw_chbre(chbre) prise = sw_chbre(chbre)
vlans += ', '.join(prise.vlans()) vlans += ', '.join(prise.vlans())
f += u'prise %s' % prise.prise_brute f += u'prise %s' % prise.prise_brute
rows, cols = get_screen_size() rows, cols = get_screen_size()
if prise.is_up() : if prise.is_up() :
f += u', ' + coul(u'machine branchée','vert') f += u', ' + coul(u'machine branchée','vert')
reste_cols = cols - 45 reste_cols = cols - 45
if prise.eth_mode().find('10Mbits')!=-1 : if prise.eth_mode().find('10Mbits')!=-1 :
f+= u', ' + coul(u'prise en 10Mbps','jaune') f+= u', ' + coul(u'prise en 10Mbps','jaune')
@ -914,15 +914,15 @@ def prise_etat(chbre) :
macs = prise.show_prise_mac() macs = prise.show_prise_mac()
if len(macs) == 0: if len(macs) == 0:
if reste_cols < 20 : if reste_cols < 20 :
# Faut aller à la ligne # Faut aller à la ligne
f += u'\n ' f += u'\n '
f += coul(u'aucune MAC détectée', 'jaune') f += coul(u'aucune MAC détectée', 'jaune')
else: else:
if len(macs) == 1 and reste_cols > 25 : if len(macs) == 1 and reste_cols > 25 :
# Une seule mac et on a assez de place # Une seule mac et on a assez de place
f += u"MAC: %s" % macs[0] f += u"MAC: %s" % macs[0]
else : else :
# On va à la ligne # On va à la ligne
# Combien d'adresses MAC peut-on mettre par ligne ? # Combien d'adresses MAC peut-on mettre par ligne ?
# Une adresse MAC =~ 20 caracteres # Une adresse MAC =~ 20 caracteres
cols -= 17 # On met 15espaces devant chaque ligne cols -= 17 # On met 15espaces devant chaque ligne
@ -936,9 +936,9 @@ def prise_etat(chbre) :
f += u"%s" % macs.pop() f += u"%s" % macs.pop()
count += 1 count += 1
elif not prise.is_enable() : elif not prise.is_enable() :
f+= u', ' + coul(u'prise désactivée','rouge') f+= u', ' + coul(u'prise désactivée','rouge')
else : else :
f+= u', activée, lien non détecté' f+= u', activée, lien non détecté'
except ConversationError, r: except ConversationError, r:
# Switch non manageable ou down # Switch non manageable ou down
f += ', ' f += ', '
@ -956,7 +956,7 @@ def prise_etat(chbre) :
return f, vlans return f, vlans
############################################################################## ##############################################################################
## Partie dévolue au système de recherche ## Partie dévolue au système de recherche
def __usage_brief(err='') : def __usage_brief(err='') :
""" Message d'erreur """ """ Message d'erreur """
@ -1004,7 +1004,7 @@ def __usage() :
accu = champ accu = champ
longueur = len(champ) longueur = len(champ)
# Dernière ligne # Dernière ligne
liste.append(accu) liste.append(accu)
cprint(__doc__ % { 'prog': sys.argv[0].split('/')[-1].split('.')[0], cprint(__doc__ % { 'prog': sys.argv[0].split('/')[-1].split('.')[0],
@ -1015,11 +1015,11 @@ def __usage() :
def __recherche() : def __recherche() :
""" """
Recherche et affichage des résultats à partir des options founies (sys.argv) Recherche et affichage des résultats à partir des options founies (sys.argv)
""" """
global aff_ipsec, limit_aff_details, limit_aff_historique, debug global aff_ipsec, limit_aff_details, limit_aff_historique, debug
# Récupération des options # Récupération des options
if len(sys.argv) == 1 : if len(sys.argv) == 1 :
# Pas d'option fournie # Pas d'option fournie
__usage_brief() __usage_brief()
@ -1045,37 +1045,37 @@ def __recherche() :
# Mode debug # Mode debug
debug = 1 debug = 1
elif opt == '-l' or opt =='--limit': elif opt == '-l' or opt =='--limit':
# Passage mode condensé, mode détaillé # Passage mode condensé, mode détaillé
try : limit_aff_details = int(val) try : limit_aff_details = int(val)
except : except :
__usage_brief(u'Valeur du paramètre %s incorecte (doit être un entier positif)' % opt) __usage_brief(u'Valeur du paramètre %s incorecte (doit être un entier positif)' % opt)
elif opt == '-L' or opt =='--limit-historique': elif opt == '-L' or opt =='--limit-historique':
# Limitation du nombre de lignes d'historique # Limitation du nombre de lignes d'historique
try : limit_aff_historique = int(val) try : limit_aff_historique = int(val)
except : except :
__usage_brief(u'Valeur du paramètre %s incorecte (doit être un entier positif)' % opt) __usage_brief(u'Valeur du paramètre %s incorecte (doit être un entier positif)' % opt)
elif opt in [ '-a', '--adherent' ] : elif opt in [ '-a', '--adherent' ] :
only_adh = 1 only_adh = 1
cprint(u"Affichage limité aux adhérents.") cprint(u"Affichage limité aux adhérents.")
elif opt in [ '-m', '--machine' ] : elif opt in [ '-m', '--machine' ] :
only_mac = 1 only_mac = 1
cprint(u"Affichage limité aux machines.") cprint(u"Affichage limité aux machines.")
elif opt in [ '-c', '--club' ] : elif opt in [ '-c', '--club' ] :
only_club = 1 only_club = 1
cprint(u"Affichage limité aux clubs.") cprint(u"Affichage limité aux clubs.")
elif opt == '--crans' : elif opt == '--crans' :
only_crans = 1 only_crans = 1
mtech = 1 mtech = 1
cprint(u"Affichage limité aux machines du crans.") cprint(u"Affichage limité aux machines du crans.")
elif opt in [ '-b', '--bornes' ] : elif opt in [ '-b', '--bornes' ] :
only_bornes = 1 only_bornes = 1
cprint(u"Affichage limité aux bornes wifi.") cprint(u"Affichage limité aux bornes wifi.")
# On va tenter de limiter un peu la recherche # On va tenter de limiter un peu la recherche
if not arg : if not arg :
# Recherche initiale sans critère # Recherche initiale sans critère
arg = [ 'canal=*&host=*.crans.org'] arg = [ 'canal=*&host=*.crans.org']
elif arg[0].find('=')!=-1 : elif arg[0].find('=')!=-1 :
# Recherche avec critères # Recherche avec critères
arg += [ '&canal=*' ] arg += [ '&canal=*' ]
elif opt in [ '-t', '--tech' ] : elif opt in [ '-t', '--tech' ] :
# Format affichage des machines # Format affichage des machines
@ -1085,13 +1085,13 @@ def __recherche() :
aff_ipsec = 1 aff_ipsec = 1
if only_adh + only_mac + only_club + only_bornes > 1 : if only_adh + only_mac + only_club + only_bornes > 1 :
__usage_brief(u'Options utilisées incompatibles') __usage_brief(u'Options utilisées incompatibles')
arg = ' '.join(arg) arg = ' '.join(arg)
# Cas particulier de recherche sur prise # Cas particulier de recherche sur prise
if arg.count('=') == 1 and arg.split('=')[0] == 'prise' : if arg.count('=') == 1 and arg.split('=')[0] == 'prise' :
prise = arg.split('=')[1] prise = arg.split('=')[1]
# Récupération de la chambre # Récupération de la chambre
try: try:
from annuaires import reverse from annuaires import reverse
chbre = reverse(prise[0].lower())[prise[1:]] chbre = reverse(prise[0].lower())[prise[1:]]
@ -1103,7 +1103,7 @@ def __recherche() :
if chbre: if chbre:
if len(chbre) != 1 : if len(chbre) != 1 :
cprint(u"Prise correspondante à plusieurs chambres %s" % ' '.join(chbre)) cprint(u"Prise correspondante à plusieurs chambres %s" % ' '.join(chbre))
return return
# On fait la recherche sur la chambre # On fait la recherche sur la chambre
chbre= prise[0] + chbre[0] chbre= prise[0] + chbre[0]
@ -1122,21 +1122,21 @@ def __recherche() :
except ValueError, c : except ValueError, c :
__usage_brief(c.args[0]) __usage_brief(c.args[0])
# Traitement du résultat # Traitement du résultat
if not res['adherent'] and not res['machine'] and not res['club']: if not res['adherent'] and not res['machine'] and not res['club']:
# Pas de résultat dans la base # Pas de résultat dans la base
# Recherche sur chambre ? # Recherche sur chambre ?
if arg.count('=') == 1 and arg.split('=')[0] == 'chbre' : if arg.count('=') == 1 and arg.split('=')[0] == 'chbre' :
# Affichage des infos de la chambre # Affichage des infos de la chambre
chbre = arg.split('=')[1] chbre = arg.split('=')[1]
cprint(u"Chambre %s inoccupée ou invalide (%s)" % (chbre,prise_etat(chbre)[0])) cprint(u"Chambre %s inoccupée ou invalide (%s)" % (chbre,prise_etat(chbre)[0]))
else : else :
cprint(u"Aucun résultat trouvé.") cprint(u"Aucun résultat trouvé.")
sys.exit(3) sys.exit(3)
# L'affichage souhaité a été précisé ? # L'affichage souhaité a été précisé ?
elif only_bornes : elif only_bornes :
if not res['machine'] : if not res['machine'] :
cprint(u'Aucun résultat à afficher') cprint(u'Aucun résultat à afficher')
sys.exit(4) sys.exit(4)
else : else :
if len(res['machine']) > limit_aff_details : if len(res['machine']) > limit_aff_details :
@ -1154,11 +1154,11 @@ def __recherche() :
traite.append(a.id()) traite.append(a.id())
to_aff.append(m.proprietaire()) to_aff.append(m.proprietaire())
if not(to_aff) : if not(to_aff) :
cprint(u'Aucun résultat à afficher') cprint(u'Aucun résultat à afficher')
sys.exit(4) sys.exit(4)
aff(to_aff) aff(to_aff)
elif res['club'] : elif res['club'] :
cprint(u'Aucun résultat à afficher') cprint(u'Aucun résultat à afficher')
sys.exit(4) sys.exit(4)
elif only_mac : elif only_mac :
if res['machine'] : aff(res['machine'],mtech) if res['machine'] : aff(res['machine'],mtech)
@ -1179,22 +1179,22 @@ def __recherche() :
traite.append(a.id()) traite.append(a.id())
to_aff.append(m.proprietaire()) to_aff.append(m.proprietaire())
if not(to_aff) : if not(to_aff) :
cprint(u'Aucun résultat à afficher') cprint(u'Aucun résultat à afficher')
sys.exit(4) sys.exit(4)
aff(to_aff) aff(to_aff)
elif res['adherent'] : elif res['adherent'] :
cprint(u'Aucun résultat à afficher') cprint(u'Aucun résultat à afficher')
sys.exit(4) sys.exit(4)
# Non : on affiche tout. # Non : on affiche tout.
else : else :
if res['adherent'] : if res['adherent'] :
cprint(u"Résultats trouvés parmi les adhérents :", 'cyan') cprint(u"Résultats trouvés parmi les adhérents :", 'cyan')
aff(res['adherent']) aff(res['adherent'])
if res['machine'] : if res['machine'] :
cprint(u"Résultats trouvés parmi les machines :", 'cyan') cprint(u"Résultats trouvés parmi les machines :", 'cyan')
aff(res['machine'],mtech) aff(res['machine'],mtech)
if res['club']: if res['club']:
cprint(u"Résultats trouvés parmi les clubs :", 'cyan') cprint(u"Résultats trouvés parmi les clubs :", 'cyan')
aff(res['club']) aff(res['club'])
if __name__ == '__main__' : if __name__ == '__main__' :
@ -1214,12 +1214,12 @@ if __name__ == '__main__' :
# Fin # Fin
sys.exit(c) sys.exit(c)
except : except :
cprint(u"""Une erreur fatale s'est produite durant l'exécution. cprint(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 Pour l'amélioration de ce programme merci de prévenir nounou en spécifiant la
marche à suivre pour reproduire cette erreur.""") marche à suivre pour reproduire cette erreur.""")
if debug : if debug :
cprint('-'*40) cprint('-'*40)
cprint(u'Détails techniques :') cprint(u'Détails techniques :')
import traceback import traceback
# On veut le traceback sur la sortie standard # On veut le traceback sur la sortie standard
sys.stderr = sys.stdout sys.stderr = sys.stdout