Import initial !
darcs-hash:20040831131446-d1718-0734aa73d3b8481b3b4b861e447e85128e488e8a.gz
This commit is contained in:
parent
c9083dfd86
commit
6626a44f15
20 changed files with 6494 additions and 0 deletions
164
gestion/affich_tools.py
Executable file
164
gestion/affich_tools.py
Executable file
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
""" Collection de fonction/classe pour avoir un bel affichage
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
import sys, sre, os, tempfile
|
||||
|
||||
def dialog(backtitle,arg) :
|
||||
""" Affiche la boite de dialogue défine avec les arguments fournis
|
||||
(cf man dialog)
|
||||
si tout se déroule bien retourne :
|
||||
[ 0, [ reponse(s) ] ]
|
||||
si annulatin retourne :
|
||||
[ 1, [] ]
|
||||
si appui sur ESC demande confirmation de l'abandon et exécute sys.exit(0)
|
||||
si erreur dans les arguments raise RuntimeError
|
||||
"""
|
||||
f = tempfile.NamedTemporaryFile()
|
||||
cmd = u'/usr/bin/dialog --backtitle "%s" --cancel-label "Retour" %s 2>%s' % (backtitle,arg,f.name)
|
||||
res = os.system(cmd.encode('iso-8859-15','ignore'))
|
||||
|
||||
if res == 256 :
|
||||
# Annuler
|
||||
f.close()
|
||||
return [ 1, [] ]
|
||||
|
||||
# Lecture du fichier de résultat et effacement
|
||||
try:
|
||||
result=f.readlines()
|
||||
f.close()
|
||||
except :
|
||||
result = [ "n'importe quoi", '']
|
||||
res = 65280
|
||||
|
||||
# Traitement
|
||||
if res==65280 and result:
|
||||
# Erreur dans les arguments
|
||||
raise RuntimeError( arg, result[1].strip() )
|
||||
elif res==65280 :
|
||||
# Appui sur ESC
|
||||
arg1 = u'--title "Annulation" --yesno "Quitter ?\nLes dernières modifications seront perdues." 6 48'
|
||||
print backtitle
|
||||
cmd = u'/usr/bin/dialog --backtitle "%s" %s' % (backtitle,arg1)
|
||||
res = os.system(cmd.encode('iso-8859-15','ignore') )
|
||||
if res==0 : sys.exit(0)
|
||||
else : return dialog(backtitle,arg)
|
||||
elif not result : result=['']
|
||||
|
||||
return [ 0, result ]
|
||||
|
||||
def coul(txt,col):
|
||||
"""
|
||||
Retourne la chaine donnée encadrée des séquences qui
|
||||
vont bien pour obtenir la couleur souhaitée
|
||||
Les couleur sont celles de codecol
|
||||
Il est possible de changer la couleur de fond grace aux couleur f_<couleur>
|
||||
"""
|
||||
codecol={'rouge' : 31 , 'vert' : 32 , 'jaune' : 33 , 'bleu': 34 , 'violet' : 35 , 'cyan' : 36 , 'gras' : 50}
|
||||
try :
|
||||
if col[:2]=='f_' : add=10; col=col[2:]
|
||||
else : add=0
|
||||
txt = "\033[1;%sm%s\033[1;0m" % (codecol[col]+add,txt)
|
||||
finally :
|
||||
return txt
|
||||
|
||||
OK = coul('OK','vert')
|
||||
WARNING = coul('WARNING','jaune')
|
||||
ERREUR = coul('ERREUR','rouge')
|
||||
|
||||
def cprint(txt,col):
|
||||
print coul(txt,col)
|
||||
|
||||
def tableau(largeurs,data) :
|
||||
"""
|
||||
retourne une chaine formatée repésentant un tableau
|
||||
largeur est la liste des largeurs des colones
|
||||
data est une liste de tuples :
|
||||
[ ( données entète), (données ligne1), .... ]
|
||||
"""
|
||||
sep_col = u'|'
|
||||
|
||||
# Ligne de séparation entète corps
|
||||
s=u'\n'
|
||||
for l in largeurs :
|
||||
s+= sep_col + u'-'*l
|
||||
s += sep_col + u'\n'
|
||||
|
||||
nb_cols = len(largeurs)
|
||||
|
||||
# Remplissage tableau
|
||||
f=u''
|
||||
for ligne in data :
|
||||
for i in range(0, nb_cols) :
|
||||
f+= sep_col
|
||||
# Centrage
|
||||
l = len(sre.sub('\x1b\[1;([0-9]|[0-9][0-9])m','',ligne[i])) # Longeur sans les chaines de formatage
|
||||
if l >= largeurs[i] :
|
||||
f += ligne[i]
|
||||
else :
|
||||
n = largeurs[i] - l
|
||||
f += u' '*(n/2) + ligne[i] + u' '*(n/2 + n%2)
|
||||
f+= sep_col + u'\n'
|
||||
|
||||
# Final
|
||||
f = f.replace(u'\n',s,1) # Insertion du séparateur entète - corps
|
||||
return f[:-1] # Supression du \n final
|
||||
|
||||
def prompt(prompt, defaut=''):
|
||||
""" Pose la question prompt, retourne la réponse """
|
||||
sys.stdout.write(coul(prompt,'gras'))
|
||||
if defaut :
|
||||
sys.stdout.write(" ["+defaut+"]")
|
||||
sys.stdout.write(" ")
|
||||
v=sys.stdin.readline().strip()
|
||||
if not v : v = defaut
|
||||
return v
|
||||
|
||||
class anim :
|
||||
""" Permet de créer une animation :
|
||||
truc................./
|
||||
truc.................-
|
||||
truc.................\
|
||||
truc.................|
|
||||
ou une barre de progression si le nombre total d'itéraitions est founi.
|
||||
"""
|
||||
def __init__(self,truc,iter=0) :
|
||||
""" Affichage de :
|
||||
truc................."""
|
||||
self.txt = truc + '.'*(40-len(truc))
|
||||
self.c = 1
|
||||
self.iter = iter
|
||||
sys.stdout.write(self.txt)
|
||||
sys.stdout.flush()
|
||||
|
||||
def reinit(self) :
|
||||
""" Efface la ligne courrante et
|
||||
affiche : truc................. """
|
||||
sys.stdout.write('\r' + self.txt)
|
||||
if self.iter :
|
||||
sys.stdout.write(' '*28)
|
||||
sys.stdout.write('\r' + self.txt)
|
||||
sys.stdout.flush()
|
||||
|
||||
def cycle(self) :
|
||||
""" Efface la ligne courrante et
|
||||
affiche : truc..................?
|
||||
? caratère variant à chaque appel """
|
||||
sys.stdout.write('\r' + self.txt)
|
||||
if self.iter!=0 :
|
||||
sys.stdout.write('[')
|
||||
av = float(self.c) / float(self.iter)
|
||||
n = int(20 * av)
|
||||
sys.stdout.write('='*n)
|
||||
sys.stdout.write('>')
|
||||
sys.stdout.write(' '*(20 - n))
|
||||
sys.stdout.write('] %3i%%' % int(100 * av) )
|
||||
else :
|
||||
sys.stdout.write('/-\|'[self.c%4])
|
||||
sys.stdout.flush()
|
||||
self.c += 1
|
508
gestion/annuaires.py
Executable file
508
gestion/annuaires.py
Executable file
|
@ -0,0 +1,508 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: iso8859-15 -*-
|
||||
|
||||
aide={
|
||||
'g' : "appart du RDC=G901" ,
|
||||
'i' : "Chambres 209g + 309g + 105g + 403g + 110d + 312 + 007g +007d + locaux clubs sur prise 150.",
|
||||
'h' : "Chambres 7 et 8 et les locaux clubs sur la prise 046"
|
||||
}
|
||||
|
||||
# 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.
|
||||
|
||||
#Pour le G :
|
||||
# le signe - indique un cable 10 Mbps
|
||||
# et XXX = prise vide
|
||||
#Les chambres G121, G241 et G201 ont chacune 2 cables en 100 Mbps qui
|
||||
#sont branches sur les switchs.
|
||||
|
||||
# Correspondance chbre -> prise
|
||||
chbre_prises={ 'a' :
|
||||
{'101d':'101d' , '101g':'101g' , '102':'102' , '103':'103' ,
|
||||
'104':'104' , '105':'105' , '106':'106' , '107':'107' ,
|
||||
'108':'108' , '109':'109' , '110d':'110d' , '110g':'110g' ,
|
||||
'111d':'111d' , '111g':'111g' , '112d':'112d' , '112g':'112g' ,
|
||||
'113d':'113d' , '113g':'113g' , '114':'114' , '115':'115' ,
|
||||
|
||||
'201d':'201d' , '201g':'201g' , '202':'202' , '203':'203' ,
|
||||
'204':'204' , '205':'205' , '206':'206' , '207':'207' ,
|
||||
'208':'208' , '209':'209' , '210d':'210d' , '210g':'210g' ,
|
||||
'211d':'211d' , '211g':'211g' , '212d':'212d' , '212g':'212g' ,
|
||||
'213d':'213d' , '213g':'213g' , '214':'214' , '215':'215' ,
|
||||
|
||||
'301d':'301d' , '301g':'301g' , '302':'302' , '303':'303' ,
|
||||
'304':'304' , '305':'305' , '306':'306' , '307':'307' ,
|
||||
'308':'308' , '309':'309' , '310d':'310d' , '310g':'310g' ,
|
||||
'311d':'311d' , '311g':'311g' , '312d':'312d' , '312g':'312g' ,
|
||||
'313d':'313d' , '313g':'313g' , '314':'314' , '315':'315' ,
|
||||
|
||||
'401d':'401d' , '401g':'401g' , '402':'402' , '403':'403' ,
|
||||
'404':'404' , '405':'405' , '406':'406' , '407':'407' ,
|
||||
'408':'408' , '409':'409' , '410d':'410d' , '410g':'410g' ,
|
||||
'411d':'411d' , '411g':'411g' , '412d':'412d' , '412g':'412g' ,
|
||||
'413d':'413d' , '413g':'413g' , '414':'414' , '415':'415' ,
|
||||
|
||||
'501d':'501d' , '501g':'501g' , '502d':'502d' , '502g':'502g' ,
|
||||
'503d':'503d' , '503g':'503g' , '504d':'504d' , '504g':'504g' ,
|
||||
'505d':'505d' , '505g':'505g' , '506d':'506d' , '506g':'506g' ,
|
||||
'507d':'507d' , '507g':'507g' , '507d':'507d' , '508g':'508g' ,
|
||||
|
||||
'601d':'601d' , '601g':'601g' , '602d':'602d' , '602g':'602g' ,
|
||||
'603d':'603d' , '603g':'603g' , '604d':'604d' , '604g':'604g' ,
|
||||
'605d':'605d' , '605g':'605g' , '606d':'606d' , '606g':'606g' ,
|
||||
'607d':'607d' , '607g':'607g' , '607d':'607d' , '608g':'608g' } ,
|
||||
|
||||
'b' :
|
||||
{'cl0':'047' , 'cl1':'045' ,
|
||||
'105':'001' , '106':'002' , '107':'003' , '108':'004' ,
|
||||
'120g':'005' , '120d':'006' , '121g':'007' , '121d':'008' ,
|
||||
'205':'009' , '206':'010' , '207':'011' , '208':'012' ,
|
||||
'109':'013' , '110':'014' , '111':'015' , '112':'016' ,
|
||||
'122g':'017' , '122d':'018' , '123':'019' , '124':'020' ,
|
||||
'209':'021' , '210':'022' , '211':'023' , '212':'024' ,
|
||||
'cl6':'025' , 'cl5':'026' , 'cl4':'027' , 'cl3':'028' ,
|
||||
'101g':'029' , '101d':'030' , '102g':'031' , '102d':'032' ,
|
||||
'113':'033' , '114':'034' , '115':'035' , '116':'036' ,
|
||||
'103g':'037' , '103d':'038' , '104g':'039' , '104d':'040' ,
|
||||
'117':'041' , '118':'042' , '119g':'043' , '119d':'044' ,
|
||||
|
||||
'220g':'101' , '220d':'102' , '221g':'103' , '221d':'104' ,
|
||||
'305':'105' , '306':'106' , '307':'107' , '308':'108' ,
|
||||
'320g':'109' , '320d':'110' , '321g':'111' , '321d':'112' ,
|
||||
'222g':'113' , '222d':'114' , '223':'115' , '224':'116' ,
|
||||
'309':'117' , '310':'118' , '311':'119' , '312':'120' ,
|
||||
'322g':'121' , '322d':'122' , '323':'123' , '324':'124' ,
|
||||
'201g':'125' , '201d':'126' , '202g':'127' , '202d':'128' ,
|
||||
'213':'129' , '214':'130' , '215':'131' , '216':'132' ,
|
||||
'301g':'133' , '301d':'134' , '302g':'135' , '302d':'136' ,
|
||||
'203g':'137' , '203d':'138' , '204g':'139' , '204d':'140' ,
|
||||
'217':'141' , '218':'142' , '219g':'143' , '219d':'144' ,
|
||||
'303g':'145' , '303d':'146' , '304g':'147' , '304d':'148' ,
|
||||
|
||||
'405':'201' , '406':'202' , '407':'203' , '408':'204' ,
|
||||
'420g':'205' , '420d':'206' , '421g':'207' , '421d':'208' ,
|
||||
'505g':'209' , '505d':'210' , '506g':'211' , '506d':'212' ,
|
||||
'411':'213' , '412':'214' , '410':'215' , '409':'216' ,
|
||||
'422g':'217' , '422d':'218' , '423':'219' , '424':'220' ,
|
||||
'507g':'221' , '507d':'222' , '508g':'223' , '508d':'224' ,
|
||||
'313':'225' , '314':'226' , '316':'227' , '315':'228' ,
|
||||
'401g':'229' , '401d':'230' , '402g':'231' , '402d':'232' ,
|
||||
'413':'233' , '414':'234' , '415':'235' , '416':'236' ,
|
||||
'317':'237' , '318':'238' , '319g':'239' , '319d':'240' ,
|
||||
'403g':'241' , '403d':'242' , '404g':'243' , '404d':'244' ,
|
||||
'417':'245' , '418':'246' , '419g':'247' , '419d':'248' ,
|
||||
|
||||
'511g':'301' , '511d':'302' , '512g':'303' , '512d':'304' ,
|
||||
'603g':'305' , '603d':'306' , '604g':'307' , '604d':'308' ,
|
||||
'609g':'309' , '609d':'310' , '610g':'311' , '610d':'312' ,
|
||||
'513g':'313' , '513d':'314' , '514g':'315' , '514d':'316' ,
|
||||
'605g':'317' , '605d':'318' , '606g':'319' , '606d':'320' ,
|
||||
'611g':'321' , '611d':'322' , '612g':'323' , '612d':'324' ,
|
||||
'501g':'325' , '501d':'326' , '502g':'327' , '502d':'328' ,
|
||||
'607g':'329' , '607d':'330' , '608g':'331' , '608d':'332' ,
|
||||
'613g':'333' , '613d':'334' , '614g':'335' , '614d':'336' ,
|
||||
'503g':'337' , '503d':'338' , '504g':'339' , '504d':'340' ,
|
||||
'509g':'341' , '509d':'342' , '510g':'343' , '510d':'344' ,
|
||||
'601g':'345' , '601d':'346' , '602g':'347' , '602d':'348' } ,
|
||||
|
||||
'c' :
|
||||
{'312d':'001', '313g':'002' , '313d':'003' , '314':'004' ,
|
||||
'315':'005' , '401g':'006' , '401d':'007' , '402g':'008' ,
|
||||
'402d':'009' , '403g':'010' , '406g':'011' , '406d':'012' ,
|
||||
'407g':'013' , '407d':'014' , '408g':'015' , '408d':'016' ,
|
||||
'409g':'017' , '409d':'018' , '410g':'019' , '410d':'020' ,
|
||||
'411g':'021' , '411d':'022' , '414':'023' , '415':'024' ,
|
||||
'501g':'025' , '501d':'026' , '502':'027' , '503':'028' ,
|
||||
'601g':'029' , '601d':'030' , '602':'031' , '603':'032' ,
|
||||
'403d':'033' , '404g':'034' , '404d':'035' , '412g':'036' ,
|
||||
'412d':'037' , '413g':'038' , '413d':'039' , '405g':'040' ,
|
||||
'405d':'041' , '311d':'042' , '312g':'043' , '311g':'044' ,
|
||||
'310d':'045' , '310g':'046' , '309d':'047' , '309g':'048' ,
|
||||
|
||||
'103d':'101' , '111d':'102' , '103g':'103' , '111g':'104' ,
|
||||
'102d':'105' , '110d':'106' , '102g':'107' , '110g':'108' ,
|
||||
'101d':'109' , '109d':'110' , '101g':'111' , '109g':'112' ,
|
||||
'205d':'113' , '213d':'114' , '307g':'115' , '205g':'116' ,
|
||||
'213g':'117' , '306d':'118' , '204d':'119' , '212d':'120' ,
|
||||
'306g':'121' , '204g':'122' , '212g':'123' , '305d':'124' ,
|
||||
'203d':'125' , '211d':'126' , '305g':'127' , '203g':'128' ,
|
||||
'211g':'129' , '304d':'130' , '104g':'131' , '112g':'132' ,
|
||||
'206g':'133' , '214':'134' , '307d':'135' , '104d':'136' ,
|
||||
'112d':'137' , '105g':'138' , '113g':'139' , '105d':'140' ,
|
||||
'113d':'141' , '106g':'142' , '114g':'143' , '106d':'144' ,
|
||||
'114d':'145' , '107g':'146' , '201g':'147' , '107d':'148' ,
|
||||
|
||||
'304g':'201' , '303d':'202' , '303g':'203' , '210d':'204' ,
|
||||
'210g':'205' , '209d':'206' , '302d':'207' , '209g':'208' ,
|
||||
'208d':'209' , '302g':'210' , '208g':'211' , '301d':'212' ,
|
||||
'207d':'213' , '301g':'214' , '207g':'215' , '308d':'216' ,
|
||||
'206d':'217' , '215':'218' , '308g':'219' , '108d':'220' ,
|
||||
'202d':'221' , '108g':'222' , '202g':'223' , '201d':'224' } ,
|
||||
|
||||
'g' :
|
||||
{'257':'001' , '180':'002-', '183':'003' , '135':'004' ,
|
||||
'298':'005' , '174':'006' , 'XXX':'007-', '138':'008' ,
|
||||
'136':'009' , '127':'010' , '176':'011' , '139':'012-' ,
|
||||
'132':'013' , '172':'014' , '137':'015' , '186':'016' ,
|
||||
'125':'017-', '181':'018' , '128':'019' , '178':'020' ,
|
||||
'175':'021' , '130':'022' , '177':'023' , '185':'024' ,
|
||||
'182':'025' , '131':'026' , '179':'027' , '299':'028' ,
|
||||
'259':'029-', '310':'030' , '300':'031' , '251':'032-' ,
|
||||
'295':'033' , 'XXX':'034-', '306':'035-', '058':'036' ,
|
||||
'304':'037' , '254':'038' , '261':'039' , '002':'040' ,
|
||||
'308':'041-', '252':'042' , '255':'043' , '256':'044' ,
|
||||
'253':'045' , '297':'046' , '260':'047' , '015':'048' ,
|
||||
|
||||
'247':'101-', '301':'102-', '249':'103' , '049':'104' ,
|
||||
'014':'105' , '054':'106' , '061':'107-', '010':'108' ,
|
||||
'005':'109' , '013':'110' , '006':'111' , '008':'112-' ,
|
||||
'009':'113-', 'XXX':'114-', '001':'115-', '052':'116-' ,
|
||||
'012':'117-', '053':'118' , '004':'119' , '066':'120' ,
|
||||
'076':'121' , '118':'122' , '119':'123' , '072':'124' ,
|
||||
'065':'125' , '073':'126' , '114':'127' , '112':'128' ,
|
||||
'123':'129' , '120':'130' , '068':'131' , '113':'132' ,
|
||||
'XXX':'133' , '055':'134' , '117':'135-', '074':'136' ,
|
||||
'063':'137' , '077':'138' , '071':'139' , '111':'140' ,
|
||||
'121':'141' , '901':'142' , '122':'143' , '050':'144' ,
|
||||
'064':'145' , '067':'146' , '115':'147' , '124':'148' ,
|
||||
|
||||
'059':'201' , '258':'202' , '307':'203' , 'XXX':'204' ,
|
||||
'187':'205' , '246':'206-', '190':'207' , '193':'208' ,
|
||||
'195':'209' , '309':'210' , '189':'211' , '242':'212' ,
|
||||
'238':'213' , 'XXX':'214' , '241':'215' , '244':'216-' ,
|
||||
'198':'217-', '199':'218-', '192':'219' , '239':'220' ,
|
||||
'245':'221' , '303':'222' , '305':'223' , '191':'224' ,
|
||||
'XXX':'225' , 'XXX':'226' , 'XXX':'227' , 'XXX':'228' ,
|
||||
'XXX':'229' , 'XXX':'230' , 'XXX':'231' , 'XXX':'232' ,
|
||||
'XXX':'233' , 'XXX':'234' , 'XXX':'235' , 'XXX':'236' ,
|
||||
'XXX':'237' , 'XXX':'238' , 'XXX':'239' , 'XXX':'240' ,
|
||||
'XXX':'241' , 'XXX':'242' , 'XXX':'243' , 'XXX':'244' ,
|
||||
'XXX':'245' , 'XXX':'246' , 'XXX':'247' , 'XXX':'248' ,
|
||||
|
||||
'288':'401' , '204':'402' , '206':'403' , '207':'404-' ,
|
||||
'208':'405' , '210':'406' , '212':'407' , '213':'408-' ,
|
||||
'216':'409' , '217':'410' , '218':'411' , '220':'412' ,
|
||||
'222':'413' , '223':'414' , '224':'415' , '226':'416-' ,
|
||||
'231':'417' , '233':'418' , '234':'419' , '235':'420' ,
|
||||
'236':'421' , '237':'422-', '263':'423' , '264':'424' ,
|
||||
'265':'425' , '266':'426' , '267':'427' , '269':'428' ,
|
||||
'270':'429' , '271':'430' , '272':'431' , '273':'432' ,
|
||||
'274':'433' , '275':'434' , '277':'435' , '279':'436' ,
|
||||
'281':'437' , '282':'438' , '285':'439' , '286':'440' ,
|
||||
'287':'441' , '149':'442' , '289':'443' , '290':'444' ,
|
||||
'291':'445' , '292':'446' , '293':'447' , '221':'448' ,
|
||||
|
||||
'140':'501' , '141':'502' , '142':'503' , '143':'504' ,
|
||||
'XXX':'505' , '147':'506-', '165':'507' , 'XXX':'508' ,
|
||||
'150':'509' , '151':'510' , '152':'511' , '153':'512' ,
|
||||
'154':'513' , '155':'514-', '156':'515' , '157':'516-' ,
|
||||
'158':'517' , '144':'518' , '160':'519' , '161':'520' ,
|
||||
'162':'521-', '163':'522' , '164':'523' , 'XXX':'524' ,
|
||||
'166':'525' , '167':'526-', '168':'527-', '169':'528' ,
|
||||
'280':'529' , '171':'530' , '101':'531' , '173':'532' ,
|
||||
'294':'533' , '026':'534' , '225':'535' , '031':'536' ,
|
||||
'146':'537' , '148':'538' , 'XXX':'539' , 'XXX':'540' ,
|
||||
'XXX':'541' , 'XXX':'541' , 'XXX':'543' , 'XXX':'544' ,
|
||||
'XXX':'545' , '096':'546-' , '903':'547' , '036':'548' ,
|
||||
|
||||
'106':'601-', '229':'602' , 'Med':'603' , '089':'604-' ,
|
||||
'092':'605' , '016':'606' , '017':'607' , '018':'608' ,
|
||||
'019':'609' , '200':'610' , '024':'611' , '025':'612' ,
|
||||
'028':'613' , '030':'614' , '034':'615' , '035':'616-' ,
|
||||
'037':'617' , '038':'618' , '039':'619' , '045':'620-' ,
|
||||
'041':'621' , '042':'622' , '043':'623' , '044':'624' ,
|
||||
'XXX':'625' , '046':'626' , '078':'627-', '079':'628' ,
|
||||
'080':'629' , '081':'630' , '082':'631' , '083':'632-' ,
|
||||
'084':'633' , '085':'634-', '086':'635' , '088':'636-' ,
|
||||
'090':'637' , '091':'638' , '095':'639' , '097':'640-' ,
|
||||
'103':'641' , '102':'642' , '107':'643-', '109':'644' ,
|
||||
'227':'645' , '201':'646' , '202':'647' , '203':'648' } ,
|
||||
|
||||
'h' :
|
||||
{'007g':'046' , '007d':'046' , '008g':'046' , '008d':'046' ,
|
||||
'cl2':'046' , 'cl3':'046' , 'cl4':'046' , 'cl1':'046' ,
|
||||
'004g':'046' ,
|
||||
|
||||
'301':'101' , '302':'103' , '303':'105' , '304':'107' ,
|
||||
'305':'109' , '306':'111' , '307':'113' , '308':'115' ,
|
||||
'309g':'117' , '309d':'119' , '310g':'121' , '310d':'123' ,
|
||||
'311g':'125' , '311d':'127' , '312':'129' , '313':'131' ,
|
||||
'314':'133' , '315':'135' , '316':'137' , '317':'139' ,
|
||||
'318':'141' , '319':'143' ,
|
||||
|
||||
'401g':'102' , '401d':'104' , '402g':'106' , '402d':'108' ,
|
||||
'403g':'110' , '403d':'112' , '404g':'114' , '404d':'116' ,
|
||||
'405g':'118' , '405d':'120' , '406g':'122' , '406d':'124' ,
|
||||
'407g':'126' , '407d':'128' , '408g':'130' , '408d':'132' ,
|
||||
'409g':'134' , '409d':'136' , '410g':'138' , '410d':'140' ,
|
||||
'411g':'142' , '411d':'144' ,
|
||||
|
||||
'101g':'001' , '101d':'003' , '102g':'005' , '102d':'007' ,
|
||||
'103g':'009' , '103d':'011' , '104g':'013' , '104d':'015' ,
|
||||
'105g':'017' , '105d':'019' , '106g':'021' , '106d':'023' ,
|
||||
'107g':'025' , '107d':'027' , '108g':'029' , '108d':'031' ,
|
||||
'109g':'033' , '109d':'035' , '110g':'037' , '110d':'039' ,
|
||||
|
||||
'001g':'041' , '001d':'043' , '003g':'045' , '003d':'047' ,
|
||||
'004d':'048' , '005g':'145' , '005d':'147' , '006g':'146' ,
|
||||
'006d':'148' ,
|
||||
|
||||
'201':'002' , '202':'004' , '203':'006' , '204':'008' ,
|
||||
'205':'010' , '206':'012' , '207':'014' , '208':'016' ,
|
||||
'209g':'018' , '209d':'020' , '210g':'022' , '210d':'024' ,
|
||||
'211g':'026' , '211d':'028' , '212':'030' , '213':'032' ,
|
||||
'214':'034' , '215':'036' , '216':'038' , '217':'040' ,
|
||||
'218':'042' , '219':'044' } ,
|
||||
|
||||
'i' :
|
||||
{'110d':'150' , '403g':'150' , '105g':'150' , '209g':'150' ,
|
||||
'309g':'150' , '312':'150' , 'cl2':'150' , 'cl3':'150' ,
|
||||
'cl4':'150' , 'cl1':'150' , '007g':'150' , '007d':'150' ,
|
||||
|
||||
'009d':'102' , '009g':'101' , '008d':'103' , '005d':'104' ,
|
||||
'008g':'105' , '005g':'106' , '006d':'107' , '004d':'108' ,
|
||||
'006g':'109' , '004g':'110' , '001g':'147' , '001d':'148' ,
|
||||
'002g':'145' , '002d':'146' , '003g':'143' , '003d':'144' ,
|
||||
|
||||
'107g':'114' , '103g':'111' , '106d':'112' , '102d':'128' ,
|
||||
'106g':'129' , '102g':'131' , '105d':'130' , '101d':'132' ,
|
||||
'101g':'133' , '103d':'134' , '107d':'135' , '104g':'136' ,
|
||||
'108g':'137' , '104d':'138' , '108d':'139' , '109g':'140' ,
|
||||
'109d':'141' , '110g':'142' ,
|
||||
|
||||
'217':'044' , '216':'041' , '213':'047' , '206':'125' ,
|
||||
'215':'043' , '208':'046' , '214':'045' , '207':'048' ,
|
||||
'212':'123' , '205':'124' , '211d':'126' , '204':'127' ,
|
||||
'211g':'121' , '203':'122' , '210d':'119' , '202':'120' ,
|
||||
'210g':'117' , '201':'118' , '209d':'115' , '219':'116' ,
|
||||
'218':'113' ,
|
||||
|
||||
'315':'034' , '308':'035' , '314':'036' , '307':'037' ,
|
||||
'313':'038' , '306':'040' , '305':'039' , '311d':'042' ,
|
||||
'304':'009' , '311g':'010' , '303':'008' , '302':'006' ,
|
||||
'310d':'004' , '310g':'002' , '301':'007' , '309d':'005' ,
|
||||
'319':'003' , '318':'001' , '317':'032' , '316':'033' ,
|
||||
|
||||
'405g':'021' , '411g':'022' , '405d':'019' , '411d':'020' ,
|
||||
'401g':'018' , '406g':'017' , '406d':'015' , '401d':'016' ,
|
||||
'407g':'013' , '402g':'014' , '402d':'012' , '407d':'011' ,
|
||||
'410d':'023' , '410g':'024' , '409d':'025' , '404d':'026' ,
|
||||
'404g':'028' , '409g':'027' , '408d':'029' , '403d':'030' ,
|
||||
'408g':'031' } ,
|
||||
|
||||
'j' :
|
||||
{'002d':'002d' , '002g':'002g' , '003d':'003d' , '003g':'003g' ,
|
||||
'004d':'004d' , '004g':'004g' , '005d':'005d' , '005g':'005g' ,
|
||||
|
||||
'101d':'101d' , '101g':'101g' , '102d':'102d' , '102g':'102g' ,
|
||||
'103d':'103d' , '103g':'103g' , '104d':'104d' , '104g':'104g' ,
|
||||
'105d':'105d' , '105g':'105g' , '106d':'106d' , '106g':'106g' ,
|
||||
'107d':'107d' , '107g':'107g' , '108d':'108d' , '108g':'108g' ,
|
||||
'109d':'109d' , '109g':'109g' , '110d':'110d' , '110g':'110g' ,
|
||||
'111d':'111d' , '111g':'111g' , '112d':'112d' , '112g':'112g' ,
|
||||
|
||||
'201':'201' , '202':'202' , '203':'203' , '204':'204' ,
|
||||
'205':'205' , '206':'206' , '207':'207' , '208':'208' ,
|
||||
'209':'209' , '210':'210' , '211d':'211d' , '211g':'211g' ,
|
||||
'212d':'212d' , '212g':'212g' , '213d':'213d' , '213g':'213g' ,
|
||||
'214':'214' , '215':'215' , '216':'216' , '217':'217' ,
|
||||
'218':'218' , '219':'219' , '220':'220' , '221':'221' ,
|
||||
'222':'222' , '223':'223' ,
|
||||
|
||||
'301':'301' , '302':'302' , '303':'303' , '304':'304' ,
|
||||
'305':'305' , '306':'306' , '307':'307' , '308':'308' ,
|
||||
'309':'309' , '310':'310' , '311d':'311d' , '311g':'311g' ,
|
||||
'312d':'312d' , '312g':'312g' , '313d':'313d' , '313g':'313g' ,
|
||||
'314':'314' , '315':'315' , '316':'316' , '317':'317' ,
|
||||
'318':'318' , '319':'319' , '320':'320' , '321':'321' ,
|
||||
'322':'322' , '323':'323' ,
|
||||
|
||||
'401d':'401d' , '401g':'401g' , '402d':'402d' , '402g':'402g' ,
|
||||
'403d':'403d' , '403g':'403g' , '404d':'404d' , '404g':'404g' ,
|
||||
'405d':'405d' , '405g':'405g' , '406d':'406d' , '406g':'406g' ,
|
||||
'407d':'407d' , '407g':'407g' , '408d':'408d' , '408g':'408g' ,
|
||||
'409d':'409d' , '409g':'409g' , '410d':'410d' , '410g':'410g' ,
|
||||
'411d':'411d' , '411g':'411g' , '412d':'412d' , '412g':'412g' ,
|
||||
'413d':'413d' , '413g':'413g' } ,
|
||||
|
||||
'm' :
|
||||
{'001':'001' , '002':'002' , '003':'003' , '004':'004' ,
|
||||
'005':'005' , '006':'006' ,
|
||||
|
||||
'101':'101' , '102':'102' , '103':'103' , '104':'104' ,
|
||||
'105':'105' , '106':'106' , '106b':'106b' , '107':'107' ,
|
||||
'108':'108' , '109':'109' , '110':'110' , '111':'111' ,
|
||||
'112':'112' , '113':'113' , '114':'114' , '115':'115' ,
|
||||
'116':'116' , '117':'117' , '118':'118' , '119':'119' ,
|
||||
'120':'120' , '121':'121' , '122':'122' , '123':'123' ,
|
||||
'124':'124' , '125':'125' , '126':'126' , '127':'127' ,
|
||||
'128':'128' , '129':'129' , '130':'130' , '131':'131' ,
|
||||
'132':'132' , '133':'133' , '134':'134' , '135':'135' ,
|
||||
'136':'136' , '137':'137' , '138':'138' , '138b':'138b' ,
|
||||
'139':'101' , '140':'140' , '141':'141' , '142':'142' ,
|
||||
'143':'101' , '144':'144' , '145':'145' , '146':'146' ,
|
||||
'147':'101' , '148':'148' , '149':'149' , '150':'150' ,
|
||||
'151':'101' , '152':'152' , '153':'153' , '154':'154' ,
|
||||
'155':'101' , '156':'156' , '157':'157' , '158':'158' ,
|
||||
'159':'101' , '160':'160' , '161':'161' , '162':'162' ,
|
||||
'163':'101' , '164':'164' , '165':'165' , '166':'166' ,
|
||||
'167':'101' , '168':'168' ,
|
||||
|
||||
'201':'201' , '202':'202' , '203':'203' , '204':'204' ,
|
||||
'205':'205' , '206':'206' , '206b':'206b' , '207':'207' ,
|
||||
'208':'208' , '209':'209' , '210':'210' , '211':'211' ,
|
||||
'212':'212' , '213':'213' , '214':'214' , '215':'215' ,
|
||||
'216':'216' , '217':'217' , '218':'218' , '219':'219' ,
|
||||
'220':'220' , '221':'221' , '222':'222' , '223':'223' ,
|
||||
'224':'224' , '225':'225' , '226':'226' , '227':'227' ,
|
||||
'228':'228' , '229':'229' , '230':'230' , '231':'231' ,
|
||||
'232':'232' , '233':'233' , '234':'234' , '235':'235' ,
|
||||
'236':'236' , '237':'237' , '238':'238' , '238b':'238b' ,
|
||||
'239':'201' , '240':'240' , '241':'241' , '242':'242' ,
|
||||
'243':'201' , '244':'244' , '245':'245' , '246':'246' ,
|
||||
'247':'201' , '248':'248' , '249':'249' , '250':'250' ,
|
||||
'251':'201' , '252':'252' , '253':'253' , '254':'254' ,
|
||||
'255':'201' , '256':'256' , '257':'257' , '258':'258' ,
|
||||
'259':'201' , '260':'260' , '261':'261' , '262':'262' ,
|
||||
'263':'201' , '264':'264' , '265':'265' , '266':'266' ,
|
||||
'267':'201' , '268':'268' ,
|
||||
|
||||
'301':'301' , '302':'302' , '303':'303' , '304':'304' ,
|
||||
'305':'305' , '306':'306' , '306b':'306b' , '307':'307' ,
|
||||
'308':'308' , '309':'309' , '310':'310' , '311':'311' ,
|
||||
'312':'312' , '313':'313' , '314':'314' , '315':'315' ,
|
||||
'316':'316' , '317':'317' , '318':'318' , '319':'319' ,
|
||||
'320':'320' , '321':'321' , '322':'322' , '323':'323' ,
|
||||
'324':'324' , '325':'325' , '326':'326' , '327':'327' ,
|
||||
'328':'328' , '329':'329' , '330':'330' , '331':'331' ,
|
||||
'332':'332' , '333':'333' , '334':'334' , '335':'335' ,
|
||||
'336':'336' , '337':'337' , '338':'338' , '338b':'338b' ,
|
||||
'339':'301' , '340':'340' , '341':'341' , '342':'342' ,
|
||||
'343':'301' , '344':'344' , '345':'345' , '346':'346' ,
|
||||
'347':'301' , '348':'348' , '349':'349' , '350':'350' ,
|
||||
'351':'301' , '352':'352' , '353':'353' , '354':'354' ,
|
||||
'355':'301' , '356':'356' , '357':'357' , '358':'358' ,
|
||||
'359':'301' , '360':'360' , '361':'361' , '362':'362' ,
|
||||
'363':'301' , '364':'364' , '365':'365' , '366':'366' ,
|
||||
'367':'301' , '368':'368' ,
|
||||
|
||||
'401':'401' , '402':'402' , '403':'403' , '404':'404' ,
|
||||
'405':'405' , '406':'406' , '406b':'406b' , '407':'407' ,
|
||||
'408':'408' , '409':'409' , '410':'410' , '411':'411' ,
|
||||
'412':'412' , '413':'413' , '414':'414' , '415':'415' ,
|
||||
'416':'416' , '417':'417' , '418':'418' , '419':'419' ,
|
||||
'420':'420' , '421':'421' , '422':'422' , '423':'423' ,
|
||||
'424':'424' , '425':'425' , '426':'426' , '427':'427' ,
|
||||
'428':'428' , '429':'429' , '430':'430' , '431':'431' ,
|
||||
'432':'432' , '433':'433' , '434':'434' , '435':'435' ,
|
||||
'436':'436' , '437':'437' , '438':'438' , '438b':'438b' ,
|
||||
'439':'401' , '440':'440' , '441':'441' , '442':'442' ,
|
||||
'443':'401' , '444':'444' , '445':'445' , '446':'446' ,
|
||||
'447':'401' , '448':'448' , '449':'449' , '450':'450' ,
|
||||
'451':'401' , '452':'452' , '453':'453' , '454':'454' ,
|
||||
'455':'401' , '456':'456' , '457':'457' , '458':'458' ,
|
||||
'459':'401' , '460':'460' , '461':'461' , '462':'462' ,
|
||||
'463':'401' , '464':'464' , '465':'465' , '466':'466' ,
|
||||
'467':'401' , '468':'468' ,
|
||||
|
||||
'501':'501' , '502':'502' , '502b':'502b' , '503':'503' ,
|
||||
'504':'504' , '505':'505' , '506':'506' , '507':'507' ,
|
||||
'508':'508' , '509':'509' , '510':'510' , '511':'511' ,
|
||||
'512':'512' , '513':'513' , '514':'514' , '515':'515' ,
|
||||
'516':'516' , '517':'517' , '518':'518' , '519':'519' ,
|
||||
'520':'520' , '521':'521' , '522':'522' , '523':'523' ,
|
||||
'524':'524' , '525':'525' , '526':'526' , '527':'527' ,
|
||||
'528':'528' } ,
|
||||
|
||||
'p' :
|
||||
{'101':'101' , '102':'102' , '103':'103' , '104':'104' ,
|
||||
'105':'105' , '106':'106' , '111':'111' , '112':'112' ,
|
||||
'113':'113' , '114':'114' , '115':'115' , '116':'116' ,
|
||||
'117':'117' , '118':'118' , '119':'119' , '120':'120' ,
|
||||
'121':'121' , '122':'122' , '123':'123' , '124':'124' ,
|
||||
'125':'125' , '126':'126' , '127':'127' , '128':'128' ,
|
||||
'129':'129' , '130':'130' , '131':'131' ,
|
||||
|
||||
'201':'201' , '202':'202' , '203':'203' , '204':'204' ,
|
||||
'205':'205' , '206':'206' , '211':'211' , '212':'212' ,
|
||||
'213':'213' , '214':'214' , '215':'215' , '216':'216' ,
|
||||
'217':'217' , '218':'218' , '219':'219' , '220':'220' ,
|
||||
'221':'221' , '222':'222' , '223':'223' , '224':'224' ,
|
||||
'225':'225' , '226':'226' , '227':'227' , '228':'228' ,
|
||||
'229':'229' , '230':'230' , '231':'231' ,
|
||||
|
||||
'301':'301' , '302':'302' , '303':'303' , '304':'304' ,
|
||||
'305':'305' , '306':'306' , '311':'311' , '312':'312' ,
|
||||
'313':'313' , '314':'314' , '315':'315' , '316':'316' ,
|
||||
'317':'317' , '318':'318' , '319':'319' , '320':'320' ,
|
||||
'321':'321' , '322':'322' , '323':'323' , '324':'324' ,
|
||||
'325':'325' , '326':'326' , '327':'327' , '328':'328' ,
|
||||
'329':'329' , '330':'330' , '331':'331' ,
|
||||
|
||||
'401':'401' , '402':'402' , '403':'403' , '404':'404' ,
|
||||
'405':'405' , '406':'406' , '411':'411' , '412':'412' ,
|
||||
'413':'413' , '414':'414' , '415':'415' , '416':'416' ,
|
||||
'417':'417' , '418':'418' , '419':'419' , '420':'420' ,
|
||||
'421':'421' , '422':'422' , '423':'423' , '424':'424' ,
|
||||
'425':'425' , '426':'426' , '427':'427' , '428':'428' ,
|
||||
'429':'429' , '430':'430' , '431':'431' }
|
||||
}
|
||||
|
||||
# Prises d'uplink, de machines du crans ou de bornes wifi
|
||||
uplink_prises={ 'i' :
|
||||
{ 49 : 'uplink->backbone' , 50 : 'uplink->bati1',
|
||||
149 : 'uplink->bati' } ,
|
||||
'h' :
|
||||
{ 49 : 'uplink->backbone' , 50 : 'uplink->bath1',
|
||||
149 : 'uplink->bath' , 150 : 'pegase' } ,
|
||||
'g' :
|
||||
{ 49 : 'uplink->backbone', 50 : 'uplink->batg1' ,
|
||||
149 : 'uplink->batg' , 150 : 'uplink->batg2' ,
|
||||
249 : 'uplink->batg1' , 250 : 'uplink->batg4' ,
|
||||
449 : 'uplink->batg2' , 450 : 'uplink->batg5' ,
|
||||
549 : 'uplink->batg4' , 550 : 'uplink->batg6' ,
|
||||
649 : 'uplink->batg5' , 547 : 'wifi_lodur' } ,
|
||||
'b' :
|
||||
{ 49 : 'uplink->backbone', 50 : 'uplink->batb1',
|
||||
149 : 'uplink->batb', 150 : 'uplink->batb2',
|
||||
249 : 'uplink->batb1', 250 : 'uplink->batb3',
|
||||
349 : 'uplink->batb2' },
|
||||
'c' :
|
||||
{ 49 : 'uplink->backbone', 50 : 'uplink->batc1',
|
||||
149 : 'uplink->batc' , 150 : 'uplink->batc2',
|
||||
225 : 'uplink->batc1', 226 : 'locaux_clubs' }
|
||||
}
|
||||
|
||||
# Dictionnaire inverse
|
||||
def reverse(bat) :
|
||||
""" Retourne un dictionnaire : { prise : [ chambre(s) ] } """
|
||||
reverse={}
|
||||
for chbre, prise in chbre_prises[bat].items() :
|
||||
if reverse.has_key(prise) :
|
||||
reverse[prise] += [ chbre ]
|
||||
else :
|
||||
reverse[prise] = [ chbre ]
|
||||
return reverse
|
||||
|
||||
# Locaux clubs : lecture dans chbre_prises et ajout des locaux dans les bats non
|
||||
# manageables
|
||||
def locaux_clubs() :
|
||||
""" Retourne le dicctionaire des locaux club : { bat :[ locaux ] } """
|
||||
# Corespondance chbre -> nom du local club
|
||||
locaux_clubs = { 'Bcl0' : 'Kfet' ,
|
||||
'Bcl1' : 'Krobot',
|
||||
'Gcl0' : 'Med' ,
|
||||
'Pcl0' : 'Bds' }
|
||||
# Ajout des locaux d'étage A, B et C
|
||||
for b in 'ABC' :
|
||||
for i in range(2,7) :
|
||||
locaux_clubs['%scl%i' % ( b, i)] = '%i@%s' % (i, b)
|
||||
# Ajout de ceux des H, I et J
|
||||
for b in 'HIJ' :
|
||||
for i in range(1,5) :
|
||||
locaux_clubs['%scl%i' % ( b, i)] = '%i@%s' % (i, b)
|
||||
# Supression du 2@B et 4@J
|
||||
locaux_clubs.pop('Bcl2')
|
||||
locaux_clubs.pop('Jcl4')
|
||||
|
||||
return locaux_clubs
|
41
gestion/chgpass.py
Executable file
41
gestion/chgpass.py
Executable file
|
@ -0,0 +1,41 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
import getpass, commands, os
|
||||
|
||||
import ldap_secret
|
||||
|
||||
def chgpass(dn) :
|
||||
print "Le mot de passe tapé ne sera pas écris à l'écran."
|
||||
print "Taper Ctrl-C pour abandonner"
|
||||
|
||||
try :
|
||||
|
||||
while 1 :
|
||||
mdp = getpass.getpass('Nouveau mot de passe :')
|
||||
mdp1 = getpass.getpass('Retaper mot de passe :')
|
||||
|
||||
if mdp != mdp1 :
|
||||
print 'Les deux mots de passe entrés sont différents, réesayer'
|
||||
continue
|
||||
|
||||
# Test du mdp
|
||||
test = commands.getoutput('echo "%s" | /usr/sbin/crack_testlib' % mdp)
|
||||
|
||||
if test.split(':')[1] == ' ok' :
|
||||
break
|
||||
else :
|
||||
print test.split(':')[1]
|
||||
|
||||
# Changement mdp
|
||||
if os.system('/usr/bin/ldappasswd -x -D "%s" -w %s "%s" -s %s > /dev/null' % (ldap_secret.auth_dn, ldap_secret.password, dn, mdp) ):
|
||||
print 'Erreur lors du changement de mot de passe'
|
||||
else :
|
||||
print 'Changement effectué avec succès'
|
||||
|
||||
except KeyboardInterrupt :
|
||||
pass
|
||||
|
||||
if __name__ == '__main__' :
|
||||
print 'TODO : interface de sélection'
|
||||
chgpass('aid=10,dc=crans,dc=org')
|
101
gestion/config.py
Normal file
101
gestion/config.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
# -*- python -*-
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
############################################
|
||||
## Définition du comportement des scripts ##
|
||||
############################################
|
||||
|
||||
#Précablage possible ?
|
||||
precab=1
|
||||
|
||||
#Bloquage si carte d'étudiant manquante pour l'année en cours
|
||||
carte_et=1
|
||||
|
||||
##Création de comptes
|
||||
# Gid des comptes créés
|
||||
gid=100
|
||||
# Shell
|
||||
login_shell='/bin/zsh'
|
||||
# Longueur maximale d'un login
|
||||
maxlen_login=15
|
||||
|
||||
# Année scolaire en cours
|
||||
from time import localtime
|
||||
dat = localtime()
|
||||
if dat[1]<9 : ann_scol = dat[0]-1
|
||||
else : ann_scol = dat[0]
|
||||
|
||||
## Quelques fichiers
|
||||
# Log des destructions de machines ou d'adhérents
|
||||
delete_log = '/tmp/delete.log'
|
||||
|
||||
#############################
|
||||
## Paramètres des machines ##
|
||||
#############################
|
||||
|
||||
## >>>>>>>>>>>>>>> La modification des paramètres suivants doit se
|
||||
## >> ATTENTION >> faire avec précaution, il faut mettre la base à
|
||||
## >>>>>>>>>>>>>>> jour en parralèle de ces modifs.
|
||||
|
||||
# Sous réseaux alloués à chaque type de machine ou bâtiment
|
||||
NETs = { 'wifi' : [ '138.231.149.0/24', '138.231.150.0/23' ],
|
||||
'b' : [ '138.231.137.0/24' ],
|
||||
'm' : [ '138.231.138.0/24' ],
|
||||
'c' : [ '138.231.139.0/24' ],
|
||||
'p' : [ '138.231.140.0/25' ],
|
||||
'a' : [ '138.231.140.128/25'],
|
||||
'g' : [ '138.231.141.0/24' ],
|
||||
'i' : [ '138.231.142.0/25' ],
|
||||
'j' : [ '138.231.142.128/25'],
|
||||
'h' : [ '138.231.143.0/24' ],
|
||||
'all' : [ '138.231.136.0/21', '138.231.148.0/22' ] }
|
||||
|
||||
# Domaines dans lesquels les machines sont placées suivant leur type
|
||||
domains = { 'wifi' : 'wifi.crans.org' ,
|
||||
'fixe' : 'crans.org' ,
|
||||
'borne': 'wifi.crans.org' }
|
||||
|
||||
#######################
|
||||
## Mail de bienvenue ##
|
||||
#######################
|
||||
#From est batx@crans.org ou respbat si adhérent extérieur
|
||||
txt_mail_bienvenue = """From: Crans <%(From)s>
|
||||
To: %(To)s
|
||||
Subject: Bienvenue au Cr@ns !
|
||||
|
||||
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.
|
||||
|
||||
Par ailleurs, toutes les informations concernant l'association sont
|
||||
disponibles sur le WIKI à l'adresse http://wiki.crans.org
|
||||
|
||||
Notamment, il est important de prendre le temps de lire la page :
|
||||
http://wiki.crans.org/moin.cgi/CransPratique
|
||||
Elle regroupe toutes les informations nécessaires à l'utilisation des
|
||||
ressources de l'association.
|
||||
|
||||
Sans lire attentivement ce document, l'accès au Web peut ne pas fonctionner.
|
||||
|
||||
-----
|
||||
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 les news :
|
||||
* Utilisateur : Vivelapa
|
||||
* Mot de passe : ranoia!
|
||||
- Pour le wiki :
|
||||
* Utilisateur : ViveLe
|
||||
* Mot de passe : Wiki!
|
||||
-----
|
||||
|
||||
Sur ce, bienvenue au Cr@ns !
|
||||
--
|
||||
Les membres actifs."""
|
||||
|
||||
## Ports ouvers par défaut pour tous les adhérents
|
||||
# A Priori stocké dans la base ldap quand Fred se sera bougé le cul
|
||||
port_default = { 'tcp_input' : ['22','1024:'],
|
||||
'tcp_output': [':79','81:134','136','140:444','446:'],
|
||||
'udp_input' : [''],
|
||||
'udp_output': [':136','140:'] }
|
||||
|
140
gestion/gen_confs/__init__.py
Executable file
140
gestion/gen_confs/__init__.py
Executable file
|
@ -0,0 +1,140 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
""" Package pour la génération des fichiers de conf
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
import sys, os, signal
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
||||
import time, commands
|
||||
from affich_tools import *
|
||||
from lock import *
|
||||
|
||||
import config
|
||||
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
# Notes snmp
|
||||
oid = '.1.3.6.1.4.1.2021.255'
|
||||
try :
|
||||
if sys.argv[1] == '-s' and sys.argv[2] == oid :
|
||||
service = sys.argv[4].strip().strip('"')
|
||||
except :
|
||||
None
|
||||
# Fin notes snmp
|
||||
|
||||
class gen_config :
|
||||
""" Base pour toutes les classes de génération de fichiers de conf """
|
||||
base = None
|
||||
ann_scol = config.ann_scol
|
||||
debug = 0
|
||||
_locked = 0
|
||||
__restore={} # pour restorer la config d'origine en cas d'erreur de génération
|
||||
|
||||
def lock(self) :
|
||||
""" Lock le service courant """
|
||||
if not self._locked :
|
||||
make_lock(str(self.__class__),'')
|
||||
self._locked = 1
|
||||
|
||||
def unlock(self) :
|
||||
""" Supression du lock """
|
||||
if self._locked : remove_lock(str(self.__class__))
|
||||
|
||||
def __del__(self) :
|
||||
# Au cas où...
|
||||
self.unlock()
|
||||
|
||||
def _restore(self) :
|
||||
""" Affichage d'une erreur et du traceback si debug
|
||||
Puis restauration des fichers """
|
||||
print ERREUR
|
||||
if self.debug :
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
# Restauration
|
||||
for nom, f in self.__restore.items() :
|
||||
os.system('cp -f %s %s' % ( f.name, nom ) )
|
||||
|
||||
def _open_conf(self,nom,comment=None) :
|
||||
""" Créé un fichier
|
||||
si comment est fourni, insère une entète qui utilisera le caractère
|
||||
de commentaire fourni
|
||||
|
||||
copie l'ancien fichier dans un fichier temporaire pour permettre
|
||||
la restauration en cas d'échec de la configuration
|
||||
|
||||
Retourne le descripteur du fichier """
|
||||
|
||||
f = NamedTemporaryFile()
|
||||
os.system('cp %s %s 2> /dev/null' % ( nom, f.name ) )
|
||||
self.__restore[nom] = f
|
||||
|
||||
fd = open(nom, 'w')
|
||||
|
||||
if comment :
|
||||
e = """***********************************************************
|
||||
Ce fichier est généré par les scripts de %s
|
||||
Les données proviennent de la base LDAP et de la conf
|
||||
présente au début du script.
|
||||
|
||||
Génération : %s
|
||||
Fichier : %s
|
||||
|
||||
NE PAS EDITER
|
||||
|
||||
***********************************************************""" % \
|
||||
(__name__, nom, time.strftime('%A %d %B %Y %H:%M') )
|
||||
|
||||
e = comment + e.replace('\n', '\n%s' % comment) + '\n'
|
||||
fd.write(e)
|
||||
|
||||
return fd
|
||||
|
||||
def gen_conf(self) :
|
||||
""" Génération des fichiers de conf, retourne 1 si erreur """
|
||||
self.lock()
|
||||
self.anim = anim('\tgénération fichiers')
|
||||
try :
|
||||
warn = self._gen()
|
||||
if warn :
|
||||
self.anim.reinit()
|
||||
print WARNING
|
||||
if self.debug : sys.stderr.write(warn.encode("ISO-8859-15"))
|
||||
else :
|
||||
self.anim.reinit()
|
||||
print OK
|
||||
self.unlock()
|
||||
except :
|
||||
self.anim.reinit()
|
||||
self._restore()
|
||||
self.unlock()
|
||||
return 1
|
||||
|
||||
def restart(self) :
|
||||
""" Redémarrage du service concerné """
|
||||
self.lock()
|
||||
self.anim = anim('\trestart')
|
||||
status, output = commands.getstatusoutput(self.restart_cmd)
|
||||
if status :
|
||||
self.anim.reinit()
|
||||
print ERREUR
|
||||
if self.debug :
|
||||
sys.stderr.write(output+'\n')
|
||||
self.unlock()
|
||||
return 1
|
||||
else :
|
||||
print OK
|
||||
self.unlock()
|
||||
|
||||
def reconfigure(self) :
|
||||
""" Génère les fichiers puis redémarre le service
|
||||
si la génération c'est bien passée """
|
||||
cprint('Reconfiguration %s :' % self.__str__() , 'gras')
|
||||
if not self.gen_conf() :
|
||||
return self.restart()
|
||||
else : return 1
|
186
gestion/gen_confs/bind.py
Executable file
186
gestion/gen_confs/bind.py
Executable file
|
@ -0,0 +1,186 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
""" Génération de la configuration pour bind9
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
# TODO :
|
||||
# verif si SOA zamok.crans.org bon partout
|
||||
# verif si liste NS identiques partout ok
|
||||
# traitement warnings
|
||||
|
||||
import time, sre
|
||||
from gen_confs import gen_config
|
||||
|
||||
class dns(gen_config) :
|
||||
"""
|
||||
Génération des fichiers de configuration de bind9 :
|
||||
* fichier DNS_CONF qui contient les définitions de zone conformément
|
||||
à zone_template. Ce fichier doit être inclus à partir de la config statique
|
||||
de bind
|
||||
* les fichiers de zones, ce sont eux qui contiennent les données du
|
||||
dns, ils ont appellés par le fichier DNS_CONF et sont générés dans DNS_DIR
|
||||
Leur entète est générée à partir de zone_entete.
|
||||
|
||||
Les fichiers générés placent bind comme autoritaire sur les noms de
|
||||
zones_direct et les adresses de zones_reverse. Les données proviennent de
|
||||
la base LDAP
|
||||
"""
|
||||
######################################PARTIE DE CONFIGURATION
|
||||
|
||||
### Fichiers à écrire
|
||||
# Répertoire d'écriture des fichiers de zone
|
||||
DNS_DIR='/etc/bind/generated/' # Avec un / à la fin
|
||||
# Fichier de définition des zones
|
||||
DNS_CONF=DNS_DIR + 'zones_crans'
|
||||
|
||||
### Sur quelles zones on a autorité ?
|
||||
# Résolution directe
|
||||
zones_direct = [ 'crans.org' , 'crans.ens-cachan.fr', 'wifi.crans.org' ]
|
||||
# Résolution inverse (regexp pour définir les débuts des IP correspondantes)
|
||||
zones_reverse = sre.compile('^138\.231\.1(3[6-9]|4[0-9]|5[01])') # 138.231.136.0 à 138.231.151.255
|
||||
|
||||
### Liste DNS
|
||||
# Le premier est doit être le maitre
|
||||
DNSs = [ 'zamok.crans.org' , 'sila.crans.org' , 'freebox.crans.org' ]
|
||||
|
||||
### Serveurs de mail
|
||||
# format : [ priorité serveur , .... ]
|
||||
MXs = ['10 zamok.crans.org', '20 freebox.crans.org' ]
|
||||
|
||||
### Entète des fichiers de zone
|
||||
zone_entete="""
|
||||
$ORIGIN %(zone)s.
|
||||
$TTL 86400
|
||||
@\tIN\tSOA zamok.crans.org. root.crans.org. (
|
||||
%(serial)i ; numero de serie
|
||||
21600 ; refresh (s)
|
||||
3600 ; retry (s)
|
||||
1209600 ; expire (s)
|
||||
86400 ; TTL (s)
|
||||
)
|
||||
"""
|
||||
|
||||
# Syntaxe utilisée dans le fichier DNS_CONF pour définir une zone
|
||||
zone_template="""
|
||||
zone "%(NOM_zone)s" {
|
||||
type master;
|
||||
file "%(FICHIER_zone)s";
|
||||
};
|
||||
"""
|
||||
|
||||
### Verbosité
|
||||
# Si =1 ralera (chaine warnings) si machines hors zone trouvée
|
||||
# Si =0 ralera seulement contre les machines ne pouvant être classées
|
||||
verbose = 1
|
||||
|
||||
restart_cmd = '/etc/init.d/bind9 reload'
|
||||
######################################FIN PARTIE DE CONFIGURATION
|
||||
|
||||
def __str__(self) :
|
||||
return "DNS"
|
||||
|
||||
def _gen(self) :
|
||||
### Génération du numéro de série
|
||||
# Le + 1000.... s'explique pas l'idée précédente et peu pratique d'avoir
|
||||
# le numéro de série du type AAAAMMJJNN (année, mois, jour, incrément par jour)
|
||||
serial = time.time() + 1000000000
|
||||
|
||||
### DNS
|
||||
DNS='; DNS de la zone par ordre de priorité\n'
|
||||
for d in self.DNSs :
|
||||
DNS += '@\tIN\tNS %s.\n' % d
|
||||
DNS += '\n'
|
||||
|
||||
### Serveurs de mail
|
||||
MX='; Serveurs de mails\n'
|
||||
for m in self.MXs :
|
||||
MX += '%(zone)s.\t' # Sera remplacé par le nom de zone plus tard
|
||||
MX += 'IN\tMX\t%s.\n' % m
|
||||
MX += '\n'
|
||||
|
||||
### Tri des machines
|
||||
direct = {} # format : { zone : [ lignes correspondantes] }
|
||||
reverse = {}
|
||||
warnings = ''
|
||||
|
||||
self.anim.iter=len(self.machines)
|
||||
for machine in self.machines :
|
||||
self.anim.cycle()
|
||||
|
||||
# Calculs préliminaires
|
||||
try :
|
||||
nom , zone = machine.nom().split('.',1)
|
||||
zone = zone.encode('iso-8859-1')
|
||||
except :
|
||||
warnings += u'Machine ignorée (mid=%s) : format nom incorrect (%s)\n' % ( machine.id().encode('iso-8859-1'), machine.nom().encode('iso-8859-1') )
|
||||
continue
|
||||
|
||||
# Le direct
|
||||
if zone in self.zones_direct :
|
||||
ligne = "%s\tIN\tA\t%s\n" % ( nom, machine.ip() )
|
||||
try : direct[zone] += ligne
|
||||
except : direct[zone] = ligne
|
||||
elif self.verbose :
|
||||
warnings += u'Résolution directe ignorée (mid=%s) : zone non autoritaire (%s)\n' % ( machine.id().encode('iso-8859-1'), zone.encode('iso-8859-1') )
|
||||
|
||||
# Le direct avec alias
|
||||
for alias in machine.alias() :
|
||||
# Bon format ?
|
||||
alias_l = alias.split('.')
|
||||
ok = 0
|
||||
for i in range(len(alias_l)) :
|
||||
zone_essai = '.'.join(alias_l[i:])
|
||||
if zone_essai in self.zones_direct :
|
||||
# On est autoritaire sur cette zone
|
||||
# On place donc l'alias dans le fichier de cette zone
|
||||
zone = zone_essai
|
||||
nom = '.'.join(alias_l[:i])
|
||||
ok = 1
|
||||
break
|
||||
if not ok :
|
||||
warnings += u'Alias ignoré (mid=%s) : %s\n' % ( machine.id().encode('iso-8859-1'), alias.encode('iso-8859-1') )
|
||||
continue
|
||||
zone = zone.encode('iso-8859-1')
|
||||
ligne = "%s\tIN\tCNAME\t%s.\n" % ( nom, machine.nom() )
|
||||
try : direct[zone] += ligne
|
||||
except : direct[zone] = ligne
|
||||
# Le reverse
|
||||
if self.zones_reverse.match(machine.ip()) :
|
||||
base_ip = machine.ip().split('.')
|
||||
base_ip.reverse()
|
||||
zone = "%s.%s.%s.in-addr.arpa" % tuple(base_ip[1:])
|
||||
zone = zone.encode('iso-8859-1')
|
||||
ligne = '%s\tIN\tPTR\t%s.\n' % (base_ip[0],machine.nom())
|
||||
try : reverse[zone] += ligne
|
||||
except : reverse[zone] = ligne
|
||||
elif self.verbose :
|
||||
warnings += u'Résolution inverse ignorée (mid=%s) : ip sur zone non autoritaire (%s)\n' % ( machine.id().encode('iso-8859-1'), machine.ip().encode('iso-8859-1') )
|
||||
|
||||
### Ajouts pour les fichiers de résolution directs
|
||||
for zone in direct.keys() :
|
||||
# MXs
|
||||
direct[zone] = MX % { 'zone' : zone } + direct[zone]
|
||||
|
||||
### Ecriture des fichiers de zone et préparation du fichier de définition
|
||||
f = ''
|
||||
for zone, lignes in direct.items() + reverse.items() :
|
||||
file = self.DNS_DIR + 'db.' + zone
|
||||
fd = self._open_conf(file,';')
|
||||
fd.write(self.zone_entete % \
|
||||
{ 'zone' : zone, 'serveur_autoritaire' : self.DNSs[0] , 'serial' : serial } )
|
||||
fd.write('\n')
|
||||
fd.write(DNS)
|
||||
fd.write(lignes)
|
||||
fd.close()
|
||||
f += self.zone_template % { 'NOM_zone' : zone, 'FICHIER_zone' : file }
|
||||
|
||||
### Ecriture fichier de définition
|
||||
fd = self._open_conf(self.DNS_CONF,'//')
|
||||
fd.write(f)
|
||||
fd.close()
|
||||
|
||||
return warnings
|
42
gestion/gen_confs/blacklist_upload.py
Executable file
42
gestion/gen_confs/blacklist_upload.py
Executable file
|
@ -0,0 +1,42 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
from firewall import bl_upload_fw
|
||||
from squid import bl_upload_squid
|
||||
|
||||
class bl_upload :
|
||||
""" Classe d'interface avec les classes spécifiques des
|
||||
opération de configuration pour upload """
|
||||
debug = 0
|
||||
description = u'Bloquage de toute communiquation vers l\'extérieur.'
|
||||
|
||||
def __str__(self) :
|
||||
return "blackliste upload"
|
||||
|
||||
def __init__(self) :
|
||||
self.fw = bl_upload_fw()
|
||||
|
||||
self.squid = bl_upload_squid()
|
||||
|
||||
def __set(self) :
|
||||
""" Attribution des proprietes des differentes classes """
|
||||
self.fw.base = self.base
|
||||
self.fw.debug = self.debug
|
||||
|
||||
self.squid.base = self.base
|
||||
self.squid.debug = self.debug
|
||||
|
||||
def reconfigure(self) :
|
||||
self.__set()
|
||||
self.fw.reconfigure()
|
||||
self.squid.reconfigure()
|
||||
|
||||
def restart(self) :
|
||||
self.__set()
|
||||
self.fw.restart()
|
||||
self.squid.restart()
|
||||
|
||||
def gen_conf(self) :
|
||||
self.__set()
|
||||
self.fw.gen_conf()
|
||||
self.squid.gen_conf()
|
115
gestion/gen_confs/dhcpd.py
Executable file
115
gestion/gen_confs/dhcpd.py
Executable file
|
@ -0,0 +1,115 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
""" Génération de la configuration pour le dhcp
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
from iptools import AddrInNet, param
|
||||
from gen_confs import gen_config
|
||||
|
||||
class dhcp(gen_config) :
|
||||
""" Génération du fichier de configuration pour dhcpd (DHCPD_CONF)
|
||||
Le fichier comporte une partie par réseau servi, chaque réseau
|
||||
servi doit être une clef du dictionnaire reseaux, la valeur correspondante
|
||||
est une chaine décrivant les options spécifiques à ce réseau.
|
||||
Les options communes sont celles de base_dhcp.
|
||||
|
||||
Chaque machines possède ensuite une entrée de la forme de host_template
|
||||
"""
|
||||
######################################PARTIE DE CONFIGURATION
|
||||
|
||||
# Fichier à écire
|
||||
DHCPD_CONF='/etc/dhcpd.conf'
|
||||
|
||||
# Réseaux servis avec leurs options spécifiques
|
||||
reseaux = { '138.231.136.0/21' :
|
||||
"""option routers 138.231.136.4;
|
||||
option domain-name-servers 138.231.136.6, 138.231.136.10, 138.231.136.9;
|
||||
option domain-name "crans.org";
|
||||
option option-119 "crans.org wifi.crans.org";""",
|
||||
|
||||
'138.231.148.0/22' :
|
||||
"""option routers 138.231.148.1;
|
||||
option domain-name-servers 138.231.148.1;
|
||||
option domain-name "wifi.crans.org";
|
||||
option option-119 "wifi.crans.org crans.org";"""
|
||||
}
|
||||
|
||||
# Options communes à toutes les réseaux servis
|
||||
base_dhcp="""
|
||||
subnet %(network)s netmask %(netmask)s {
|
||||
default-lease-time 86400;
|
||||
option subnet-mask %(netmask)s;
|
||||
option broadcast-address %(broadcast)s;
|
||||
%(OPTIONS_RESEAU)s
|
||||
option time-servers 138.231.136.6;
|
||||
option ntp-servers 138.231.136.6;
|
||||
option smtp-server 138.231.136.6;
|
||||
option netbios-name-servers 138.231.136.6;
|
||||
option netbios-dd-server 138.231.136.6;
|
||||
option netbios-node-type 8;
|
||||
option ip-forwarding off;
|
||||
option option-252 "http://www.crans.org/proxy.pac" ;
|
||||
deny unknown-clients;
|
||||
not authoritative;
|
||||
%(HOSTs)s
|
||||
}
|
||||
"""
|
||||
|
||||
host_template="""
|
||||
host %(nom)s {
|
||||
hardware ethernet %(mac)s;
|
||||
fixed-address %(ip)s;
|
||||
option host-name "%(nom)s";
|
||||
}
|
||||
"""
|
||||
|
||||
### Verbosité
|
||||
# Si =1 ralera (chaine warnings) si machines hors zone trouvée
|
||||
# Si =0 ralera seulement si réseau vide
|
||||
verbose = 1
|
||||
|
||||
restart_cmd = '/etc/init.d/dhcp restart'
|
||||
|
||||
######################################FIN PARTIE DE CONFIGURATION
|
||||
|
||||
def __str__(self) :
|
||||
return 'dhcp'
|
||||
|
||||
def _gen(self) :
|
||||
warnings =''
|
||||
|
||||
### Construction de la partie du fichier contenant les machines
|
||||
hosts={}
|
||||
|
||||
self.anim.iter=len(self.machines)
|
||||
for machine in self.machines :
|
||||
self.anim.cycle()
|
||||
t = 0
|
||||
for net in self.reseaux.keys() :
|
||||
if AddrInNet(machine.ip(),net) :
|
||||
d = { 'nom' : machine.nom().split('.')[0] , 'mac' : machine.mac() , 'ip' : machine.ip() }
|
||||
try : hosts[net] += self.host_template % d
|
||||
except : hosts[net] = self.host_template % d
|
||||
t = 1
|
||||
if not t and self.verbose :
|
||||
warnings += u'Machine ignorée (mid=%s) : ip en dehors des réseaux servis (%s)\n' % ( machine.id(), machine.ip() )
|
||||
|
||||
### Ecriture du fichier
|
||||
fd = self._open_conf(self.DHCPD_CONF,'#')
|
||||
for net, options in self.reseaux.items() :
|
||||
if not hosts.has_key(net) :
|
||||
warnings += u'Réseau %s ignoré : aucune machine à servir\n' % net
|
||||
continue
|
||||
d = param(net)
|
||||
d['OPTIONS_RESEAU'] = options
|
||||
d['HOSTs'] = hosts[net]
|
||||
|
||||
fd.write(self.base_dhcp % d)
|
||||
|
||||
fd.close()
|
||||
|
||||
return warnings
|
80
gestion/gen_confs/droits.py
Executable file
80
gestion/gen_confs/droits.py
Executable file
|
@ -0,0 +1,80 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
import sys, signal
|
||||
from gen_confs import gen_config, anim, cprint, OK, ERREUR
|
||||
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
from ldap_crans import crans_ldap, crans, ann_scol, preattr, ldap
|
||||
|
||||
class droits(crans_ldap,gen_config) :
|
||||
####### Les groupes
|
||||
base_group_dn = 'ou=Group,dc=crans,dc=org'
|
||||
|
||||
# Quels droits donnent l'appartenacne à quel groupe ?
|
||||
groupes = { 'adm' : [ u'Nounou' ] ,
|
||||
'respbats' : [ u'Câbleur' , u'Déconnecteur', u'Nounou' ] ,
|
||||
'moderateurs' : [ u'Modérateur' ] ,
|
||||
'disconnect' : [ u'Déconnecteur' ] ,
|
||||
'webcvs' : [ u'CVSWeb'] }
|
||||
|
||||
####### Les ML
|
||||
# Le + devant un nom de ML indique une synchronisqtion
|
||||
# ML <-> fonction partielle : il n'y a pas d'effacement
|
||||
# des abonnés si le droit est retiré
|
||||
mailing_listes = { 'roots' : [ u'Nounou', u'Apprenti' ],
|
||||
'+nounou' : [ u'Nounou', u'Apprenti' ],
|
||||
'respbats' : [ u'Câbleur', u'Nounou' ],
|
||||
'moderateurs' : [ u'Modérateur' ],
|
||||
'disconnect' : [ u'Déconnecteur' ] }
|
||||
|
||||
def restart(s) :
|
||||
# Rien à faire
|
||||
pass
|
||||
|
||||
def __str__(self):
|
||||
return "droits"
|
||||
|
||||
def build_group(self) :
|
||||
""" Reconstruit les groupes dans la base LDAP """
|
||||
self.anim.iter = len( self.groupes.keys() )
|
||||
for group, fonctions in self.groupes.items() :
|
||||
self.anim.cycle()
|
||||
# Qui doit être dans ce groupe ?
|
||||
res = []
|
||||
for f in fonctions :
|
||||
res += self.search('droits=%s' % f)['adherent']
|
||||
|
||||
# Récupération de la constitution du groupe actuel
|
||||
dn = 'cn=%s,%s' % (group, self.base_group_dn)
|
||||
data = self.conn.search_s(dn ,0,'objectClass=posixGroup')[0][1]
|
||||
init_data = data.copy()
|
||||
|
||||
# Supression de tout les membres
|
||||
data['memberUid'] = []
|
||||
|
||||
# Ajout des bonnes personnes
|
||||
for adher in res :
|
||||
uid = preattr(adher.compte())[1]
|
||||
if uid and uid not in data['memberUid'] :
|
||||
data['memberUid'].append(uid)
|
||||
|
||||
# Sauvegarde
|
||||
modlist = ldap.modlist.modifyModlist(init_data,data)
|
||||
self.conn.modify_s(dn,modlist)
|
||||
|
||||
def gen_conf(self) :
|
||||
self.anim = anim('\tconfiguration groupes')
|
||||
try :
|
||||
self.build_group()
|
||||
self.anim.reinit()
|
||||
print OK
|
||||
except :
|
||||
self.anim.reinit()
|
||||
print ERREUR
|
||||
if self.debug :
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
self.anim = anim('\tconfiguration ML Crans')
|
||||
print 'TODO'
|
60
gestion/gen_confs/firewall.py
Executable file
60
gestion/gen_confs/firewall.py
Executable file
|
@ -0,0 +1,60 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
""" Génération de la configuration pour le firewall
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
from gen_confs import gen_config
|
||||
from time import localtime
|
||||
|
||||
class firewall(gen_config) :
|
||||
""" Génère le fichier de paires MAC-IP """
|
||||
# Fichier
|
||||
MACIP = '/CRANS/generated/ether/pairesMAC-IP.txt'
|
||||
|
||||
restart_cmd = '/etc/init.d/firewall macip'
|
||||
|
||||
def __str__(self) :
|
||||
return "firewall"
|
||||
|
||||
def _gen(self) :
|
||||
macip= self._open_conf(self.MACIP)
|
||||
|
||||
self.anim.iter=len(self.machines)
|
||||
for machine in self.machines :
|
||||
self.anim.cycle()
|
||||
macip.write( "%s %s\n" % ( machine.mac(), machine.ip() ) )
|
||||
|
||||
macip.close()
|
||||
|
||||
class bl_upload_fw(gen_config) :
|
||||
""" Génère le fichier de blackliste d'upload pour le firewall"""
|
||||
# Fichier
|
||||
BL_UPLOAD = '/tmp/bl_upload_fw'
|
||||
|
||||
restart_cmd = '/etc/init.d/firewall blacklist'
|
||||
|
||||
def __str__(self) :
|
||||
return "blackliste upload firewall"
|
||||
|
||||
def _gen(self) :
|
||||
upload = self._open_conf( self.BL_UPLOAD, '#' )
|
||||
|
||||
if localtime()[1] == 9:
|
||||
# On est en septembre, on autorise ceux qui ont payé l'an dernier et cette année
|
||||
base = self.base.search('(paiement=%d|paiement=%d)' % (int(self.ann_scol),
|
||||
int(self.ann_scol) - 1))
|
||||
else:
|
||||
base = self.base.search('paiement=%s' % self.ann_scol)
|
||||
for adh in ( [ self.crans ] + base['adherent'] + base['club'] ):
|
||||
for machine in adh.machines() :
|
||||
self.anim.cycle()
|
||||
bl = machine.blacklist_actif()
|
||||
if 'bl_upload' in bl and not 'bloq' in bl :
|
||||
upload.write( '%s:smtp,smtps,pop3,pop3s,imap,imaps,http\n' % machine.nom() )
|
||||
|
||||
upload.close()
|
||||
|
161
gestion/gen_confs/generate.py
Executable file
161
gestion/gen_confs/generate.py
Executable file
|
@ -0,0 +1,161 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
import sys, signal, os, commands, getopt
|
||||
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
|
||||
from ldap_crans import crans_ldap, crans, ann_scol
|
||||
from lock import *
|
||||
from affich_tools import anim, cprint, OK, ERREUR, WARNING
|
||||
from time import localtime
|
||||
import config
|
||||
|
||||
signal.signal(signal.SIGINT,signal.SIG_IGN) # Pas de Ctrl-C
|
||||
|
||||
db = crans_ldap()
|
||||
make_lock('auto_generate')
|
||||
|
||||
##### Options fournies ?
|
||||
try :
|
||||
if len(sys.argv) > 1 :
|
||||
options, arg = getopt.getopt(sys.argv[1:], '', ['quiet', 'home=', 'ML-ENS=', 'droits', 'switch=' , 'dhcp', 'dns', 'firewall' ])
|
||||
else :
|
||||
options, arg = ( [],'')
|
||||
except getopt.error, msg :
|
||||
sys.stderr.write('%s\n' % msg)
|
||||
sys.exit(255)
|
||||
|
||||
debug = 1 # défaut
|
||||
to_do = {}
|
||||
|
||||
for opt, val in options :
|
||||
if opt == '--quiet' :
|
||||
debug = 0
|
||||
elif len(opt)>2 and opt[:2]=='--' :
|
||||
to_do[opt[2:]] = [ val ]
|
||||
|
||||
##### Lecture de la base LDAP si besion ce qu'il y a a faire et préparation
|
||||
if not to_do :
|
||||
if debug : print 'Lecture services à redémarrer dans la base LDAP'
|
||||
to_do = db.services_to_restart()
|
||||
auto = 1
|
||||
else :
|
||||
auto = 0
|
||||
if debug : print 'Services à redémarrer imposés (non lecture de la base LDAP)'
|
||||
|
||||
inst = []
|
||||
if 'home' in to_do.keys() :
|
||||
if auto : db.services_to_restart('-home')
|
||||
cprint('Création home','gras')
|
||||
for args in to_do['home'] :
|
||||
anim('\t' + args)
|
||||
try :
|
||||
home, uid, login = args.split(',')
|
||||
os.mkdir(home, 0755)
|
||||
os.chown(home, int(uid) ,config.gid)
|
||||
os.mkdir(home + '/Mail', 0700)
|
||||
os.chown(home + '/Mail', int(uid) ,config.gid)
|
||||
status, output = commands.getstatusoutput('/usr/sbin/edquota -p pauget %s' % login )
|
||||
if status :
|
||||
print WARNING
|
||||
if debug :
|
||||
sys.stderr.write(output+'\n')
|
||||
else :
|
||||
print OK
|
||||
except :
|
||||
print ERREUR
|
||||
if debug :
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
if 'ML-ENS' in to_do.keys() :
|
||||
db.services_to_restart('-ML-ENS')
|
||||
cprint('Inscription ML-ENS','gras')
|
||||
for mail in to_do['ML-ENS'] :
|
||||
anim('\t'+mail)
|
||||
status, output = commands.getstatusoutput("echo '%s' | /usr/sbin/add_members -r - com-ens >/dev/null 2>&1" % mail)
|
||||
if status :
|
||||
# Il y a eu une erreur
|
||||
print ERREUR
|
||||
if debug :
|
||||
sys.stderr.write(output+'\n')
|
||||
else :
|
||||
print OK
|
||||
|
||||
if 'droits' in to_do.keys() :
|
||||
db.services_to_restart('-droits')
|
||||
from gen_confs.droits import droits
|
||||
a = droits()
|
||||
a.debug = debug
|
||||
a.reconfigure()
|
||||
|
||||
if 'switch' in to_do.keys() :
|
||||
if auto : db.services_to_restart('-switch')
|
||||
from gen_confs.switchs import switch
|
||||
a = switch(to_do['switch'])
|
||||
a.debug = debug
|
||||
a.reconfigure()
|
||||
|
||||
# Les services suivants ont besoin de la liste des machines
|
||||
# On va donc la lire une seule fois pour leur passer ensuite
|
||||
|
||||
if 'firewall' in to_do.keys() :
|
||||
# Quand sila et komaz liront la base LDAP
|
||||
# db.services_to_restart('firewall-komaz')
|
||||
# db.services_to_restart('firewall-sila')
|
||||
db.services_to_restart('-firewall')
|
||||
from gen_confs.firewall import firewall
|
||||
inst.append(firewall())
|
||||
|
||||
if 'dns' in to_do.keys() :
|
||||
db.services_to_restart('-dns')
|
||||
from gen_confs.bind import dns
|
||||
inst.append(dns())
|
||||
|
||||
if 'dhcp' in to_do.keys() :
|
||||
from gen_confs.dhcpd import dhcp
|
||||
db.services_to_restart('-dhcp')
|
||||
inst.append(dhcp())
|
||||
|
||||
##### On fait ce qu'il reste à faire
|
||||
|
||||
if inst :
|
||||
##### Récolte des données
|
||||
cprint('Lecture base LDAP','gras')
|
||||
# Machines de l'assoce
|
||||
machines = crans().machines()
|
||||
# Machines des adhérents et clubs de l'année en cours
|
||||
if localtime()[1] == 9:
|
||||
# On est en septembre, on autorise ceux qui ont payé l'an dernier et cette année
|
||||
base = db.search('(paiement=%d|paiement=%d)' % (int(ann_scol),
|
||||
int(ann_scol) - 1))
|
||||
else:
|
||||
base = db.search('paiement=%s' % ann_scol)
|
||||
base = base['adherent'] + base['club']
|
||||
a = anim('\ttri machines',len(base))
|
||||
for adh in base :
|
||||
a.cycle()
|
||||
# Adhérent ayant payé l'année en cours
|
||||
if 'bloq' in adh.blacklist_actif() :
|
||||
# Adhérent ignoré
|
||||
continue
|
||||
machines += adh.machines()
|
||||
a.reinit()
|
||||
print OK
|
||||
|
||||
#### Reconfiguration des services
|
||||
for i in inst :
|
||||
i.debug = debug
|
||||
i.machines = machines
|
||||
try :
|
||||
i.reconfigure()
|
||||
except :
|
||||
sys.stderr.write('Erreur dans le service %s\n' % i)
|
||||
|
||||
if debug :
|
||||
print 'Non traité ici mais signalé dans la base LDAP : \n\t', db.services_to_restart()
|
||||
|
||||
signal.signal(signal.SIGINT,signal.SIG_DFL) # Comportement normal de Ctrl-C
|
||||
|
||||
remove_lock('auto_generate')
|
14
gestion/gen_confs/home.py
Normal file
14
gestion/gen_confs/home.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
home
|
||||
home = args[0]
|
||||
os.mkdir(home, 0755)
|
||||
os.mkdir(home + '/Mail', 0700)
|
||||
os.lchown(home, int(args[1]) ,config.gid)
|
||||
os.system('/usr/sbin/edquota -p pauget %s' % arg[3] )
|
||||
|
||||
ML-ENS
|
||||
if os.system("echo '%s' | /usr/sbin/add_members -r - com-ens" % mail) :
|
||||
# Il y a eu une erreur
|
||||
arg = u'--title "Inscription Mailing liste de communiquation ENS" '
|
||||
arg+= u'--msgbox "Une erreur s\'est produite lors de l\'ajout à la mailing liste.\n\n\n" 0 0'
|
||||
dialog(arg)
|
90
gestion/gen_confs/squid.py
Executable file
90
gestion/gen_confs/squid.py
Executable file
|
@ -0,0 +1,90 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
""" Génération de la configuration pour squid """
|
||||
|
||||
from gen_confs import gen_config
|
||||
from time import localtime
|
||||
|
||||
class bl_carte_etudiant(gen_config) :
|
||||
""" Génère le fichier de blackliste pour carte d'étudiant pour squid"""
|
||||
BL_CARTE = '/tmp/bl_carte_et'
|
||||
restart_cmd = '/etc/init.d/squid reload'
|
||||
|
||||
def __str__(self) :
|
||||
return "blackliste cartes d'étudiant"
|
||||
|
||||
def _gen(self) :
|
||||
fd=self._open_conf(self.BL_CARTE)
|
||||
|
||||
if localtime()[1] == 9:
|
||||
# On est en septembre, on autorise ceux qui ont payé l'an dernier et cette année
|
||||
base = self.base.search('carteEtudiant!=%s&(paiement=%d|paiement=%d)' % (self.ann_scol,
|
||||
int(self.ann_scol),
|
||||
int(self.ann_scol) - 1))
|
||||
else:
|
||||
base = self.base.search('paiement=%s' % self.ann_scol)
|
||||
for adh in ( [ self.crans ] + base['adherent'] + base['club'] ):
|
||||
for machine in adh.machines() :
|
||||
self.anim.cycle()
|
||||
if 'bloq' in machine.blacklist_actif() : continue
|
||||
if machine.proprietaire().idn != 'aid' : continue
|
||||
fd.write(machine.nom() + '\n')
|
||||
|
||||
fd.close()
|
||||
|
||||
class bl_upload_squid(gen_config) :
|
||||
""" Génère le fichier de blackliste d'upload pour squid"""
|
||||
# Fichier
|
||||
BL_UPLOAD = '/tmp/bl_upload_squid'
|
||||
restart_cmd = '/etc/init.d/squid reload'
|
||||
|
||||
def __str__(self) :
|
||||
return "blackliste upload squid"
|
||||
|
||||
def _gen(self) :
|
||||
upload = self._open_conf( self.BL_UPLOAD )
|
||||
|
||||
if localtime()[1] == 9:
|
||||
# On est en septembre, on autorise ceux qui ont payé l'an dernier et cette année
|
||||
base = self.base.search('(paiement=%d|paiement=%d)' % (int(self.ann_scol),
|
||||
int(self.ann_scol) - 1))
|
||||
else:
|
||||
base = self.base.search('paiement=%s' % self.ann_scol)
|
||||
for adh in ( [ self.crans ] + base['adherent'] + base['club'] ):
|
||||
for machine in adh.machines() :
|
||||
self.anim.cycle()
|
||||
bl = machine.blacklist_actif()
|
||||
if 'bl_upload' in bl and not 'bloq' in bl :
|
||||
upload.write( machine.nom() + '\n' )
|
||||
|
||||
upload.close()
|
||||
|
||||
class bl_virus(gen_config) :
|
||||
""" Génère le fichier de blackliste virus pour squid"""
|
||||
# Fichiers
|
||||
BL_VIRUS = '/tmp/bl_virus'
|
||||
|
||||
def __str__(self) :
|
||||
return "blackliste virus"
|
||||
|
||||
restart_cmd = '/etc/init.d/squid reload'
|
||||
|
||||
description = u'Bloquage accès http vers l\'extérieur, page expliquative'
|
||||
|
||||
def _gen(self) :
|
||||
virus = self._open_conf( self.BL_VIRUS )
|
||||
|
||||
if localtime()[1] == 9:
|
||||
# On est en septembre, on autorise ceux qui ont payé l'an dernier et cette année
|
||||
base = self.base.search('(paiement=%d|paiement=%d)' % (int(self.ann_scol),
|
||||
int(self.ann_scol) - 1))
|
||||
else:
|
||||
base = self.base.search('paiement=%s' % self.ann_scol)
|
||||
for machine in base['machine'] :
|
||||
self.anim.cycle()
|
||||
bl = machine.blacklist_actif()
|
||||
if 'bl_virus' in bl and not 'bloq' in bl :
|
||||
virus.write( machine.nom() + '\n')
|
||||
|
||||
virus.close()
|
372
gestion/gen_confs/switchs.py
Executable file
372
gestion/gen_confs/switchs.py
Executable file
|
@ -0,0 +1,372 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
""" met à jour les propriétés des prises des switchs du bat :
|
||||
mac autorisée(s), état (activé ou non) et nom de la prise
|
||||
argument : nom du switch
|
||||
|
||||
procédure de configuration initiale :
|
||||
* mot de passe admin (password manager user-name <username>)
|
||||
* upgrade firmware (copy tftp flash 138.231.136.7 <file>)
|
||||
* reboot (boot)
|
||||
* génération clef ssh (crypto key generate ssh)
|
||||
* copie fichier de conf (copy tftp startup-config 138.231.136.7 <file>)
|
||||
* faire le stacking et le snmpv3 à la main
|
||||
pour les reconfiguration juste copier le fichier de conf
|
||||
"""
|
||||
|
||||
import string, sys, os, commands
|
||||
|
||||
sys.path.append('/CRANS/code')
|
||||
#sys.path.append('/home/fred/Crans/zamok/CRANS/code')
|
||||
from hptools import hp
|
||||
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
from ldap_crans import crans_ldap, ann_scol
|
||||
from annuaires import chbre_prises #, uplink_prises, reverse
|
||||
from gen_confs import gen_config, OK, ERREUR, anim
|
||||
from time import localtime
|
||||
# from qqch import switchs # Liste des switchs
|
||||
bat_switchs = [ 'b', 'c', 'h', 'i', 'g' ]
|
||||
|
||||
class switch(gen_config) :
|
||||
def __init__(self,chbres):
|
||||
""" Chbre doit être une liste de chambres """
|
||||
self.db = crans_ldap()
|
||||
# On enlève la chambre "CRA"
|
||||
self.chbres = [ch for ch in chbres if ch != "CRA"]
|
||||
|
||||
def __str__(self) :
|
||||
return 'switchs'
|
||||
|
||||
def restart(self) :
|
||||
# Rien à faire ici
|
||||
pass
|
||||
|
||||
def gen_conf(self) :
|
||||
self.chbres.sort()
|
||||
for chbre in self.chbres :
|
||||
bat = chbre[0].lower()
|
||||
a = self.db.search('chbre=%s' % chbre)['adherent']
|
||||
action = ''
|
||||
for adh in a :
|
||||
if ((ann_scol in adh.paiement() or
|
||||
((ann_scol-1) in adh.paiement and localtime()[1]==9)) and
|
||||
'bloq' not in adh.blacklist_actif()) :
|
||||
# Il faut activer la prise
|
||||
anim('\tactivation chbre %s' % chbre)
|
||||
action = 'enable'
|
||||
break
|
||||
if action == '' :
|
||||
# Il faut désactiver la prise
|
||||
anim('\tdésactivation chbre %s' % chbre)
|
||||
action = 'disable'
|
||||
|
||||
try :
|
||||
if bat in bat_switchs :
|
||||
# Action sur le switch
|
||||
prise = chbre_prises[bat][chbre[1:].lower()]
|
||||
sw=hp(bat,int(prise[0]))
|
||||
r = sw.set_prise(int(prise[1:4]),'disable')
|
||||
sw.close()
|
||||
if not r :
|
||||
raise RuntimeError('Erreur de communiquation')
|
||||
else :
|
||||
# Mail au bat
|
||||
To = "bat%s@crans.org" % bat
|
||||
From = To
|
||||
conn=smtplib.SMTP('localhost')
|
||||
txt_mail = "From: Crans scripts <%(From)s>\n"
|
||||
txt_mail+= "To: %(To)s\n"
|
||||
txt_mail+= "Subject: Bienvenue au Cr@ns !\n\n"
|
||||
txt_mail+= "Chambre %s à débrancher." % chbre
|
||||
conn.sendmail(From, To , txt_mail % { 'From' : From, 'To' : To })
|
||||
conn.quit()
|
||||
print OK
|
||||
except :
|
||||
print ERREUR
|
||||
if self.debug :
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
### BROUILLON POUR PLUS TARD
|
||||
|
||||
class switch2(gen_config) :
|
||||
# Répertoire ou écire les fichiers de conf
|
||||
CONF_REP='/tmp/' # avec un / derrière
|
||||
|
||||
config = """; J4899A Configuration Editor; Created on release #H.07.32
|
||||
|
||||
hostname "%(switch)s"
|
||||
;-------------------------------------------------------- Snmp
|
||||
snmp-server contact "root@crans.org"
|
||||
snmp-server location "Batiment %(bat)s"
|
||||
;A faire à la main
|
||||
;snmpv3 enable
|
||||
;snmpv3 restricted-access
|
||||
;snmpv3 user "initial"
|
||||
;snmpv3 user "crans"
|
||||
;snmpv3 group ManagerPriv user "crans" sec-model ver3
|
||||
;snmp-server community "public" Operator
|
||||
;-------------------------------------------------------- Réglage heure/date
|
||||
time timezone 60
|
||||
time daylight-time-rule Western-Europe
|
||||
sntp server 138.231.136.6
|
||||
timesync sntp
|
||||
sntp unicast
|
||||
;-------------------------------------------------------- Misc
|
||||
console inactivity-timer 30
|
||||
;-------------------------------------------------------- Logs
|
||||
logging 138.231.136.7
|
||||
;-------------------------------------------------------- Logs
|
||||
%(INTERFACES_CONF)s
|
||||
;-------------------------------------------------------- IP du switch
|
||||
ip default-gateway 138.231.136.4
|
||||
vlan 1
|
||||
name "DEFAULT_VLAN"
|
||||
untagged 1-%(nb_prises)d
|
||||
ip address %(ip)s 255.255.248.0
|
||||
ip igmp
|
||||
no ip igmp querier
|
||||
exit
|
||||
;-------------------------------------------------------- Accès d'adminsitration
|
||||
no web-management
|
||||
aaa authentication ssh login public-key
|
||||
ip ssh
|
||||
ip ssh version 2
|
||||
ip authorized-managers 138.231.136.0 255.255.255.0
|
||||
ip authorized-managers 138.231.137.216
|
||||
ip authorized-managers 138.231.137.215
|
||||
;STACKING_CONF
|
||||
;-------------------------------------------------------- Spanning-tree
|
||||
spanning-tree
|
||||
; Config des uplinks
|
||||
no spanning-tree %(uplinks)s edge-port
|
||||
; Config des prises adhérent
|
||||
spanning-tree %(non_uplinks)s point-to-point-mac auto
|
||||
spanning-tree %(non_uplinks)s priority 15
|
||||
no cdp run
|
||||
;-------------------------------------------------------- Avec mot de passe ;)
|
||||
password manager
|
||||
"""
|
||||
|
||||
interface_template = """interface %(prise)i\n%(etat)s
|
||||
name %(nom)s
|
||||
flow-control%(speed)s
|
||||
no lacp
|
||||
exit
|
||||
"""
|
||||
filtre_mac_template = "port-security %(prise)i learn-mode static address-limit 3 mac-address%(macs)s\n"
|
||||
|
||||
nom = 'switchs'
|
||||
|
||||
def __str__(self) :
|
||||
return self.nom
|
||||
|
||||
def __init__(self,qqch='') :
|
||||
"""
|
||||
Si qqch='' : reconfigure tous les switchs
|
||||
Si qqch=<nom d'un switch> (batX-N) : reconfigure que ce switch
|
||||
Si qqch=<chambre> (XNNN) : regénère le fichier de conf du switch correspondant
|
||||
et reconfigure uniquement la prise """
|
||||
|
||||
# Traitement argument
|
||||
if not qqch :
|
||||
self.__params = {}
|
||||
elif qqch in switchs :
|
||||
self.__params = { 'bat' : qqch[3].lower() ,
|
||||
'sw_num' : qqch[5] ,
|
||||
'switch' : qqch.lower() }
|
||||
self.nom = 'switch %(switch)s' % self.__params
|
||||
else :
|
||||
# Ca doit être une chambre
|
||||
bat = qqch[0].lower()
|
||||
if bat in mail_bats :
|
||||
# Pas de switch à reconfigurer
|
||||
self.__params = { 'chbre' : qqch.capitalize() ,
|
||||
'bat' : bat }
|
||||
else :
|
||||
try :
|
||||
prise = chbre_prises[bat][qqch[1:]]
|
||||
self.__params = { 'nom_prise' : qqch.capitalize() ,
|
||||
'sw_prise' : int(prise[1:]) ,
|
||||
'bat' : bat ,
|
||||
'sw_num': int(prise[0]),
|
||||
'switch': 'bat%s-%s' % (bat, prise[0]) }
|
||||
self.nom = 'prise %s%s (chbre %s)' % (bat.upper(), prise,qqch)
|
||||
except :
|
||||
# Prise inconnue
|
||||
raise RuntimeError("Impossible d'associer une prise à la chambre.")
|
||||
|
||||
|
||||
def gen_conf(self) :
|
||||
""" Génération configuration :
|
||||
* soit d'un switch si présent dans self.__params
|
||||
* soit de tous les switchs si aucun présent dans self.__params
|
||||
* soit d'aucun switch si chbre dans bat non manageable, dans ce cas
|
||||
envoi un mail quand il faut aller débrancher et retourne 2
|
||||
En cas d'erreur retourne 1
|
||||
"""
|
||||
if self.__params.has_key('chbre') :
|
||||
# Pas de switch manageable, il suffit de mailer
|
||||
anim('\tmail à bat%(bat)s' % self.__params)
|
||||
print 'TODO'
|
||||
return 2
|
||||
|
||||
self.lock()
|
||||
|
||||
if self.__params.has_key('switch') :
|
||||
# Regénération de la conf d'un switch
|
||||
self.__gen_switch(self.__params)
|
||||
else :
|
||||
# Regénération de la conf de tous les switchs
|
||||
for switch in switchs :
|
||||
params = { 'bat' : switch[3].lower() ,
|
||||
'sw_num' : int(switch[5]) ,
|
||||
'switch' : switch.lower() }
|
||||
self.__gen_switch(params)
|
||||
|
||||
self.unlock()
|
||||
|
||||
def restart(self) :
|
||||
"""
|
||||
Si l'instance à été initialisée avec une chbre reconfigure cette chambre
|
||||
Sinon reconfigure le switch founi, si aucun fourni, les reconfigure tous
|
||||
"""
|
||||
if self.__params.has_key('chbre') :
|
||||
# Rien à faire, le mail doit être envoyé
|
||||
return
|
||||
|
||||
self.lock()
|
||||
|
||||
if self.__params.has_key('sw_prise') :
|
||||
# Utiliser la classe hptools et/ou faire du snmp
|
||||
anim('\treconfiguration prise' )
|
||||
|
||||
elif self.__params.has_key('switch') :
|
||||
# Restart d'un seul switch
|
||||
self.__restart_switch(self.__params['switch'])
|
||||
else :
|
||||
# Restart tous les switchs
|
||||
for switch in switchs :
|
||||
self.__restart_switch(switch)
|
||||
|
||||
self.unlock()
|
||||
|
||||
def __gen_switch(self,params) :
|
||||
""" params est un dictionnaire avec les keys bat, sw_num et switch """
|
||||
aff = anim('\tgénération de %(switch)s.conf' % params)
|
||||
|
||||
try :
|
||||
bat = params['bat']
|
||||
|
||||
# Nombre de prises
|
||||
nb_prises = """
|
||||
METTRE CA DANS LA CLASSE S'OCCUPANT DU SNMP
|
||||
try :
|
||||
nb = int(sys.argv[2])
|
||||
except :
|
||||
a=os.popen("snmpget -c public %s system.sysDescr.0 2>/dev/null" % switch)
|
||||
try :
|
||||
version = string.strip(string.split(string.split(a.readlines()[0],',')[0],'=')[1])
|
||||
except :
|
||||
version = ''
|
||||
a.close()
|
||||
if version == 'HP J4900A ProCurve Switch 2626' :
|
||||
nb=26
|
||||
elif version == 'HP J4899A ProCurve Switch 2650' :
|
||||
nb=50
|
||||
else :
|
||||
print "Erreur : impossible de déterminer le nombre de ports"
|
||||
sys.exit(1)
|
||||
"""
|
||||
nb_prises = 50
|
||||
params['nb_prises'] = nb_prises
|
||||
|
||||
# Récupération IP
|
||||
params['ip'] = commands.getoutput("host %s" % switch).split()[-1]
|
||||
|
||||
params['INTERFACES_CONF'] = ''
|
||||
params['MAC_FILTER'] = ''
|
||||
|
||||
# Dictionnaire prise -> chambre
|
||||
prise_chbres = reverse(bat)
|
||||
|
||||
# Configuration des prises
|
||||
mac_filter=[]
|
||||
aff.iter = nb_prises+1
|
||||
for prise in range(1,nb_prises+1):
|
||||
aff.cycle()
|
||||
|
||||
prise_params = { 'prise' : prise , 'speed' : '', 'etat' : '' }
|
||||
annu_prise = '%i%02i' % (params['sw_num'], prise)
|
||||
|
||||
if uplink_prises[bat].has_key(int(annu_prise)) :
|
||||
### Prise d'uplink
|
||||
prise_params['nom'] = uplink_prises[bat][int(annu_prise)]
|
||||
try : params['uplinks'] += ',%i' % prise
|
||||
except : params['uplinks'] = str(prise)
|
||||
else :
|
||||
### Prise adhérent
|
||||
try : params['non_uplinks'] += ',%i' % prise
|
||||
except : params['non_uplinks'] = str(prise)
|
||||
|
||||
if prise_chbres.has_key(annu_prise) :
|
||||
chbres = prise_chbres[annu_prise]
|
||||
elif prise_chbres.has_key(annu_prise+'-') :
|
||||
# Prise en 10
|
||||
prise_params['speed'] = ' speed-duplex auto-10\n'
|
||||
chbres = prise_chbres[annu_prise+'-']
|
||||
else :
|
||||
# Prise non référencée dans l'annuaire
|
||||
prise_params['nom'] = "Pas_dans_l'annuaire"
|
||||
prise_params['etat']=' disable\n'
|
||||
chbres = []
|
||||
|
||||
if chbres :
|
||||
prise_params['nom'] = 'Chambre'
|
||||
if len(chbres) > 1 :
|
||||
prise_params['nom'] += 's'
|
||||
|
||||
for chbre in chbres :
|
||||
prise_params['nom'] += '_' + chbre
|
||||
|
||||
# Etat
|
||||
macs = ''
|
||||
machines = self.base.search('chbre=%s%s' % (bat.upper(), chbre) )['machine']
|
||||
for m in machines :
|
||||
if 'bloq' in m.blacklist_actif() : continue
|
||||
macs += ' ' + m.mac()
|
||||
if not macs :
|
||||
prise_params['etat']=' disable\n'
|
||||
else :
|
||||
params['MAC_FILTER'] += self.filtre_mac_template % vars()
|
||||
|
||||
params['INTERFACES_CONF'] += self.interface_template % prise_params
|
||||
|
||||
# Petites verif
|
||||
if not params.has_key('uplinks') or not params.has_key('non_uplinks') :
|
||||
raise RuntimeError('Switch sans uplink ou sans prise adhérent.')
|
||||
|
||||
fd = self._open_conf(self.CONF_REP + 'switch' + '.conf')
|
||||
fd.write(self.config % params)
|
||||
fd.close()
|
||||
|
||||
aff.reinit()
|
||||
print OK
|
||||
|
||||
except :
|
||||
aff.reinit()
|
||||
self._restore()
|
||||
return 1
|
||||
|
||||
def __restart_switch(self,switch) :
|
||||
anim('\trestart %s' % switch)
|
||||
try :
|
||||
print 'TODO'
|
||||
except :
|
||||
print ERREUR
|
||||
if self.debug :
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return 1
|
1540
gestion/gest_crans.py
Executable file
1540
gestion/gest_crans.py
Executable file
File diff suppressed because it is too large
Load diff
93
gestion/iptools.py
Executable file
93
gestion/iptools.py
Executable file
|
@ -0,0 +1,93 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
"""
|
||||
Manipulation d'IPv4
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
def QuadToDec(ip) :
|
||||
"""
|
||||
Retourne la représentation décimale d'une ip
|
||||
ip est de la forme xxx.xxx.xxx.xxx
|
||||
"""
|
||||
test = ip.split('.')
|
||||
if len(test)!=4 : raise ValueError('IP Invalide')
|
||||
ip_dec = 0
|
||||
for z in range(0,4) :
|
||||
n = int(test[z])
|
||||
if n<0 or n>255 : raise ValueError('IP Invalide')
|
||||
ip_dec += n * ( 256**(3-z) )
|
||||
|
||||
return ip_dec
|
||||
|
||||
def DecToQuad(ip_dec) :
|
||||
"""
|
||||
Retourne la représentation habituelle d'une ip (xxx.xxx.xxx.xxx)
|
||||
ip_dec est l'IP en base 10
|
||||
"""
|
||||
try :
|
||||
return "%d.%d.%d.%d" % ( \
|
||||
ip_dec/(256**3) ,
|
||||
(ip_dec%(256**3)) / (256**2) ,
|
||||
( (ip_dec%(256**3)) % (256**2) ) / 256 ,
|
||||
( (ip_dec%(256**3)) % (256**2) ) % 256 )
|
||||
except :
|
||||
raise ValueError('IP Invalide')
|
||||
|
||||
def param(net) :
|
||||
"""
|
||||
net est un résau fourni sous la forme xxx.xxx.xxx.xxx/yy
|
||||
si donnée valide retourne un dictionnaire :
|
||||
{ 'network' : xxx.xxx.xxx.xxx ,
|
||||
'netmask' : yyy.yyy.yyy.yyy ,
|
||||
'broadcast' : zzz.zzz.zzz.zzz }
|
||||
sinon retourne {}
|
||||
"""
|
||||
reseau = {}
|
||||
ip, mask = net.split('/')
|
||||
|
||||
try :
|
||||
mask = int(mask)
|
||||
dec_ip = QuadToDec(ip)
|
||||
if dec_ip == -1 : raise
|
||||
except :
|
||||
return {}
|
||||
|
||||
# Calcul du netmask
|
||||
dec_netmask=0
|
||||
non_dec_netmask=0 # On calcule aussi le complémentaire
|
||||
for i in range(0,32) :
|
||||
if i < mask :
|
||||
dec_netmask += 2**(31-i)
|
||||
else :
|
||||
non_dec_netmask += 2**(31-i)
|
||||
|
||||
reseau['netmask'] = DecToQuad(dec_netmask)
|
||||
|
||||
# Calcul du network
|
||||
reseau['network'] = DecToQuad( dec_ip & dec_netmask )
|
||||
|
||||
# Calcul du broadcast
|
||||
reseau['broadcast'] = DecToQuad( dec_ip | non_dec_netmask )
|
||||
return reseau
|
||||
|
||||
def AddrInNet(ip,net) :
|
||||
"""
|
||||
ip est de la forme xxx.xxx.xxx.xxx
|
||||
net est de la forme xxx.xxx.xxx.xxx/yy
|
||||
net peut être une liste de chaînes ci-dessus
|
||||
Retourne True si l'ip est dans un des réseaux.
|
||||
Note : retourne Fasle si l'IP est une adresse de réseau ou broadcast
|
||||
"""
|
||||
if type(net)==str : net = [ net ]
|
||||
|
||||
r = False
|
||||
for ne in net :
|
||||
n = param(ne)
|
||||
if ip == n['broadcast'] or ip ==n['network'] :
|
||||
return False
|
||||
r = r or QuadToDec(n['netmask']) & QuadToDec(ip) == QuadToDec(n['network'])
|
||||
|
||||
return r
|
1909
gestion/ldap_crans.py
Executable file
1909
gestion/ldap_crans.py
Executable file
File diff suppressed because it is too large
Load diff
50
gestion/lock.py
Executable file
50
gestion/lock.py
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
""" Gestion de lock
|
||||
|
||||
Copyright (C) Frédéric Pauget
|
||||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
import os,string,time,sys,pwd, affich_tools
|
||||
|
||||
def make_lock(lock_name, lock_comment='') :
|
||||
""" Création d'un lock """
|
||||
lock_file = '/var/lock/' + lock_name
|
||||
if os.path.isfile(lock_file) :
|
||||
### Lock existant
|
||||
|
||||
# Lecture du lock
|
||||
fd = open(lock_file, "r")
|
||||
pid= fd.readline().strip()
|
||||
fd.close()
|
||||
|
||||
# Informations sur le processus lockant
|
||||
if os.system( "ps %s > /dev/null 2>&1" % pid ) :
|
||||
# Le script lockant ne tourne plus
|
||||
os.remove(lock_file)
|
||||
else :
|
||||
# Il faut attendre
|
||||
a = affich_tools.anim('\tattente du lock')
|
||||
for i in range(8) :
|
||||
time.sleep(1)
|
||||
a.cycle()
|
||||
sys.stdout.write('\r')
|
||||
return make_lock(lock_name, lock_comment)
|
||||
|
||||
### Prise du lock
|
||||
lock_fd=open(lock_file, "w")
|
||||
lock_fd.write("%s\n%s\n%s" % (os.getpid(), pwd.getpwuid(os.getuid())[0], lock_comment) )
|
||||
lock_fd.close()
|
||||
|
||||
def remove_lock( lock_name ) :
|
||||
""" Destruction du lock """
|
||||
lock_file = '/var/lock/' + lock_name
|
||||
try :
|
||||
fd = open(lock_file, "r")
|
||||
if fd.readline().strip()=="%s" % os.getpid():
|
||||
os.remove(lock_file)
|
||||
fd.close()
|
||||
except :
|
||||
None
|
69
gestion/secours.py
Executable file
69
gestion/secours.py
Executable file
|
@ -0,0 +1,69 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
# Fichiers à modifier et chaine indiquant un commentaire dans ceux-ci
|
||||
fichiers = { '/etc/bind/named.conf.options' : '//' ,
|
||||
'/etc/postfix/main.cf' : '#' }
|
||||
|
||||
import sys, sre
|
||||
|
||||
def edit(file,comment,secours) :
|
||||
""" Edite le fichier fourni en commentant (mode normal)
|
||||
ou décommentant (mode secours) les lignes se terminant avec #POUR SECOURS """
|
||||
|
||||
signal = '#POUR SECOURS'
|
||||
l = len(signal)
|
||||
|
||||
fd = open(file)
|
||||
line = fd.readline()
|
||||
new = ''
|
||||
while line :
|
||||
l = line.rstrip()
|
||||
if sre.match('.*'+signal+'$',l) :
|
||||
# Ligne pour secours
|
||||
if not sre.match('^' + comment,l) and not secours:
|
||||
# On est actuellement configuré en secours
|
||||
# Il faut passer en normal
|
||||
new += comment + line
|
||||
elif sre.match('^' + comment,l) and secours :
|
||||
# On est actuellement configuré en normal
|
||||
# Il faut passer en secours
|
||||
new += line.replace(comment,'',1)
|
||||
else :
|
||||
# Rien à faire, on est bien configuré
|
||||
new += line
|
||||
else :
|
||||
# Ligne normale
|
||||
new += line
|
||||
|
||||
line = fd.readline()
|
||||
|
||||
fd.close()
|
||||
|
||||
# Ecriture de la nouvelle version
|
||||
fd = open(file,'w')
|
||||
fd.write(new)
|
||||
fd.close()
|
||||
|
||||
|
||||
def usage() :
|
||||
print 'Usage : %s 0 pour reconfigurer les services locaux en normal' % sys.argv[0]
|
||||
print ' %s 1 pour reconfigurer les services locaux en secours' % sys.argv[0]
|
||||
print 'Fichiers modifiés par le changement de mode : \n\t', '\n\t'.join(fichiers.keys())
|
||||
|
||||
if __name__ == '__main__' :
|
||||
if len(sys.argv) != 2 :
|
||||
usage()
|
||||
else :
|
||||
mode = sys.argv[1]
|
||||
if mode not in '01' :
|
||||
usage()
|
||||
else :
|
||||
mode = int(mode)
|
||||
for f, c in fichiers.items() :
|
||||
try :
|
||||
print 'Edition de %s' % f
|
||||
edit(f,c,mode)
|
||||
except :
|
||||
import traceback
|
||||
traceback.print_exc()
|
759
gestion/whos.py
Executable file
759
gestion/whos.py
Executable file
|
@ -0,0 +1,759 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
|
||||
# Copyright (C) Frédéric Pauget
|
||||
# Licence : GPLv2
|
||||
|
||||
"""Ce script permet de recherche et d'afficher le détail d'une machine ou
|
||||
d'un adhérent.
|
||||
|
||||
Usage: %(prog)s [options] <chaine de recherche>
|
||||
|
||||
La chaine de recherche peut être :
|
||||
* soit un terme unique, dans ce cas la recherche sera effectuée sur les
|
||||
champs en bleu ci-dessous.
|
||||
* soit du type "champ1=valeur1&champ2!=valeur2 ...", les résultats seront
|
||||
alors limités aux entrées correspondantes à tous les critères.
|
||||
|
||||
Les champs de recherche possibles sont :
|
||||
%(champs_rech)s
|
||||
|
||||
Les options de recherches sont :
|
||||
* limitations sur la recherche :
|
||||
-a ou --adherent : limitation de la recherche aux adhérents
|
||||
-m ou --machine : limitation de la recherche aux machines
|
||||
-c ou --club : limitation de la recherche aux clubs
|
||||
-b ou --bornes : limitation de la recherche aux bornes wifi
|
||||
* options d'affichage :
|
||||
-t ou --tech : affichages des infos techniques des machines
|
||||
à la place des infos administratives dans les résumés.
|
||||
-i ou --ipsec : montre la clef ipsec des machines wifi
|
||||
-l <num> ou --limit=<num> : limite du nombre de résultats pour utiliser
|
||||
le mode d'affichage condensé au lieu du mode détaillé (défaut %(limit_aff_details)i)
|
||||
-L <num> ou --limit-historique=<num> : limitation du nombre de lignes
|
||||
d'historique affichées (défaut %(limit_aff_historique)i)
|
||||
|
||||
"""
|
||||
|
||||
from ldap_crans import is_actif , crans_ldap, isadm, ann_scol
|
||||
from affich_tools import *
|
||||
|
||||
limit_aff_details = 1
|
||||
limit_aff_historique = 4
|
||||
aff_ipsec = 0
|
||||
|
||||
def aff(qqch,mtech=0) :
|
||||
""" Affichage de qqch.
|
||||
qqch peut être une liste d'instances des classes adhérent ou machine
|
||||
(un seul type dans la liste) dans ce cas :
|
||||
* si la longueur de la liste est inférieure à limit_aff_details
|
||||
affiche les propriétés détaillées de chaque élément.
|
||||
* sinon résume dans un tabeau des principales propriétés
|
||||
si qqch est une instance seul la traité comme une liste à une élément
|
||||
Si mtech = 1 affiches les infomations techniques des machines plutot
|
||||
qu'administratives dans le tableau des propriétés
|
||||
"""
|
||||
if type(qqch) != list :
|
||||
qqch = [ qqch ]
|
||||
|
||||
if len(qqch) > limit_aff_details :
|
||||
t = qqch[0].idn
|
||||
if t == 'aid' :
|
||||
print adhers_brief(qqch)
|
||||
elif t == 'mid' :
|
||||
if mtech : print list_machines(qqch)
|
||||
else : print machines_brief(qqch)
|
||||
elif t == 'cid' :
|
||||
print clubs_brief(qqch)
|
||||
else :
|
||||
i = 0
|
||||
for c in qqch :
|
||||
t = c.idn
|
||||
if i : print coul(u'='*80,'cyan')
|
||||
i = 1
|
||||
if t == 'aid' : print adher_details(c)
|
||||
elif t == 'mid' :
|
||||
print machine_details(c)
|
||||
elif t == 'cid' : print club_details(c)
|
||||
|
||||
def adhers_brief(adhers) :
|
||||
"""
|
||||
Formatage sous forme de tableau des infos sur la liste d'adhérent fournie :
|
||||
* aid
|
||||
* prénom nom
|
||||
* chambre
|
||||
* machines
|
||||
"""
|
||||
data = [ ( u'aid' , u'Prénom Nom' , u'Chbre', u'P', u'C', u'Machines' ) ]
|
||||
|
||||
for a in adhers :
|
||||
## Etat administratif
|
||||
ok = u'\x1b[1;32mo\x1b[1;0m'
|
||||
nok = u'\x1b[1;31mn\x1b[1;0m'
|
||||
# Paiement
|
||||
if ann_scol in a.paiement() : paid = ok
|
||||
else : paid = nok
|
||||
|
||||
# Précablage
|
||||
if ann_scol+1 in a.paiement() : paid = coul(paid,'f_vert')
|
||||
|
||||
# Carte d'étudiant
|
||||
if ann_scol in a.carteEtudiant() : carte = ok
|
||||
else : carte = nok
|
||||
|
||||
machines = ''
|
||||
# Récupération des machines
|
||||
for machine in a.machines() :
|
||||
nom = machine.nom().split('.')[0]
|
||||
if machine.blacklist_actif() : k = 'rouge'
|
||||
else : k= ''
|
||||
if machines : machines += ', ' + coul(nom,k)
|
||||
else : machines = coul(nom,k)
|
||||
|
||||
# Données
|
||||
data.append((a.id() , a.Nom(), a.chbre(),paid,carte,machines ))
|
||||
|
||||
return u"Machines en rouge = machines avec limitation de services\n" + \
|
||||
u"P : paiement année en cours, le fond vert indique le précâblage\n" + \
|
||||
u"C : carte d'étudiant année en cours\n" + \
|
||||
tableau([5, 30 , 5, 1, 1,30], data)
|
||||
|
||||
def machines_brief(machines) :
|
||||
"""
|
||||
Formatage sous forme d'un tableau des propriétés de la liste de machine :
|
||||
* mid
|
||||
* type (fixe ou wifi, born)
|
||||
* nom
|
||||
* adresse IP
|
||||
* adresse MAC
|
||||
* si blacklistée
|
||||
"""
|
||||
data = [ ( u'mid' , u'Type', u'Nom de machine', u'Propriétaire', u'Chbre', u'Limitation' ) ]
|
||||
|
||||
for m in machines :
|
||||
t, bl = __bases_machines(m)
|
||||
|
||||
# Propriétaire
|
||||
a = m.proprietaire()
|
||||
p = a.Nom()
|
||||
|
||||
# A jour administrativement
|
||||
if ann_scol not in a.paiement() or ann_scol not in a.carteEtudiant() :
|
||||
p = coul(p,'rouge')
|
||||
|
||||
# Données
|
||||
data.append((m.id() , t, m.nom().split('.')[0], p, a.chbre(), bl))
|
||||
|
||||
return u"Le propriétaire en rouge signale un problème administratif\n" + \
|
||||
tableau([5, 4, 18, 30, 5, 10], data)
|
||||
|
||||
def clubs_brief(clubs) :
|
||||
"""
|
||||
Formatage sous forme de tableau des infos sur la liste de clubs fournie :
|
||||
* cid
|
||||
* nom
|
||||
* local
|
||||
* machines
|
||||
"""
|
||||
data = [ ( u'cid' , u'Nom ', u'Local',u'P', u'Responsable', u'Machines' ) ]
|
||||
|
||||
for c in clubs :
|
||||
## Etat administratif
|
||||
ok = u'\x1b[1;32m\xa4\x1b[1;0m'
|
||||
nok = u'\x1b[1;31m\xa4\x1b[1;0m'
|
||||
# Paiement
|
||||
if ann_scol in c.paiement() : paid = ok
|
||||
else : paid = nok
|
||||
|
||||
# Précablage
|
||||
if ann_scol+1 in c.paiement() : paid = coul(paid,'f_vert')
|
||||
|
||||
machines = ''
|
||||
# Récupération des machines
|
||||
for machine in c.machines() :
|
||||
nom = machine.nom().split('.')[0]
|
||||
if machine.blacklist_actif() : k = 'rouge'
|
||||
else : k= ''
|
||||
if machines : machines += ', ' + coul(nom,k)
|
||||
else : machines = coul(nom,k)
|
||||
|
||||
# Responsable
|
||||
resp = c.responsable().Nom()
|
||||
|
||||
# Données
|
||||
data.append((c.id() , c.Nom(), c.local(),paid, resp, machines ))
|
||||
|
||||
return u"Machines en rouge = machines avec limitation de services\n" + \
|
||||
u"P : signature charte année en cours, le fond vert indique le précâblage\n" + \
|
||||
tableau([5, 15 , 6, 1, 21, 24], data)
|
||||
|
||||
|
||||
def list_machines(machines) :
|
||||
"""
|
||||
Formatage sous forme d'un tableau des propriétés de la liste de machine :
|
||||
* mid
|
||||
* type (fixe ou wifi)
|
||||
* nom
|
||||
* adresse IP
|
||||
* adresse MAC
|
||||
* si blacklistée
|
||||
"""
|
||||
data = [ ( u'mid' , u'Type', u'Nom de machine', u'Adresse IP', u'Adresse MAC', u'Limitation' ) ]
|
||||
|
||||
for m in machines :
|
||||
t, bl = __bases_machines(m)
|
||||
|
||||
# Données
|
||||
data.append((m.id() , t, m.nom().split('.')[0], m.ip(), m.mac(), bl))
|
||||
|
||||
return tableau([5, 4, 18, 17, 19, 10], data)
|
||||
|
||||
def list_bornes(bornes) :
|
||||
"""
|
||||
Formatage sous forme d'un tableau des propriétés de la liste de bornes wifi :
|
||||
* mid
|
||||
* nom
|
||||
* adresse IP
|
||||
* adresse MAC
|
||||
* puissance
|
||||
* canal
|
||||
* lieu (la première remarque en fait)
|
||||
"""
|
||||
p = u'**'
|
||||
|
||||
if isadm : p = u'P'
|
||||
|
||||
data = [ ( u'mid' , u'Nom', u'Adresse IP', u'Adresse MAC', u'C' , p, u'Lieu') ]
|
||||
|
||||
for b in bornes :
|
||||
t, bl = __bases_machines(b)
|
||||
if t != 'born' : continue
|
||||
|
||||
if isadm :
|
||||
p = b.puissance()
|
||||
|
||||
# Données
|
||||
data.append((b.id() , b.nom().split('.')[0], b.ip(), b.mac(), b.canal(), p, b.info()[0] ))
|
||||
|
||||
if isadm :
|
||||
t = u"C=canal, P=puissance\n"
|
||||
else :
|
||||
t = u"C=canal\n"
|
||||
|
||||
return t + tableau([5, 14, 17, 19, 2, 2, 13], data)
|
||||
|
||||
def adher_details(adher) :
|
||||
"""
|
||||
Affichage du détail des propriétés d'un adhérent
|
||||
"""
|
||||
f=''
|
||||
# Aid
|
||||
f+= coul(u'aid=%s ' % adher.id() ,'bleu')
|
||||
# Nom, prenom
|
||||
f += coul(u'Nom : ','gras') + "%s\n" % adher.Nom()
|
||||
|
||||
# Mail
|
||||
if adher.mail().find('@')!=-1 :
|
||||
f += coul(u'Adresse mail : ','gras') + "%s" % adher.mail()
|
||||
else :
|
||||
f += coul(u'Login : ','gras') + "%s\t" % adher.mail()
|
||||
alias = ', '.join([adher.cannonical_alias()] + adher.alias())
|
||||
if alias :
|
||||
if alias[0]==',' :
|
||||
# Cannonical étéait vide
|
||||
alias = alias[2:]
|
||||
f += coul(u'Alias : ','gras') + alias
|
||||
f+= u'\n'
|
||||
|
||||
# Etat administratif
|
||||
f += coul(u'Etat administratif : ','gras')
|
||||
jour=1
|
||||
if ann_scol not in adher.carteEtudiant() :
|
||||
f += coul(u"manque carte d'étudiant",'violet')
|
||||
jour = 0
|
||||
if ann_scol not in adher.paiement() :
|
||||
if not jour : f += ' et '
|
||||
f += coul(u"cotisation %s/%d non réglée"% (ann_scol, ann_scol+1 ),'violet')
|
||||
jour = 0
|
||||
|
||||
if jour :
|
||||
f += coul(u"à jour",'vert')
|
||||
f += '\n'
|
||||
|
||||
# Telephone
|
||||
tel = adher.tel()
|
||||
try :
|
||||
tel = u'%s %s %s %s %s' % ( tel[:2], tel[2:4], tel[4:6], tel[6:8], tel[8:] )
|
||||
except :
|
||||
None
|
||||
f += coul(u'Numéro de téléphone : ','gras') + "%s\n" % tel.ljust(12)
|
||||
|
||||
# Adresse
|
||||
chbre = adher.chbre()
|
||||
if chbre == 'EXT' :
|
||||
# Adhérent extérieur
|
||||
f += coul(u'Adresse : ','gras')
|
||||
addr = adher.adresse()
|
||||
f += addr[0] + u'\n'
|
||||
if addr[1] != ' ' : f += u' ' + addr[1] + u'\n'
|
||||
f+= u' ' + addr[2] + u' ' + addr[3]
|
||||
else :
|
||||
# Chambre + prise (d'après annuaire)
|
||||
f += coul(u'Chambre : ','gras') + u"%s " % chbre
|
||||
prise = adher.prise()
|
||||
if prise :
|
||||
f += u'(prise %s)' % prise
|
||||
f += '\n'
|
||||
|
||||
# Etudes
|
||||
if adher.etudes(1).isdigit() :
|
||||
f += coul(u'Etudes : ','gras')+ "%s %s%s\n" % \
|
||||
( adher.etudes(0), adher.etudes(1), adher.etudes(2) )
|
||||
else :
|
||||
f += coul(u'Etudes : ','gras')+ "%s %s %s\n" % \
|
||||
( adher.etudes(0), adher.etudes(1), adher.etudes(2) )
|
||||
|
||||
# Role dans l'assoce
|
||||
d = adher.droits()
|
||||
if d :
|
||||
f += coul(u"Droits sur les serveurs : ",'gras') + ', '.join(d)
|
||||
f += u'\n'
|
||||
|
||||
# Paiement
|
||||
if adher.paiement() :
|
||||
if len(adher.paiement()) == 1 :
|
||||
f += coul(u'Cotisation payée pour l\'année scolaire :','gras')
|
||||
else :
|
||||
f += coul(u'Cotisation payée pour les années scolaires :','gras')
|
||||
g = u''
|
||||
for an in adher.paiement() : g += u" %i-%i" % ( an, an+1 )
|
||||
if len(g) > 35 : f += '\n\t'
|
||||
f += g
|
||||
f += u'\n'
|
||||
|
||||
# Cartes d'étudiant fournie
|
||||
if adher.carteEtudiant() :
|
||||
if len(adher.carteEtudiant()) == 1 :
|
||||
f += coul(u"Carte d'étudiant fournie pour l'année scolaire :",'gras')
|
||||
else :
|
||||
f += coul(u"Carte d'étudiant fournie pour les années scolaires :",'gras')
|
||||
g = u''
|
||||
for an in adher.carteEtudiant() : g += u" %i-%i" % ( an, an+1 )
|
||||
if len(g) > 25 : f += '\n\t'
|
||||
f += g
|
||||
f += u'\n'
|
||||
|
||||
f += _blacklist(adher)
|
||||
f += _info(adher)
|
||||
f += _hist(adher)
|
||||
|
||||
# Formatage des machines aussi
|
||||
f += coul(u'Machine(s) : ','gras')
|
||||
m = adher.machines()
|
||||
if m :
|
||||
f += u'\n' + list_machines(m)
|
||||
else :
|
||||
f += u'aucune'
|
||||
|
||||
return f
|
||||
|
||||
def machine_details(machine) :
|
||||
"""
|
||||
Formatage du détail des propriétés d'une machine
|
||||
"""
|
||||
f = ''
|
||||
f+= coul(u'mid=%s ' % machine.id(),'bleu')
|
||||
|
||||
# Type de machine
|
||||
if machine.ipsec() : a='Machine wifi'
|
||||
elif machine.canal() : a='Borne wifi'
|
||||
else : a='Machine fixe'
|
||||
f+= coul(a+' : ' ,'gras')
|
||||
|
||||
f+= "%s\n" % machine.nom()
|
||||
|
||||
# Alias ?
|
||||
alias = machine.alias()
|
||||
if machine.alias() :
|
||||
f += coul(u'Alias : ' ,'gras') + ', '.join(alias)
|
||||
f+= '\n'
|
||||
|
||||
f+= coul(u'IP : ','gras') + "%s\t\t" %machine.ip()
|
||||
f+= coul(u'MAC : ','gras') + "%s\n" %machine.mac()
|
||||
|
||||
# Propriétaire
|
||||
a = machine.proprietaire()
|
||||
f+= coul(u'Propriétaire : ','gras')
|
||||
f += "%s" % a.Nom()
|
||||
if a.chbre() : f += " (%s)" % a.chbre()
|
||||
f+= '\n'
|
||||
|
||||
# Adhérent blacklisté ?
|
||||
bl = a.blacklist_actif()
|
||||
if bl :
|
||||
f += coul(u'Restrictions sur adhérent : ','gras')
|
||||
f += coul(u', '.join(bl),'rouge')
|
||||
f += '\n'
|
||||
|
||||
# Borne wifi
|
||||
if isadm and machine.puissance() :
|
||||
f += coul(u'Puissance : ','gras') + machine.puissance()
|
||||
f += coul(u'\tCanal : ', 'gras') + machine.canal()
|
||||
f += '\n'
|
||||
|
||||
if aff_ipsec and machine.ipsec() :
|
||||
f += coul(u'Clef IPsec : ','gras') + machine.ipsec()
|
||||
f += '\n'
|
||||
|
||||
# Ports spéciaux
|
||||
if machine.portTCPin() :
|
||||
f += coul(u'Ports TCP ouvert ext->machine : ','gras') + machine.portTCPin() + '\n'
|
||||
if machine.portTCPout() :
|
||||
f += coul(u'Ports TCP ouvert machine->ext : ','gras') + machine.portTCPout() + '\n'
|
||||
if machine.portTCPin() :
|
||||
f += coul(u'Ports UDP ouvert ext->machine : ','gras') + machine.portUDPin() + '\n'
|
||||
if machine.portUDPout() :
|
||||
f += coul(u'Ports UDP ouvert machine->ext : ','gras') + machine.portUDPout() + '\n'
|
||||
|
||||
f += _blacklist(machine)
|
||||
f += _info(machine)
|
||||
f += _hist(machine)
|
||||
|
||||
return f
|
||||
|
||||
def club_details(club) :
|
||||
"""
|
||||
Affichage du détail des propriétés d'un adhérent
|
||||
"""
|
||||
f=''
|
||||
# Cid
|
||||
f+= coul(u'cid=%s ' % club.id() ,'bleu')
|
||||
# Nom
|
||||
f += coul(u'Nom : ','gras') + "%s\n" % club.Nom()
|
||||
|
||||
# Etat administratif
|
||||
f += coul(u'Etat administratif : ','gras')
|
||||
jour=1
|
||||
if ann_scol not in club.paiement() :
|
||||
if not jour : f += ' et '
|
||||
f += coul(u"charte %s/%d non signée"% (ann_scol, ann_scol+1 ),'violet')
|
||||
jour = 0
|
||||
|
||||
if jour :
|
||||
f += coul(u"à jour",'vert')
|
||||
f += '\n'
|
||||
|
||||
# Chambre + prise
|
||||
f += coul(u'Local : ','gras') + "%s " % club.local()
|
||||
prise = club.prise()
|
||||
if prise :
|
||||
f += '(prise %s)' % prise
|
||||
f += '\n'
|
||||
|
||||
# Paiement
|
||||
if club.paiement() :
|
||||
f += coul(u'Charte signée pour les années scolaires :','gras')
|
||||
g = ''
|
||||
for an in club.paiement() : g += " %i-%i" % ( an, an+1 )
|
||||
if len(g) > 35 : f += '\n\t'
|
||||
f += g
|
||||
f += '\n'
|
||||
|
||||
f += _blacklist(club)
|
||||
f += _info(club)
|
||||
f += _hist(club)
|
||||
|
||||
# Formatage des machines aussi
|
||||
f += coul(u'Machine(s) : ','gras')
|
||||
m = club.machines()
|
||||
if m :
|
||||
f += '\n' + list_machines(m)
|
||||
else :
|
||||
f += 'aucune'
|
||||
|
||||
return f
|
||||
|
||||
###########################################
|
||||
# Fonctions annexes de formatage de données
|
||||
|
||||
def _blacklist(clas) :
|
||||
""" Formatage blackliste de la classe fournie """
|
||||
f = u''
|
||||
for event in clas.blacklist() :
|
||||
if is_actif(event) :
|
||||
# Colorisation si sanction en cours
|
||||
c = 'rouge'
|
||||
else :
|
||||
c = 'blanc'
|
||||
f += u"%s\n\t " % coul(u'du %s au %s : %s, %s' % tuple(event.split(',')) ,c)
|
||||
|
||||
f = f[:-6] # supression des espaces superflus
|
||||
|
||||
if f :
|
||||
return coul(u'Blackliste : ', 'gras') + f
|
||||
else :
|
||||
return ''
|
||||
|
||||
def _info(clas) :
|
||||
""" Formatage des remarques de la classe fournie """
|
||||
f= u''
|
||||
c = clas.info()
|
||||
if c :
|
||||
f += coul(u'Remarque :\n ' ,'gras')
|
||||
f += u'\n '.join(c)
|
||||
f += u'\n'
|
||||
return f
|
||||
|
||||
def _hist(clas) :
|
||||
""" Formatage de l'historique de la classe fournie """
|
||||
if limit_aff_historique==0 : return ''
|
||||
f=''
|
||||
h = clas.historique()
|
||||
h.reverse()
|
||||
if h :
|
||||
f += coul(u'Historique : ','gras')
|
||||
for i in range(0,limit_aff_historique) :
|
||||
try :
|
||||
a = h[i] # Produit une erreur si i trop grand
|
||||
if i !=0 : f += ' '
|
||||
f += '%s\n' % a
|
||||
except :
|
||||
break
|
||||
try :
|
||||
if h[i+1] : f += ' [...]\n'
|
||||
except :
|
||||
None
|
||||
|
||||
return f
|
||||
|
||||
def __bases_machines(m) :
|
||||
""" Retourne [ type de la machines, blacklist ] """
|
||||
#Type
|
||||
if m.ipsec() : t='wifi'
|
||||
elif m.canal() : t='born'
|
||||
else : t='fixe'
|
||||
|
||||
# Déconnectée ?
|
||||
b = m.blacklist_actif()
|
||||
if not b :
|
||||
bl = '-'
|
||||
elif len(b) == 1 :
|
||||
bl = coul(b[0],'rouge')
|
||||
else :
|
||||
bl = coul(u'cf détails','rouge')
|
||||
|
||||
return t , bl
|
||||
|
||||
##############################################################################
|
||||
## Partie dévolue au système de recherche
|
||||
|
||||
def __usage_brief(err='') :
|
||||
""" Message d'erreur """
|
||||
if err : cprint(err,'gras')
|
||||
print "Pour obtenir de l'aide sur l'utilisation de ce programme utilisez l'option -h"
|
||||
sys.exit(2)
|
||||
|
||||
def __usage() :
|
||||
""" Comment ca marche ? """
|
||||
list = ['']
|
||||
for c in base.auto_search_champs.values() :
|
||||
for champ in c :
|
||||
coul_champ = coul(champ,'bleu')
|
||||
if list[-1] == '' :
|
||||
list[-1] = coul_champ
|
||||
l = len(champ)
|
||||
else :
|
||||
l += len(champ) + 2
|
||||
if l < 80 :
|
||||
list[-1] += ', ' + coul_champ
|
||||
else :
|
||||
list.append(coul_champ)
|
||||
l = len(champ)
|
||||
|
||||
for c in base.non_auto_search_champs.values() :
|
||||
for champ in c :
|
||||
l += len(champ) + 2
|
||||
if l < 80 :
|
||||
list[-1] += ', ' + champ
|
||||
else :
|
||||
list.append(champ)
|
||||
l = len(champ)
|
||||
|
||||
print __doc__ % { 'prog' : sys.argv[0].split('/')[-1] ,
|
||||
'champs_rech' : '\n'.join(list) ,
|
||||
'limit_aff_details' : limit_aff_details ,
|
||||
'limit_aff_historique' : limit_aff_historique }
|
||||
sys.exit(0)
|
||||
|
||||
def __recherche() :
|
||||
"""
|
||||
Recherche et affichage des résultats à partir des options founies (sys.argv)
|
||||
"""
|
||||
global aff_ipsec, limit_aff_details, limit_aff_historique, debug
|
||||
|
||||
# Récupération des options
|
||||
if len(sys.argv) == 1 :
|
||||
# Pas d'option fournie
|
||||
__usage_brief()
|
||||
|
||||
try :
|
||||
options, arg = getopt.getopt(sys.argv[1:], 'hamctbil:L:', [ 'debug', 'help', 'adherent', 'machine', 'club' , 'tech', 'bornes', 'limit=', 'limit-historique=', 'ipsec' ])
|
||||
except getopt.error, msg :
|
||||
__usage_brief(msg)
|
||||
|
||||
# Traitement des options
|
||||
only_adh=0
|
||||
only_mac=0
|
||||
only_club=0
|
||||
only_bornes=0
|
||||
mtech = 0
|
||||
|
||||
for opt, val in options :
|
||||
if opt == '-h' or opt=='--help' :
|
||||
__usage()
|
||||
elif opt =='--debug' :
|
||||
# Mode debug
|
||||
debug = 1
|
||||
elif opt == '-l' or opt =='--limit':
|
||||
# Passage mode condensé, mode détaillé
|
||||
try : limit_aff_details = int(val)
|
||||
except :
|
||||
__usage_brief('Valeur du paramètre %s incorecte (doit être un entier positif)' % opt)
|
||||
elif opt == '-L' or opt =='--limit-historique':
|
||||
# Limitation du nombre de lignes d'historique
|
||||
try : limit_aff_historique = int(val)
|
||||
except :
|
||||
__usage_brief('Valeur du paramètre %s incorecte (doit être un entier positif)' % opt)
|
||||
elif opt in [ '-a', '--adherent' ] :
|
||||
only_adh = 1
|
||||
print "Recherche limitée aux adhérents."
|
||||
elif opt in [ '-m', '--machine' ] :
|
||||
only_mac = 1
|
||||
print "Recherche limitée aux machines."
|
||||
elif opt in [ '-c', '--club' ] :
|
||||
only_club = 1
|
||||
print "Recherche limitée aux clubs."
|
||||
elif opt in [ '-b', '--bornes' ] :
|
||||
only_bornes = 1
|
||||
print "Recherche limitée aux bornes wifi."
|
||||
# On va tenter de limiter un peu la recherche
|
||||
if arg[0] == '*' :
|
||||
# Recherche initiale sans critètre
|
||||
arg = [ 'canal=*' ]
|
||||
elif arg[0].find('=')!=-1 :
|
||||
# Recherche avec critères
|
||||
arg += [ 'canal=*' ]
|
||||
elif opt in [ '-t', '--tech' ] :
|
||||
# Format affichage des machines
|
||||
mtech = 1
|
||||
elif opt in [ '-i', '--ipsec' ] :
|
||||
# Affichage des clefs ipsec
|
||||
aff_ipsec = 1
|
||||
|
||||
if only_adh + only_mac + only_club + only_bornes > 1 :
|
||||
__usage_brief('Options utilisées incompatibles')
|
||||
|
||||
if not arg :
|
||||
# Pas de chaine de recherche fournie
|
||||
__usage_brief('Chaine de recherche incorrecte.')
|
||||
|
||||
try :
|
||||
res = base.search(' '.join(arg))
|
||||
except ValueError, c :
|
||||
__usage_brief(c.args[0])
|
||||
|
||||
# Traitement du résultat
|
||||
if not res['adherent'] and not res['machine'] and not res['club']:
|
||||
print "Aucun résultat trouvé."
|
||||
sys.exit(3)
|
||||
# L'affichage souhaité a été précisé ?
|
||||
elif only_bornes :
|
||||
if not res['machine'] :
|
||||
print 'Aucun résultat à afficher'
|
||||
sys.exit(4)
|
||||
else :
|
||||
if len(res['machine']) > limit_aff_details :
|
||||
print list_bornes(res['machine'])
|
||||
else :
|
||||
aff(res['machine'])
|
||||
elif only_adh :
|
||||
if res['adherent'] : aff(res['adherent'])
|
||||
elif res['machine'] :
|
||||
to_aff=[]
|
||||
traite =[]
|
||||
for m in res['machine'] :
|
||||
a = m.proprietaire()
|
||||
if a.idn != 'aid' or a.id() in traite : continue
|
||||
traite.append(a.id())
|
||||
to_aff.append(m.proprietaire())
|
||||
if not(to_aff) :
|
||||
print 'Aucun résultat à afficher'
|
||||
sys.exit(4)
|
||||
aff(to_aff)
|
||||
elif res['club'] :
|
||||
print 'Aucun résultat à afficher'
|
||||
sys.exit(4)
|
||||
elif only_mac :
|
||||
if res['machine'] : aff(res['machine'],mtech)
|
||||
else :
|
||||
to_aff = []
|
||||
for a in res['adherent'] + res['club'] :
|
||||
to_aff += a.machines()
|
||||
aff(to_aff)
|
||||
elif only_club :
|
||||
if res['club'] : aff(res['club'])
|
||||
elif res['machine'] :
|
||||
to_aff=[]
|
||||
traite =[]
|
||||
for m in res['machine'] :
|
||||
a = m.proprietaire()
|
||||
if a.idn != 'cid' or a.id() in traite : continue
|
||||
if a.id() in traite : continue
|
||||
traite.append(a.id())
|
||||
to_aff.append(m.proprietaire())
|
||||
if not(to_aff) :
|
||||
print 'Aucun résultat à afficher'
|
||||
sys.exit(4)
|
||||
aff(to_aff)
|
||||
elif res['adherent'] :
|
||||
print 'Aucun résultat à afficher'
|
||||
sys.exit(4)
|
||||
# Non : on affiche tout.
|
||||
else :
|
||||
if res['adherent'] :
|
||||
cprint("Résultats trouvés parmi les adhérents :",'cyan')
|
||||
aff(res['adherent'])
|
||||
if res['machine'] :
|
||||
cprint("Résultats trouvés parmi les machines :",'cyan')
|
||||
aff(res['machine'],mtech)
|
||||
if res['club']:
|
||||
cprint("Résultats trouvés parmi les clubs :",'cyan')
|
||||
aff(res['club'])
|
||||
|
||||
if __name__ == '__main__' :
|
||||
global debug
|
||||
debug = 0
|
||||
|
||||
import sys, getopt
|
||||
|
||||
base = crans_ldap()
|
||||
|
||||
try :
|
||||
__recherche()
|
||||
except KeyboardInterrupt :
|
||||
print "Recherche interrompue par l'utilisateur."
|
||||
sys.exit(255)
|
||||
except SystemExit, c :
|
||||
# Fin
|
||||
sys.exit(c)
|
||||
except :
|
||||
print """Une erreur fatale c'est produite durant l'exécution.
|
||||
Pour l'amélioration de ce programme merci de prévenir nounou en spécifiant la
|
||||
marche à suivre pour reproduire cette erreur."""
|
||||
if debug :
|
||||
print '-'*40
|
||||
print 'Détails techniques :'
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue