1
2
3
4
5
6
7
8
9
10
11
12
13 """fonctions utiles pour l'accès à la base de données (via adbapi)
14 """
15 from zephir.backend import config
16 from zephir.utils.creolewrap import ZephirDict
17 from zephir.backend.uucp_utils import UUCP
18 from zephir.monitor.agentmanager.util import md5files
19 from twisted.internet.utils import getProcessOutputAndValue
20 import psycopg2 as PgSQL
21 import os, sys, time, string, traceback
22 import base64
23 from glob import glob
24 import xmlrpclib, os
25
28
30 """dictionnaire des connexions postgresql en cours"""
31
37
43
49
51 cu.close()
52 self[cu].close()
53 del(self[cu])
54
55 cx_pool = CxPool()
56
58 """classe utilitaire pour récupérer diverses données sur un serveur"""
59
60 - def __init__(self, id_s, cu=None, data=None):
61 """initialise l'objet serveur et récupère les infos
62 """
63 self.version = 'creole2'
64
65 self.id_s = int(id_s)
66
67 self.modified=time.time()
68
69 self.created=time.time()
70 cursor = cu
71 if cu == None:
72 cursor = cx_pool.create()
73 try:
74 if data == None:
75
76 cursor.execute("select rne from serveurs where id=%s" % str(self.id_s))
77 data = cursor.fetchone()
78 self.rne = data[0]
79
80 self.update_data(cursor)
81 else:
82 self.rne = data[0]
83 self.confdir = os.path.join(config.PATH_ZEPHIR,'conf',self.rne, str(self.id_s))
84 if cu == None:
85 cx_pool.close(cursor)
86 except:
87 traceback.print_exc()
88 if cu == None:
89 cx_pool.close(cursor)
90
92 """recharge les données des serveurs
93 """
94
95 cursor = cu
96 if cu == None:
97 cursor = cx_pool.create()
98 try:
99 if data == None:
100 cursor.execute("select libelle, module_actuel, variante, timeout, etat, md5s, maj from serveurs where id=%s" % str(self.id_s))
101 data = cursor.fetchone()
102
103 self.libelle = data[0]
104 self.id_mod = int(data[1])
105 self.id_var = int(data[2])
106 try:
107 self.md5s = int(data[5])
108 except:
109 self.md5s = -1
110 try:
111 self.maj = int(data[6])
112 except:
113 self.maj = -1
114 try:
115 self.timeout = int(data[3])
116 except:
117 self.timeout = 0
118 if data[4] == None:
119 self.status = -1
120 else:
121 self.status = int(data[4])
122
123 cursor.execute("select libelle from etablissements where rne='%s'" % self.rne)
124 data = cursor.fetchone()
125 self.etab = data[0]
126
127 cursor.execute("select libelle from modules where id='%s'" % self.id_mod)
128 data = cursor.fetchone()
129 self.module = data[0]
130
131 if self.module in config.OLD_MODULES:
132 self.version = 'creole1'
133 else:
134 self.version = 'creole2'
135
136 cursor.execute("select libelle from variantes where id='%s'" % self.id_var)
137 data = cursor.fetchone()
138 self.variante = data[0]
139 self.modified = time.time()
140 if cu == None:
141 cx_pool.close(cursor)
142 except:
143 traceback.print_exc()
144 if cu == None:
145 cx_pool.close(cursor)
146
148 """affichage du serveur
149 """
150 return """%s => %s (%s)""" % (self.id_s, self.module, self.rne)
151
153 """affichage du serveur
154 """
155 return """%s => %s (%s) - %s (%s)""" % (self.id_s, self.libelle, self.module, self.etab, self.rne)
156
157
158
159
162
165
168
171
174
177
180
181 - def get_config(self, mode="modif_config", encode=False):
182 """retourne la configuration eole du serveur (zephir.eol)
183 """
184
185 if self.version == 'creole1':
186
187 creole_files = [self.confdir+os.sep+'dictionnaire']
188
189 creole_files.extend(glob(self.confdir+os.sep+'dicos/variante/*.eol'))
190
191 creole_files.extend(glob(self.confdir+os.sep+'dicos/*.eol'))
192 dicos = []
193 for dic in creole_files:
194 try:
195
196 fic = open(dic,'r')
197 lines = fic.readlines()
198 fic.close()
199 if encode == True:
200 data = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ]
201 else:
202 data = lines
203
204 dicos.append(data)
205 except OSError:
206 pass
207
208 if self.version == 'creole2':
209
210 dicos = []
211 for rep in ['module','local','variante']:
212 dicos.append(os.path.join(self.confdir,'dicos',rep))
213
214 dico = ZephirDict(dicos, self.confdir, mode, self.version)
215 return dico
216
217 - def save_config(self, dico_zeph, mode='config', encode=False):
218 """sauvegarde la configuration eole du serveur (zephir.eol)
219 """
220 try:
221 if mode in ['config','modif_config']:
222 fic_zephir = os.path.join(self.confdir,'zephir.eol')
223 key = 'config_ok'
224 elif mode in ['dico','modif_dico']:
225
226 fic_zephir = os.path.abspath(config.PATH_MODULES)+os.sep+str(self.id_mod)+os.sep+'variantes'+os.sep+str(self.id_var)+os.sep+'dico.eol'
227 key = 'dico_ok'
228 dico_zeph.save(fic_zephir,encode=encode)
229 self.maj_params({key:1})
230 self.check_md5conf()
231 except:
232 raise IOError("serveur %s : erreur de sauvegarde de %s" % (self.id_s, os.path.basename(fic_zephir)))
233 return ""
234
236 """renvoie le dernier état enregistré du serveur
237 """
238 try:
239 assert self.status in range (5)
240 except:
241 return -1
242 else:
243 return self.status
244
257
259 """renvoie le champ paramètres du serveur
260 """
261 try:
262 if params is None:
263 cu = cx_pool.create()
264 try:
265 cu.execute("select params from serveurs where id=%s" % str(self.id_s))
266 data = cu.fetchone()
267 cx_pool.close(cu)
268 except:
269 traceback.print_exc()
270 cx_pool.close(cu)
271 params = {}
272 try:
273 params = eval(data[0])
274 assert type(params) == dict and params.has_key('md5s')
275 except:
276
277 params = self.update_params(params)
278
279 self.save_params(params)
280 else:
281 if type(params) == str:
282 params = eval(params)
283
284
285 id_uucp = self.rne+'-'+str(self.id_s)
286 params['uucp_transfert']=0
287 params['uucp_cmd']=0
288 if os.path.isdir('/var/spool/uucp/%s/D.' % id_uucp):
289 params['uucp_transfert']=len(os.listdir('/var/spool/uucp/%s/D.' % id_uucp))
290 if os.path.isdir('/var/spool/uucp/%s/D.X' % id_uucp):
291 params['uucp_cmd']=len(os.listdir('/var/spool/uucp/%s/D.X' % id_uucp))
292
293 if params['config_ok'] == 0:
294 if os.path.isfile(self.confdir+os.sep+'zephir.eol'):
295 params['config_ok']=1
296 if params['dico_ok'] == 0:
297 if os.path.isfile(self.confdir+os.sep+'dico.eol'):
298 params['dico_ok']=1
299 return params
300 except:
301 traceback.print_exc()
302 return {}
303
305
306 if 'id' in dico_modifs.keys():
307 return 0, config.u("""l'identifiant ne peut pas être modifié""")
308
309 if 'rne' in dico_modifs.keys():
310 return 0, config.u("""le rne ne peut pas être modifié""")
311
312 if ('module_actuel' in dico_modifs.keys()) or ('module_initial' in dico_modifs.keys()):
313 return 0, config.u("""le module ne peut pas être modifié""")
314
315 if dico_modifs == {}:
316 return 1, config.u("""aucune modification demandée""")
317 else:
318
319 if ('module_actuel' in dico_modifs.keys()) and not ('variante' in dico_modifs.keys()):
320 dico_modifs['variante']=0
321 requete=["update serveurs set "]
322 for cle in dico_modifs.keys():
323 requete.append(str(cle))
324 requete.append("='")
325 requete.append(str(dico_modifs[cle]).replace("'","\\\'"))
326 requete.append("', ")
327 query="".join(requete)[:-2]
328 query += """ where id=%s""" % self.id_s
329
330
331 try:
332 cu = cx_pool.create()
333 cu.execute(query)
334 cx_pool.commit(cu)
335 except:
336 return 0, config.u("""Erreur lors de la modification dans la base""")
337
338 serveur_dir_ori = self.confdir
339 if 'variante' in dico_modifs.keys():
340 if int(dico_modifs['variante']) != int(self.id_var):
341
342 try:
343 cu = cx_pool.create()
344 cu.execute("""insert into log_serveur (id_serveur,date,type,message,etat) values (%s,'%s','ZEPHIR','Modification de la variante (%s -> %s)',0)""" % (int(self.id_s),str(time.ctime()),str(self.id_var),str(dico_modifs['variante'])))
345 cx_pool.commit(cu)
346 except:
347
348 pass
349
350
351 var_dir = os.path.abspath(config.PATH_MODULES)+os.sep+str(self.id_mod)+os.sep+'variantes'+os.sep+str(dico_modifs['variante'])
352 try:
353 os.unlink(serveur_dir_ori+os.sep+'dico.eol')
354 os.unlink(serveur_dir_ori+os.sep+'droits_variante')
355 except:
356 pass
357
358 retour = os.system('ln -s %s/dico.eol %s/dico.eol' % (var_dir, serveur_dir_ori))
359 retour = os.system('ln -s %s/droits_zephir %s/droits_variante' % (var_dir, serveur_dir_ori))
360 for rep in ['patchs','dicos','fichiers_perso','fichiers_zephir']:
361 if retour != 0:
362 break
363 if os.path.exists(serveur_dir_ori+'/%s/variante' % rep):
364 os.unlink(serveur_dir_ori+'/%s/variante' % rep)
365 retour = os.system('ln -s %s/%s %s/%s/variante' % (var_dir, rep, serveur_dir_ori, rep))
366
367 if retour != 0:
368
369 return 0, config.u("""erreur de création des liens de variante""")
370
371 self.update_data()
372
373 return 1, config.u('ok')
374
376
377 params = {'agents':1
378 ,'dico_ok':0
379 ,'config_ok':0
380 ,'cle_ok':0
381
382
383 ,'maj_ok':[-2,'']
384 ,'reboot_ok':[-2,'']
385 ,'service_restart_ok':[-2,'']
386 ,'query_maj':[-2,'']
387 ,'reconfigure_ok':[-2,'']
388 ,'configure_ok':[-2,'']
389 ,'sauvegarde_ok':[-2,'']
390 ,'lock_ok':[1,'']
391 ,'timeout':[1,'']
392 ,'md5s':[-1,'']
393 ,'last_log':'journal vide'
394 }
395 try:
396 params['agents'] = params_ori['agents']
397 except:
398
399 pass
400
401 if os.path.isfile(self.confdir+os.sep+'zephir.eol'):
402 params['config_ok']=1
403 if os.path.isfile(self.confdir+os.sep+'cle_publique'):
404 params['cle_ok']=1
405
406 query = """select type,etat,date,message from last_log_serveur where id_serveur = %s order by date desc,id desc limit 1""" % self.id_s
407 cu = cx_pool.create()
408 try:
409 cu.execute(query)
410 data = cu.fetchone()
411
412 if data is not None:
413 params['last_log']=str(data[2])
414 query = """select type,etat,date,message from last_log_serveur where id_serveur = %s and type != 'SURVEILLANCE' order by date desc,id desc""" % self.id_s
415 cu.execute(query)
416 data = cu.fetchall()
417 cx_pool.close(cu)
418
419 not_found = ['maj','reconfigure','configure','lock','sauvegarde','reboot','service_restart','query_maj']
420 for log in data:
421
422
423 if log[0] == 'LOCK':
424 if 'lock' in not_found:
425 not_found.remove('lock')
426 if log[1] == 1:
427 params['lock_ok'] = [2,str(log[2]),log[3]]
428
429 elif log[0] == 'QUERY-MAJ':
430 if 'query_maj' in not_found:
431 not_found.remove('query_maj')
432 if log[1] == 0:
433 params['query_maj'] = [0,str(log[2])]
434 if 'paquets' in log[3]:
435 try:
436 nb_paquets = int(log[3].split()[0])
437 params['query_maj'] = [nb_paquets,str(log[2])]
438 except:
439 params['query_maj'] = [-2,'erreur de lecture du résultat']
440 elif log[1] > 0:
441
442 params['query_maj'] = [-1, log[3]]
443 else:
444 for type_log in ['maj','configure','reconfigure','sauvegarde','reboot','service_restart']:
445
446 if log[0] == type_log.upper() and int(log[1]) != -2:
447
448 if type_log in not_found:
449 not_found.remove(type_log)
450 if log[1] == -1:
451 params['%s_ok' % type_log] = [2,str(log[2]),log[3]]
452 elif log[1] > 0:
453 params['%s_ok' % type_log] = [0,str(log[2]),log[3]]
454 elif log[1] == 0:
455 params['%s_ok' % type_log] = [1,str(log[2]),log[3]]
456 break
457 if not_found == []:
458 break
459 except:
460 traceback.print_exc()
461 cx_pool.close(cu)
462 return params
463
465 """modifie le champ param d'un serveur
466 @param_updates : dictionnaire contenant les modifications
467 """
468 params_ori = self.get_params()
469 params_ori.update(param_updates)
470 self.save_params(params_ori)
471
473 params = str(params).replace("'","''")
474 query = """update serveurs set params='%s' where id=%s""" % (params, self.id_s)
475 cu = cx_pool.create()
476 try:
477 cu.execute(query)
478 cx_pool.commit(cu)
479 except:
480 traceback.print_exc()
481 cx_pool.rollback(cu)
482
484
485 modifs = []
486 fics=[]
487 for src, dst, pattern in md5files:
488 if os.path.isdir(os.path.join(self.confdir,dst)):
489 for fic in os.listdir(os.path.join(self.confdir,dst)):
490 if os.path.isfile(os.path.join(self.confdir,dst,fic)):
491 if pattern == None or fic.endswith(pattern):
492 fics.append(os.path.join(dst,fic))
493 else:
494 fics.append(dst)
495
496 md5s = []
497 md5file = os.path.join(os.path.abspath(config.PATH_ZEPHIR),'data','config%s.md5' % self.id_s)
498 if os.path.isfile(md5file):
499
500 data = file(md5file).read().strip().split('\n')
501
502 for line in data:
503 fic = line.split()[1]
504 if fic not in fics:
505 modifs.append("absent sur zephir : %s" % fic)
506 else:
507 md5s.append(fic)
508
509
510
511
512
513 for fic in fics:
514 if fic not in md5s:
515
516 modifs.append("non envoyé : %s" % fic)
517
518 cmd_md5 = getProcessOutputAndValue("/usr/bin/md5sum",
519 args = ["-c",md5file],
520 path = self.confdir,
521 env = {'LC_ALL': 'C'})
522 cmd_md5.addCallback(self._check_md5_res, md5s, modifs)
523 cmd_md5.addErrback(self._check_md5_res, md5s, modifs)
524 else:
525
526 self.maj_params({'md5s':[-1,""]})
527 self.edit_serveur({'md5s':-1})
528
530
531 out, err, code = result
532 self.edit_serveur({'md5s':1})
533 self.maj_params({'md5s':[1,""]})
534 for fic in md5s:
535 if not "%s: OK" % fic in out.split('\n'):
536 modifs.append("contenu modifié : %s" % fic)
537 md5_ok = False
538 if modifs != []:
539 self.edit_serveur({'md5s':0})
540 self.maj_params({'md5s':[0,";".join(modifs).strip()]})
541
555
557 """fonction de récupération des données d'un serveur migré
558 """
559
560 if check == True:
561 if config.migration_files.has_key(self.module):
562 return 1, True
563 else:
564 return 1, False
565
566 if not config.migration_files.has_key(self.module):
567 return 1, config.u("""pas de fichiers à migrer""")
568 dir_serv = os.path.join(self.confdir,'fichiers_zephir')
569 dir_bak = os.path.join(self.confdir+'-backup','fichiers_zephir')
570 if not os.path.isdir(dir_bak):
571 return 0, config.u("répertoire backup de migration non trouvé")
572 not_found = []
573 errors = []
574
575 for src, dst, convert in config.migration_files[self.module]['files']:
576 fic_src = os.path.join(dir_bak,src)
577 fic_dst = os.path.join(dir_serv,dst)
578 if os.path.isdir(fic_src):
579
580 os.path.walk(fic_src, self.tree_copy, (fic_src, fic_dst, convert, errors))
581 elif os.path.isfile(fic_src):
582 self.copy_fic(fic_src, fic_dst, convert, errors)
583 else:
584 not_found.append(src)
585
586 for dest, options, user, group, mode in config.migration_files[self.module]['rights']:
587 cmd_rights = 'cd %s;chmod %s %s %s;chown %s %s.%s %s' % (dir_serv, options, mode, dest, options, user, group, dest)
588 res = os.system(cmd_rights)
589 if res != 0:
590 errors.append('application des droits impossible : %s' % dest)
591 return 1, config.u((not_found,errors))
592
600
601 - def copy_fic(self, src, dst, convert, errors):
602 """copie du fichier src sur dst
603 convert: si True, convertit le fichier d'ISO-8859-1 vers UTF-8
604 """
605 if convert == True:
606 cmd = '/usr/bin/iconv -f ISO-8859-1 -t UTF-8 -o "%s" "%s"' % (dst, src)
607 else:
608 cmd = '/bin/cp -f "%s" "%s"' % (src, dst)
609 res = os.system(cmd)
610 if res != 0:
611 print "erreur lors de la migration des données, la commande suivante a échoué :"
612 print cmd
613 errors.append(src)
614
615
617 """dictionnaire des serveurs existants gérant les autorisations d'accès
618 """
619
620
622
623 self._groupes_serveurs = {}
624 self._restrictions = {}
625 self.stats = {}
626 self.update_groupes()
627
628 self._mod_var = self.get_mod_var()
629 try:
630 self.update_auths()
631 except:
632
633 pass
634
636 cu = cx_pool.create()
637
638 try:
639 cu.execute("select id, libelle, serveurs from groupes_serveurs")
640 data = cu.fetchall()
641 for groupe in data:
642 id = int(groupe[0])
643 libelle = str(groupe[1])
644 serveurs = eval(groupe[2])
645 timestamp = time.time()
646 date_creat = timestamp
647 if self._groupes_serveurs.has_key(id):
648 date_creat = self._groupes_serveurs[id][2][0]
649 self._groupes_serveurs[id] = [libelle, serveurs, [date_creat, timestamp]]
650 cx_pool.close(cu)
651 except:
652 traceback.print_exc()
653 cx_pool.close(cu)
654
656 """récupére les variantes et leur module"""
657 cu = cx_pool.create()
658 try:
659 cu.execute("select id,module from variantes")
660 data = cu.fetchall()
661 cx_pool.close(cu)
662 except:
663 data = []
664 traceback.print_exc()
665 cx_pool.close(cu)
666 return dict(data)
667
669 if user != None:
670 user_clause = " where login = '%s'" % user
671 else:
672 user_clause = ""
673
674 cu = cx_pool.create()
675 try:
676
677 cu.execute("select login, id_res, type_res from restrictions %s" % user_clause)
678 data = cu.fetchall()
679 for restriction in data:
680 login, id_res, type_res = restriction
681 if not self._restrictions.has_key(login):
682 self._restrictions[login] = {}
683 if self._restrictions[login].has_key(type_res):
684 self._restrictions[login][type_res].append(id_res)
685 else:
686 self._restrictions[login][type_res] = [id_res]
687 cx_pool.close(cu)
688 except:
689 traceback.print_exc()
690 cx_pool.close(cu)
691
693 """ajoute une restriction pour un utilisateur et une ressource donnés
694 type_res : nature des objets à restreindre
695 id_res ; identifiant de l'objet autorisé
696 les différents types reconnus sont : 'rne, group, id_mod, id_var' et les attributs
697 de la classe serveur (id_s, module, version, ...)
698 """
699
700 try:
701 assert str(id_res) in self._restrictions[credential][type_res]
702 except:
703 cu = cx_pool.create()
704
705 libelle, table, field = config.type_res_label[type_res]
706 if field in ('rne','libelle'):
707
708 valid_query = "select * from %s where %s ilike '%s'" % (table, field, str(id_res))
709 else:
710
711 valid_query = "select * from %s where %s = %s" % (table, field, str(id_res))
712 try:
713 cu.execute(valid_query)
714
715 if cu.fetchone() == None:
716 raise ValueError('identifiant de ressource inconnu')
717 except Exception, e:
718 cx_pool.close(cu)
719 return False
720 try:
721 cu.execute("""insert into restrictions (login, type_res, id_res) values ('%s','%s','%s')""" % (credential, type_res, str(id_res)))
722 except:
723
724 cx_pool.rollback(cu)
725 return False
726 cx_pool.commit(cu)
727 if not self._restrictions.has_key(credential):
728 self._restrictions[credential] = {}
729 if not self._restrictions[credential].has_key(type_res):
730 self._restrictions[credential][type_res] = []
731 self._restrictions[credential][type_res].append(str(id_res))
732 else:
733
734 pass
735 return True
736
738 """renvoie la liste des restrictions d'un utilisateur
739 """
740 if not self._restrictions.has_key(credential):
741 return []
742 if type_res == None:
743
744 return self._restrictions[credential]
745 else:
746
747 if self._restrictions[credential].has_key(type_res):
748 return self._restrictions[credential][type_res]
749 else:
750 return []
751
753 """enleve une restriction d'un utilisateur
754 """
755 try:
756 liste_res = self._restrictions[credential][type_res]
757 assert str(id_res) in liste_res
758 except:
759
760 return False
761
762 cu = cx_pool.create()
763 try:
764 cu.execute("""delete from restrictions where login='%s' and type_res='%s' and id_res='%s'""" \
765 % (credential, type_res, str(id_res)))
766 cx_pool.commit(cu)
767 except:
768 traceback.print_exc()
769 cx_pool.rollback(cu)
770 return False
771
772 self._restrictions[credential][type_res].remove(str(id_res))
773 if self._restrictions[credential][type_res] == []:
774 del(self._restrictions[credential][type_res])
775 return True
776
778 """renvoie les informations de permissions associées à un fichier
779 """
780
781 permsfile = data_dir+os.sep+'droits_zephir'
782 if os.path.isfile(permsfile):
783 f_rights = file(permsfile)
784 data = f_rights.read().strip().split('\n')
785 f_rights.close()
786 else:
787 data = []
788 mode = user = group = ""
789 recursive = False
790 if filepath != "":
791 result = {filepath:[mode, user, group, recursive]}
792 else:
793 result = {}
794 for line in data:
795 if line.startswith(filepath+'#') or filepath == "":
796 try:
797 filename, mode, user, group, recursive = line.split('#')
798 if recursive != '':
799 recursive = eval(recursive)
800 result[filename] = [mode, user, group, recursive]
801 if filepath != "":
802 break
803 except:
804
805 pass
806 return result
807
809 """enregistre les informations de permissions associées à un(des) fichier(s)
810 @param data_dir: chemin ou trouver le fichier droits_zephir
811 """
812
813 permsfile = data_dir+os.sep+'droits_zephir'
814 data = self.get_file_perms(data_dir)
815 data.update(rights)
816
817 lines = []
818 for filepath in data.keys():
819
820
821 lines.append("%s#%s#%s#%s#%s" % (filepath, data[filepath][0], data[filepath][1], data[filepath][2],data[filepath][3]))
822
823 f_rights = file(permsfile,'w')
824 f_rights.write('\n'.join(lines))
825 f_rights.close()
826 return True
827
829 """supprime les informations de permissions associées à un fichier (ou tous)
830 """
831
832 permsfile = data_dir+os.sep+'droits_zephir'
833 if not os.path.exists(permsfile):
834
835 return False
836 if filepath != "":
837 f_rights = file(permsfile)
838 data = f_rights.read().strip().split('\n')
839 f_rights.close()
840 if recurse == True:
841 search_pattern = filepath
842 else:
843 search_pattern = filepath + '#'
844 for line in data:
845 if line.startswith(search_pattern):
846 data.remove(line)
847 else:
848 data = []
849
850 try:
851 f_rights = file(permsfile,'w')
852 f_rights.write('\n'.join(data))
853 f_rights.close()
854 except:
855 return False
856 return True
857
859
860
861 serv = dict.get(self,key)
862 if self._restrictions.has_key(credential):
863 for type_res, res in self._restrictions[credential].items():
864 if res == []:
865
866 continue
867 res_ok = True
868
869
870 if type_res == 'rne':
871 rne_ok = False
872 for rne in res:
873
874 if rne.endswith('%'):
875 if serv.rne.startswith(rne.split('%')[0]):
876
877 rne_ok = True
878 break
879 if not rne_ok:
880 if not serv.rne in res:
881 res_ok = False
882 elif type_res == 'groupe':
883
884 serv_in_groupes = False
885 for groupe in res:
886 if serv.id_s in self._groupes_serveurs[int(groupe)][1]:
887 serv_in_groupes = True
888 break
889 if serv_in_groupes == False:
890 res_ok = False
891 else:
892
893 if not str(getattr(serv,type_res)) in [str(i) for i in res]:
894 res_ok = False
895 if not res_ok:
896
897 raise ResourceAuthError("unauthorized resource : %s" % key)
898
900
901 if self._restrictions.has_key(credential):
902 if self._restrictions[credential].has_key('groupe'):
903 if self._restrictions[credential]['groupe'] != []:
904 if str(groupe) not in self._restrictions[credential]['groupe']:
905
906
907 raise ResourceAuthError("unauthorized resource : %s" % groupe)
908
910
911 if self._restrictions.has_key(credential):
912 if self._restrictions[credential].has_key('id_mod'):
913 if self._restrictions[credential]['id_mod'] != []:
914 if str(id_mod) not in self._restrictions[credential]['id_mod']:
915
916 raise ResourceAuthError("unauthorized module : %s" % id_mod)
917
919
920 if self._restrictions.has_key(credential):
921 try:
922 var_mod = str(self._mod_var[int(id_var)])
923 except:
924
925 self._mod_var = self.get_mod_var()
926 var_mod = str(self._mod_var[int(id_var)])
927
928 if self._restrictions[credential].has_key('id_mod'):
929 if self._restrictions[credential]['id_mod'] != []:
930 if var_mod not in self._restrictions[credential]['id_mod']:
931 raise ResourceAuthError("accès au module %s interdit" % var_mod)
932
933 if self._restrictions[credential].has_key('id_var'):
934 if self._restrictions[credential]['id_var'] != []:
935 if str(id_var) not in self._restrictions[credential]['id_var']:
936
937 raise ResourceAuthError("accès à la variante %s interdit" % id_var)
938
940
941 rne_ok = True
942 if self._restrictions.has_key(credential):
943 if self._restrictions[credential].has_key('rne'):
944 if self._restrictions[credential]['rne'] != []:
945 if str(rne) not in self._restrictions[credential]['rne']:
946 rne_ok = False
947 for etab in self._restrictions[credential]['rne']:
948 if etab.endswith('%'):
949 if str(rne).startswith(etab.split('%')[0]):
950 rne_ok = True
951 if not rne_ok:
952
953 raise ResourceAuthError("unauthorized module : %s" % rne)
954
955 - def get(self, credential, key):
956 if key in self.keys():
957 self.check_serv_credential(credential, key)
958 else:
959 raise KeyError, "serveur inexistant"
960 return dict.get(self,key)
961
963 """renvoie la liste des serveurs en alerte
964 """
965 servs=[]
966 for id_serv in self.keys():
967 try:
968 serv = self.get(credential, int(id_serv))
969 except ResourceAuthError:
970
971 continue
972 if serv.get_status() not in [1, -1]:
973 servs.append(serv)
974 return servs
975
976
978 """vérifie si des serveurs ont été modifiés
979 @param serveurs : dictionnaires {idserveur:timestamp}
980 @param last_check : Si != None, on renvoie les serveurs créés après cette date (timestamp)
981 @return : liste d'id de serveurs
982 """
983 modifs = {}
984 serv_pool = []
985 for id_serv in [str(cle) for cle in self.keys()]:
986 try:
987 serv = self.get(credential, int(id_serv))
988 except ResourceAuthError:
989
990 print "server %s not authorized" % id_serv
991 if serveurs.has_key(id_serv):
992 modifs[id_serv] = "deleted"
993 else:
994 serv_pool.append(str(serv.id_s))
995 if serveurs.has_key(id_serv):
996 if serv.modified > serveurs[id_serv]:
997
998 modifs[id_serv] = serv.modified
999 elif last_check != None:
1000 if serv.created > last_check:
1001
1002
1003 modifs[id_serv] = serv.modified
1004
1005 for id_serv in serveurs.keys():
1006 if id_serv not in serv_pool:
1007 modifs[id_serv] = "deleted"
1008
1009 return modifs
1010
1012 """vérifie si des groupes ont été modifiés
1013 @param groupes : dictionnaires {idgroupe:timestamp}
1014 @param last_check : Si != None, on renvoie les serveurs créés après cette date (timestamp)
1015 @return : dictionnaire {id_gr:[libelle, serveurs, [date_creat, date_modif]]}
1016 """
1017 modifs = {}
1018
1019 for id_gr, data in self._groupes_serveurs.items():
1020 try:
1021 group = self.get_groupes(credential,id_gr)
1022 except KeyError, ResourceAuthError:
1023
1024 print "group %s no longer exists or not authorized" % id_gr
1025 modifs[str(id_gr)] = "deleted"
1026 else:
1027
1028 id_gr = str(id_gr)
1029 if groupes.has_key(id_gr):
1030 if data[2][1] > groupes[id_gr]:
1031
1032 modifs[id_gr] = data
1033 elif last_check != None:
1034 if data[2][0] > last_check:
1035
1036 modifs[id_gr] = data
1037
1038 return modifs
1039
1040 - def add_groupe(self, credential, libelle, serveurs):
1041 query = """insert into groupes_serveurs (libelle,serveurs) values ('%s', '%s')""" % (libelle,str(serveurs))
1042 cu = cx_pool.create()
1043 try:
1044 cu.execute(query)
1045 except:
1046 traceback.print_exc()
1047 cx_pool.roolback(cu)
1048 return False
1049 cx_pool.commit(cu)
1050 self.update_groupes()
1051
1052 if self._restrictions.has_key(credential):
1053 if self._restrictions[credential].has_key('groupe'):
1054
1055 for id_gr in self._groupes_serveurs.keys():
1056 if self._groupes_serveurs[id_gr][0] == libelle:
1057 self.add_restriction(credential,'groupe',str(id_gr))
1058 return True
1059
1060 - def get_groupes(self, credential, id_groupe=None, alertes=False):
1061 if id_groupe != None:
1062 groupes = [int(id_groupe)]
1063 else:
1064 groupes = self._groupes_serveurs.keys()
1065
1066 res = []
1067 for groupe in groupes:
1068 try:
1069 self.check_gr_credential(credential, groupe)
1070 except:
1071
1072 continue
1073 libelle, serveurs, timestamps = self._groupes_serveurs[groupe]
1074
1075 res.append([int(groupe), libelle, serveurs])
1076 return res
1077
1078 - def edit_groupe(self, credential, id_groupe, libelle, serveurs):
1079
1080 id_groupe = int(id_groupe)
1081 self.check_gr_credential(credential, id_groupe)
1082
1083 cu = cx_pool.create()
1084 query = """update groupes_serveurs set libelle='%s', serveurs='%s' where id=%s""" % (libelle,str(serveurs),id_groupe)
1085 try:
1086 cu.execute(query)
1087 except:
1088 traceback.print_exc()
1089 cx_pool.rollback(cu)
1090 return False
1091 cx_pool.commit(cu)
1092
1093 date_creat = self._groupes_serveurs[id_groupe][2][0]
1094 self._groupes_serveurs[id_groupe] = [libelle, serveurs, [date_creat,time.time()]]
1095 return True
1096
1098
1099 id_groupe = int(id_groupe)
1100 self.check_gr_credential(credential, id_groupe)
1101
1102 d = {'id':id_groupe}
1103
1104 rech_groupe = """groupes like '[%(id)s]' or groupes like '[%%%(id)s,%%]' or groupes like '%%, %(id)s]'""" % d
1105 cursor = cx_pool.create()
1106 try:
1107 cursor.execute("""select login,groupes from users where %s""" % rech_groupe)
1108 data=cursor.fetchall()
1109
1110 for user in data:
1111
1112 groupes = eval(user[1])
1113 if id_groupe in groupes:
1114 groupes.remove(id_groupe)
1115 sql_update = """update users set groupes='%s' where login='%s'""" % (str(groupes),user[0])
1116 cursor.execute(sql_update)
1117
1118 cursor.execute("""delete from groupes_serveurs where id = %s""" % str(id_groupe))
1119 cx_pool.commit(cursor)
1120 except:
1121 traceback.print_exc()
1122 cx_pool.rollback(cursor)
1123 return False
1124
1125 del(self._groupes_serveurs[id_groupe])
1126 return True
1127
1128
1130
1131 id_groupe = int(id_groupe)
1132 self.check_gr_credential(credential, id_groupe)
1133
1134
1135 for serv in serveurs:
1136 if serv in self._groupes_serveurs[id_groupe][1]:
1137 serveurs.remove(serv)
1138 self._groupes_serveurs[id_groupe][1].extend(serveurs)
1139 self._groupes_serveurs[id_groupe][2] = [time.time(),time.time()]
1140 cu = cx_pool.create()
1141
1142 try:
1143 query="""update groupes_serveurs set serveurs='%s' where id=%s""" % (str(self._groupes_serveurs[id_groupe][1]),id_groupe)
1144 cu.execute(query)
1145 cx_pool.commit(cu)
1146 except:
1147 traceback.print_exc()
1148 cx_pool.rollback(cu)
1149
1150 - def add_serveur(self, credential, rne, libelle, materiel, processeur, disque_dur, date_install, installateur, tel, remarques, module_initial, module_actuel, variante, timestamp_serveur, timeout):
1151
1152 if self._restrictions.has_key(credential):
1153 if self._restrictions[credential].has_key('rne'):
1154 self.check_etab_credential(credential, rne)
1155 if self._restrictions[credential].has_key('id_mod'):
1156 if module_actuel not in self._restrictions[credential]['id_mod']:
1157 raise ResourceAuthError("unauthorized resource %s" % module_actuel)
1158 if self._restrictions[credential].has_key('variante'):
1159 if variante not in self._restrictions[credential]['variante']:
1160 raise ResourceAuthError("unauthorized resource %s" % variante)
1161
1162 cu = cx_pool.create()
1163 query = """insert into serveurs (rne,libelle,materiel,processeur,disque_dur,date_install,installateur,tel,remarques,module_initial,module_actuel,variante,timestamp,timeout) values ('%s','%s','%s','%s','%s','%s','%s','%s','%s',%s,%s,%s,'%s',%s)""" \
1164 % (rne,libelle.replace("'","\\\'"),materiel.replace("'","\\\'"),processeur.replace("'","\\\'"),disque_dur.replace("'","\\\'"),date_install.replace("'","\\\'"),installateur.replace("'","\\\'"),tel,remarques.replace("'","\\\'"),module_initial,module_actuel,variante,timestamp_serveur,timeout)
1165 cu.execute(query)
1166
1167 query = """select id from serveurs where rne='%s' and libelle ='%s' and date_install='%s' and installateur='%s' and remarques='%s' and module_actuel=%s and variante=%s and timestamp='%s'""" % (rne, libelle.replace("'","\\\'"), date_install.replace("'","\\\'"), installateur.replace("'","\\\'"), remarques.replace("'","\\\'"), module_actuel, variante, timestamp_serveur)
1168 cu.execute(query)
1169 id_serveur = int(cu.fetchone()[0])
1170 self[id_serveur] = Serveur(id_serveur,cu)
1171 cx_pool.commit(cu)
1172 return id_serveur
1173
1189
1194
1210
1211
1213 """crée un pool de tous les serveurs existants
1214 """
1215
1216 pool=ServeurPool()
1217 cu = cx_pool.create()
1218 try:
1219 cu.execute("select id, rne, libelle, module_actuel, variante, timeout, etat, md5s, maj, last_contact from serveurs")
1220 data = cu.fetchall()
1221 nbserv = len(data)
1222 no_contact = []
1223
1224 for serv in data:
1225
1226 if serv[9] == None:
1227 no_contact.append(int(serv[0]))
1228
1229 pool[serv[0]] = Serveur(serv[0], cu, serv[1:2])
1230 pool[serv[0]].update_data(cu, serv[2:9])
1231 pool.stats['no_contact'] = no_contact
1232 pool.stats['nb_serv'] = len(data)
1233 cx_pool.close(cu)
1234 except:
1235 traceback.print_exc()
1236 cx_pool.close(cu)
1237 return pool
1238
1239
1240
1241 text_characters = "".join(map(chr, range(32, 255)) + list("\n\r\t\b"))
1242 _null_trans = string.maketrans("", "")
1243
1244 -def istextfile(filename, blocksize = 1024):
1245 return istext(open(filename).read(blocksize))
1246
1248 if "\0" in s:
1249 return 0
1250
1251 if not s:
1252 return 1
1253
1254
1255
1256 t = s.translate(_null_trans, text_characters)
1257
1258
1259
1260 if len(t)/len(s) > 0.10:
1261 return 0
1262 return 1
1263