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.backend.config import log
17 try:
18 from migration_perso import migration_perso, destinations_perso
19 except:
20 migration_perso = {}
21 destinations_perso = []
22 from zephir.utils.creolewrap import ZephirDict
23 from zephir.monitor.agentmanager.util import md5files
24 from twisted.internet.utils import getProcessOutputAndValue
25 import psycopg2 as PgSQL
26 import os, sys, time, string, traceback, apt_pkg, re, shutil
27 import base64, md5
28 from ConfigParser import ConfigParser
29 from glob import glob
30 from cStringIO import StringIO
31 import xmlrpclib
32
35
37 """dictionnaire des connexions postgresql en cours"""
38
44
50
56
58 cu.close()
59 self[cu].close()
60 del(self[cu])
61
63 """gestionnaire de vérification d'état des paquets d'un serveur
64 """
66 self.pkg_file = {}
67 self.packages = {}
68 self.timestamp = {}
69 for zephir_version, data in config.DISTRIBS.items():
70 if zephir_version != 1:
71 codename, version, maintained = data
72
73 for serv_maj in config.SERVEURS_MAJ_CLIENTS:
74 if zephir_version not in self.pkg_file:
75 self.pkg_file[zephir_version] = {}
76 self.packages[zephir_version] = {}
77 self.timestamp[zephir_version] = {}
78 self.pkg_file[zephir_version][serv_maj] = os.path.join(os.path.abspath(config.PATH_ZEPHIR),'packages_%s_%s.ini' % (codename, serv_maj))
79 self.packages[zephir_version][serv_maj] = ConfigParser()
80 if not os.path.isfile(self.pkg_file[zephir_version][serv_maj]):
81 f = file(self.pkg_file[zephir_version][serv_maj],'w')
82 f.close()
83
84 log.msg("** récupération de la liste des paquets disponibles en mise à jour", serv_maj)
85 os.system('/usr/share/eole/check_maj_eole.py')
86 self.timestamp[zephir_version][serv_maj] = os.path.getmtime(self.pkg_file[zephir_version][serv_maj])
87 self.packages[zephir_version][serv_maj].read(self.pkg_file[zephir_version][serv_maj])
88
89 if len(config.held_packages) > 0:
90 self.held_pattern = re.compile("|".join(config.held_packages))
91 else:
92 self.held_pattern = None
93
95 apt_pkg.InitSystem()
96 if apt_pkg.VersionCompare(current_version, min_version) >= 0:
97 return True
98 return False
99
100 - def check_packages(self, maj_infos, pkg_file, debnames, version, serv_maj, type_maj = 'complete', show_installed = False):
101 """vérifie l'état de mise à jour des paquets
102 type_maj : type de mise à jour (minimale/complete)
103 show_installed : si True, renvoie la liste de tous les paquets installés
104 par défaut, seulement les paquets non à jour
105 """
106
107 if serv_maj not in self.packages[version]:
108 config.log.msg("Serveur de mise à jour", serv_maj, "inconnu : utilisation de", config.SERVEURS_MAJ_CLIENTS[0])
109 serv_maj = config.SERVEURS_MAJ_CLIENTS[0]
110 depot_changed = True
111 client_changed = True
112 if os.path.isfile(pkg_file):
113 md5_packs = md5.md5(file(pkg_file).read()).hexdigest()
114 else:
115
116 if maj_infos is not None:
117 return maj_infos[0], maj_infos
118 else:
119 return [], None
120
121 depot_timestamp = os.path.getmtime(self.pkg_file[version][serv_maj])
122 if maj_infos:
123
124 if maj_infos[1] == type_maj and maj_infos[2] == md5_packs and maj_infos[3] == serv_maj:
125 client_changed = False
126 if maj_infos[4] == depot_timestamp:
127 depot_changed = False
128
129 if debnames == [] and not show_installed:
130
131
132 if not depot_changed and not client_changed:
133 return maj_infos[0], maj_infos
134
135
136 pkg_liste = []
137 if os.path.isfile(pkg_file):
138 for line in file(pkg_file):
139 pak_info = line.split()
140 if debnames != []:
141
142 if pak_info[0] in debnames:
143 pkg_liste.append(pak_info)
144 if len(pkg_liste) == len(debnames):
145
146 break
147 else:
148 pkg_liste.append(line.split())
149
150 check_needed = False
151 if maj_infos is None or client_changed == True or debnames != [] or show_installed == True:
152
153 check_needed = True
154 if depot_changed:
155
156 self.packages[version][serv_maj].read(self.pkg_file[version][serv_maj])
157 self.timestamp[version][serv_maj] = depot_timestamp
158 check_needed = True
159 liste_pack = []
160 if check_needed:
161 outdated = []
162 apt_pkg.InitSystem()
163 for pkg_name, pkg_version in pkg_liste:
164 if (self.held_pattern is None) or (not self.held_pattern.match(pkg_name)):
165 try:
166
167 if self.packages[version][serv_maj].has_section(pkg_name):
168 try:
169 maj_version = self.packages[version][serv_maj].get(pkg_name, type_maj)
170 except:
171 if type_maj != 'minimum':
172 log.msg('Informations de version du paquet %s non trouvées pour %s' % (pkg_name, serv_maj))
173 traceback.print_exc()
174 if apt_pkg.VersionCompare(maj_version, pkg_version) > 0:
175
176 liste_pack.append((pkg_name, pkg_version, maj_version))
177 outdated.append((pkg_name, pkg_version, maj_version))
178 continue
179 elif show_installed == True:
180 liste_pack.append((pkg_name, pkg_version, maj_version))
181 continue
182 except:
183 traceback.print_exc()
184
185
186 if show_installed == True:
187 liste_pack.append((pkg_name, pkg_version, pkg_version))
188 maj_infos = (outdated, type_maj, md5_packs, serv_maj, depot_timestamp)
189 else:
190
191 liste_pack = maj_infos[0]
192 return liste_pack, maj_infos
193
194 cx_pool = CxPool()
195 maj_checker = AptChecker()
196
198 """classe utilitaire pour récupérer diverses données sur un serveur"""
199
200 - def __init__(self, pool, id_s, cu=None, data=None):
201 """initialise l'objet serveur et récupère les infos
202 """
203 self.version = 'creole2'
204
205 self.id_s = int(id_s)
206
207 self.modified = time.time()
208
209 self.created = time.time()
210
211 self.no_alert = False
212
213 self.pool = pool
214
215 self.maj_infos = None
216 cursor = cu
217 if cu == None:
218 cursor = cx_pool.create()
219 try:
220 if data == None:
221
222 cursor.execute("select rne from serveurs where id=%s", (int(self.id_s),))
223 data = cursor.fetchone()
224 self.rne = data[0]
225
226 self.update_data(cursor)
227 else:
228 self.rne = data[0]
229 self.confdir = os.path.join(config.PATH_ZEPHIR,'conf',self.rne, str(self.id_s))
230 if cu == None:
231 cx_pool.close(cursor)
232 except:
233 traceback.print_exc()
234 if cu == None:
235 cx_pool.close(cursor)
236
238 """recharge les données des serveurs
239 """
240
241 cursor = cu
242 if cu == None:
243 cursor = cx_pool.create()
244 try:
245 if data == None:
246 cursor.execute("select libelle, module_actuel, variante, timeout, etat, md5s, maj, no_alert from serveurs where id=%s", (int(self.id_s),))
247 data = cursor.fetchone()
248
249 self.libelle = data[0]
250 self.id_mod = int(data[1])
251 self.id_var = int(data[2])
252 try:
253 self.md5s = int(data[5])
254 except:
255 self.md5s = -1
256 try:
257 self.maj = int(data[6])
258 except:
259 self.maj = -1
260 try:
261 self.timeout = int(data[3])
262 except:
263 self.timeout = 0
264 if data[4] == None:
265 self.status = -1
266 else:
267 self.status = int(data[4])
268 try:
269 if str(data[7]) == '1':
270 self.no_alert = True
271 else:
272 self.no_alert = False
273 except:
274 pass
275
276 cursor.execute("select libelle from etablissements where rne=%s", (self.rne,))
277 data = cursor.fetchone()
278 self.etab = data[0]
279
280 cursor.execute("select libelle,version from modules where id=%s", (int(self.id_mod),))
281 data = cursor.fetchone()
282 self.module = data[0]
283 try:
284 self.module_version = int(data[1])
285 except:
286 self.module_version = 4
287
288 OLD_MODULES = config.liste_modules[1]
289 if self.module in OLD_MODULES:
290 self.version = 'creole1'
291 else:
292 self.version = 'creole2'
293
294 cursor.execute("select libelle from variantes where id=%s", (int(self.id_var),))
295 data = cursor.fetchone()
296 self.variante = data[0]
297 self.modified = time.time()
298 if cu == None:
299 cx_pool.close(cursor)
300 except:
301 traceback.print_exc()
302 if cu == None:
303 cx_pool.close(cursor)
304
306 """affichage du serveur
307 """
308 return """%s => %s (%s)""" % (self.id_s, self.module, self.rne)
309
311 """affichage du serveur
312 """
313 return """%s => %s (%s) - %s (%s)""" % (self.id_s, self.libelle, self.module, self.etab, self.rne)
314
315
316
317
320
323
326
329
332
335
338
339 - def get_config(self, mode="modif_config", encode=False):
340 """retourne la configuration eole du serveur (zephir.eol)
341 """
342
343 if self.version == 'creole1':
344
345 creole_files = [self.confdir+os.sep+'dictionnaire']
346
347 creole_files.extend(glob(self.confdir+os.sep+'dicos/variante/*.eol'))
348
349 creole_files.extend(glob(self.confdir+os.sep+'dicos/*.eol'))
350 dicos = []
351 for dic in creole_files:
352 try:
353
354 fic = open(dic,'r')
355 lines = fic.readlines()
356 fic.close()
357 if encode == True:
358 data = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ]
359 else:
360 data = lines
361
362 dicos.append(data)
363 except OSError:
364 pass
365
366 if self.version == 'creole2':
367
368 dicos = []
369 for rep in ['module','variante', 'local']:
370 dicos.append(os.path.join(self.confdir,'dicos',rep))
371
372 dico = ZephirDict(dicos, self.confdir, mode, self.version)
373 return dico
374
375 - def save_config(self, dico_zeph, mode='config', encode=False, force=False):
376 """sauvegarde la configuration eole du serveur (zephir.eol)
377 """
378 try:
379 if mode in ['config','modif_config']:
380 fic_zephir = os.path.join(self.confdir,'zephir.eol')
381 key = 'config_ok'
382 elif mode in ['dico','modif_dico']:
383
384 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'
385 key = 'dico_ok'
386 elif mode in ['migration','modif_migration']:
387 fic_zephir = os.path.join(self.confdir,'migration.eol')
388 key = 'migration_ok'
389 dico_zeph.save(fic_zephir,encode=encode,force=force)
390 if key != '':
391 self.maj_params({key:1})
392 self.check_md5conf()
393 except:
394 traceback.print_exc()
395 raise IOError("serveur %s : erreur de sauvegarde de %s" % (self.id_s, os.path.basename(fic_zephir)))
396 return ""
397
399 """renvoie le dernier état enregistré du serveur
400 """
401 try:
402 assert self.status in range (5)
403 except:
404 return -1
405 else:
406 return self.status
407
420
422 """Conserve la dernière adresse de connexion du serveur
423 """
424 cu = cx_pool.create()
425 try:
426 cu.execute("update serveurs set ip_publique=%s where id=%s", (ip_publique, int(self.id_s)))
427 cx_pool.commit(cu)
428 except:
429 traceback.print_exc()
430 cx_pool.rollback(cu)
431 return False
432 return True
433
435 """renvoie le champ paramètres du serveur
436 """
437 try:
438 if params is None:
439 cu = cx_pool.create()
440 try:
441 cu.execute("select params from serveurs where id=%s", (int(self.id_s),))
442 data = cu.fetchone()
443 cx_pool.close(cu)
444 except:
445 traceback.print_exc()
446 cx_pool.close(cu)
447 params = {}
448 try:
449 params = eval(data[0])
450
451
452 assert type(params) == dict and params.has_key('perso_ok')
453 except:
454
455 params = self.update_params(params)
456
457 self.save_params(params)
458 else:
459 if type(params) == str:
460 params = eval(params)
461
462
463 id_uucp = self.rne+'-'+str(self.id_s)
464 params['uucp_transfert']=0
465 params['uucp_cmd']=0
466 if os.path.isdir('/var/spool/uucp/%s/D.' % id_uucp):
467 params['uucp_transfert']=len(os.listdir('/var/spool/uucp/%s/D.' % id_uucp))
468 if os.path.isdir('/var/spool/uucp/%s/D.X' % id_uucp):
469 params['uucp_cmd']=len(os.listdir('/var/spool/uucp/%s/D.X' % id_uucp))
470
471 if params['config_ok'] == 0:
472 if os.path.isfile(self.confdir+os.sep+'zephir.eol'):
473 params['config_ok'] = 1
474 if params['dico_ok'] == 0:
475 if os.path.isfile(self.confdir+os.sep+'dico.eol'):
476 params['dico_ok'] = 1
477 if os.path.isfile(self.confdir+os.sep+'new_key.pub'):
478 if os.path.isfile(os.path.join(self.confdir,'new_addr')):
479 params['new_key'] = (2,file(os.path.join(self.confdir,'new_addr')).read().strip())
480 elif os.path.isfile(os.path.join(self.confdir,'new_addr_ok')):
481 params['new_key'] = (3,file(os.path.join(self.confdir,'new_addr_ok')).read().strip())
482 else:
483 params['new_key'] = (1, '')
484 else:
485 params['new_key'] = (0, '')
486 if self.version != 'creole1':
487 params['migration_ok'] = 1
488 elif os.path.isfile(self.confdir+os.sep+'migration.eol'):
489 params['migration_ok'] = 0
490 else:
491 params['migration_ok'] = -1
492 return params
493 except:
494 traceback.print_exc()
495 return {}
496
498
499 if 'id' in dico_modifs.keys():
500 return 0, config.u("""L'identifiant ne peut pas être modifié""")
501
502 if 'rne' in dico_modifs.keys():
503 return 0, config.u("""Le rne ne peut pas être modifié""")
504 if 'module_initial' in dico_modifs.keys():
505 return 0, config.u("""Le module initial ne peut pas être modifié""")
506 if 'module_actuel' in dico_modifs.keys() and int(dico_modifs['module_actuel']) != self.id_mod:
507
508 mod_name = self.module[:self.module.rindex('-')]
509 allowed_edits = config.allowed_mod_edits.get(self.module_version, {})
510 if mod_name in allowed_edits:
511
512 query = """select modules.libelle, variantes.id, modules.version from modules, variantes where modules.id=%s and modules.id=variantes.module and variantes.libelle='standard'"""
513 cu = cx_pool.create()
514 try:
515 cu.execute(query, (int(dico_modifs['module_actuel']),))
516 data = cu.fetchone()
517 cx_pool.close(cu)
518 except:
519 traceback.print_exc()
520 cx_pool.close(cu)
521 return 0, config.u("""Le module n'a pas été retrouvé""")
522 if (not data[0][:data[0].rindex('-')] in allowed_edits[mod_name]) or (int(data[2]) != int(self.module_version)):
523 return 0, config.u("""Le module demandé n'est pas compatible avec ce serveur""")
524
525 if not 'variante' in dico_modifs.keys():
526 dico_modifs['variante'] = data[1]
527 else:
528 return 0, config.u("""Le module ne peut pas être modifié""")
529
530 if dico_modifs == {}:
531 return 1, config.u("""Aucune modification demandée""")
532 else:
533 params = []
534 requete=["update serveurs set "]
535 for cle in dico_modifs.keys():
536 requete.append(str(cle))
537 if cle in ('module_initial', 'module_actuel', 'variante', 'timeout', 'etat', 'maj', 'md5s', 'no_alert'):
538 requete.append("=%s, ")
539 params.append(int(dico_modifs[cle]))
540 else:
541 requete.append("=E%s, ")
542 params.append(str(dico_modifs[cle]))
543 query = "".join(requete)[:-2]
544 query += """ where id=%s"""
545 params.append(int(self.id_s))
546
547 try:
548 cu = cx_pool.create()
549 cu.execute(query, params)
550 cx_pool.commit(cu)
551 except:
552 return 0, config.u("""Erreur lors de la modification dans la base""")
553
554 serveur_dir_ori = self.confdir
555 if 'variante' in dico_modifs.keys():
556 if int(dico_modifs['variante']) != int(self.id_var):
557
558 try:
559 params = (int(self.id_s), str(time.ctime()), int(self.id_var), int(dico_modifs['variante']))
560 cu = cx_pool.create()
561 cu.execute("""insert into log_serveur (id_serveur,date,type,message,etat) values (%s,%s,'ZEPHIR','Modification de la variante (%s -> %s)',0)""", params)
562 cx_pool.commit(cu)
563 except:
564
565 pass
566
567 if 'module_actuel' in dico_modifs.keys() and int(dico_modifs['module_actuel']) != self.id_mod:
568 code, msg = self._cree_arbo_serveur(new_module=int(dico_modifs['module_actuel']),new_variante=int(dico_modifs['variante']))
569 else:
570 code, msg = self._cree_arbo_serveur(new_variante=int(dico_modifs['variante']))
571 if code == 0:
572 return 0, config.u(msg)
573
574
575 self.pool.stats['serv_variantes'][str(self.id_var)] = self.pool.stats['serv_variantes'][str(self.id_var)] - 1
576 self.pool.stats['serv_variantes'][str(dico_modifs['variante'])] = self.pool.stats['serv_variantes'].get(str(dico_modifs['variante']), 0) + 1
577 if 'module_actuel' in dico_modifs.keys() and int(dico_modifs['module_actuel']) != self.id_mod:
578
579 self.pool.stats['serv_modules'][str(self.id_mod)] = self.pool.stats['serv_modules'][str(self.id_mod)] - 1
580 self.pool.stats['serv_modules'][str(dico_modifs['module_actuel'])] = self.pool.stats['serv_modules'].get(str(dico_modifs['module_actuel']), 0) + 1
581 self.update_data()
582
583 return 1, config.u('ok')
584
586 """crée l'arborescence zephir d'un nouveau serveur"""
587
588 edit_mode = False
589 if new_module is not None:
590 edit_mode = True
591 module = new_module
592 else:
593 module = self.id_mod
594 if new_variante is not None:
595 edit_mode = True
596 variante = new_variante
597 else:
598 variante = self.id_var
599 serveur_dir = self.confdir
600
601 if not edit_mode:
602 try:
603 os.makedirs(serveur_dir)
604 except:
605 return 0, """erreur de création du répertoire du serveur"""
606
607 try:
608 os.makedirs(serveur_dir+os.sep+'fichiers_zephir')
609 os.makedirs(serveur_dir+os.sep+'fichiers_perso')
610 os.makedirs(serveur_dir+os.sep+'dicos')
611 os.makedirs(serveur_dir+os.sep+'patchs')
612 os.makedirs(serveur_dir+os.sep+'uucp')
613 except:
614 shutil.rmtree(serveur_dir)
615 return 0, """erreur de création du répertoire des fichiers spécifiques au module"""
616
617 if (not edit_mode) or new_module:
618
619 if os.path.isdir(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/dicos'):
620
621 if not edit_mode:
622 os.makedirs(serveur_dir+os.sep+'dicos/local')
623 retour = os.system('ln -nsf '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/dicos '+serveur_dir+'/dicos/module')
624 retour = os.system('ln -nsf '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/module.eol '+serveur_dir+'/module.eol')
625 else:
626
627 retour = os.system('ln -nsf '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/dictionnaire'+' '+serveur_dir+'/dictionnaire')
628 if retour != 0:
629 shutil.rmtree(serveur_dir)
630 return 0, """erreur de lien sur le dictionnaire"""
631
632 if (not edit_mode) or new_variante:
633
634
635 retour = os.system('ln -nsf '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+os.sep+'dico.eol'+' '+serveur_dir+os.sep+'dico.eol')
636 if retour == 0:
637 retour = os.system('ln -nsf '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+os.sep+'droits_zephir'+' '+serveur_dir+os.sep+'droits_variante')
638
639 if retour == 0:
640 retour = os.system('ln -nsf '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+'/patchs'+' '+serveur_dir+'/patchs/variante')
641
642 if retour == 0:
643 retour = os.system('ln -nsf '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+'/dicos'+' '+serveur_dir+'/dicos/variante')
644
645 if retour == 0:
646 retour = os.system('ln -nsf '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+'/fichiers_perso'+' '+serveur_dir+'/fichiers_perso/variante')
647
648 if retour == 0:
649 retour = os.system('ln -nsf '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+'/fichiers_zephir'+' '+serveur_dir+'/fichiers_zephir/variante')
650
651 if retour != 0:
652 shutil.rmtree(serveur_dir)
653 return 0, """erreur de création des liens vers la variante"""
654 else:
655 return 1, 'ok'
656
657
659
660 if self.version == 'creole1':
661 migration_ok = -1
662 else:
663
664 migration_ok = 1
665 params = {'agents':1
666 ,'dico_ok':0
667 ,'config_ok':0
668 ,'migration_ok':migration_ok
669 ,'cle_ok':0
670 ,'new_key':(0,'')
671
672
673 ,'maj_ok':[-2,'']
674 ,'reboot_ok':[-2,'']
675 ,'service_restart_ok':[-2,'']
676 ,'query_maj':[-2,'']
677 ,'reconfigure_ok':[-2,'']
678 ,'configure_ok':[-2,'']
679 ,'sauvegarde_ok':[-2,'']
680 ,'upgrade_ok':[-2,'']
681 ,'perso_ok':[-2,'']
682 ,'lock_ok':[1,'']
683 ,'timeout':[1,'']
684 ,'md5s':[-1,'']
685 ,'last_log':'journal vide'
686 }
687 try:
688 params['agents'] = params_ori['agents']
689 except:
690
691 pass
692
693 if os.path.isfile(os.path.join(self.confdir,'zephir.eol')):
694 params['config_ok']=1
695 if os.path.isfile(os.path.join(self.confdir,'cle_publique')):
696 params['cle_ok']=1
697 if os.path.isfile(os.path.join(self.confdir,'new_key.pub')):
698 if os.path.isfile(os.path.join(self.confdir,'new_addr')):
699 params['new_key'] = (2,file(os.path.join(self.confdir,'new_addr')).read().strip())
700 elif os.path.isfile(os.path.join(self.confdir,'new_addr_ok')):
701 params['new_key'] = (3,file(os.path.join(self.confdir,'new_addr_ok')).read().strip())
702 else:
703 params['new_key'] = (1,'')
704
705 query = """select type,etat,date,message from last_log_serveur where id_serveur = %s order by date desc,id desc limit 1"""
706 cu = cx_pool.create()
707 try:
708 cu.execute(query, (int(self.id_s),))
709 data = cu.fetchone()
710
711 if data is not None:
712 params['last_log']=str(data[2])
713 query = """select type,etat,date,message from last_log_serveur where id_serveur = %s and type != 'SURVEILLANCE' order by date desc,id desc"""
714 cu.execute(query, (int(self.id_s),))
715 data = cu.fetchall()
716 cx_pool.close(cu)
717
718 not_found = ['maj','reconfigure','configure','lock','sauvegarde','reboot','service_restart','upgrade','perso']
719 for log in data:
720
721
722 if log[0] == 'LOCK':
723 if 'lock' in not_found:
724 not_found.remove('lock')
725 if log[1] == 1:
726 params['lock_ok'] = [2,str(log[2]),log[3]]
727 else:
728 for type_log in ['maj','configure','reconfigure','sauvegarde','reboot','service_restart','upgrade','perso']:
729
730 if log[0] == type_log.upper() and int(log[1]) != -2:
731
732 if type_log in not_found:
733 not_found.remove(type_log)
734 if log[1] == -1:
735 params['%s_ok' % type_log] = [2,str(log[2]),log[3]]
736 elif log[1] > 0:
737 params['%s_ok' % type_log] = [0,str(log[2]),log[3]]
738 elif log[1] == 0:
739 params['%s_ok' % type_log] = [1,str(log[2]),log[3]]
740 break
741 if not_found == []:
742 break
743 except:
744 traceback.print_exc()
745 cx_pool.close(cu)
746 return params
747
749 """modifie le champ param d'un serveur
750 @param_updates : dictionnaire contenant les modifications
751 """
752 params_ori = self.get_params()
753 params_ori.update(param_updates)
754 self.save_params(params_ori)
755
757 query = """update serveurs set params=E%s where id=%s"""
758 sql_params = (str(params), int(self.id_s))
759 cu = cx_pool.create()
760 try:
761 cu.execute(query, sql_params)
762 cx_pool.commit(cu)
763 except:
764 traceback.print_exc()
765 cx_pool.rollback(cu)
766
768
769 modifs = []
770 fics=[]
771 files=md5files[self.module_version]
772
773
774
775 fic_ori = os.path.join(self.confdir,'zephir.eol')
776 fic_var = os.path.join(self.confdir,'variables.eol')
777 if os.path.isfile(fic_ori):
778 f_var = file(fic_var,'w')
779 for line in file(fic_ori).readlines():
780 if self.module_version == 1:
781 if "@@" in line:
782 f_var.write(line)
783 else:
784 if not "valprec =" in line:
785 f_var.write(line)
786 f_var.close()
787 for src, dst, pattern in files:
788 if os.path.isdir(os.path.join(self.confdir,dst)):
789 for fic in os.listdir(os.path.join(self.confdir,dst)):
790 if os.path.isfile(os.path.join(self.confdir,dst,fic)):
791 if pattern == None or fic.endswith(pattern):
792 fics.append(os.path.join(dst,fic))
793 else:
794 fics.append(dst)
795 md5s = []
796 md5file = os.path.join(os.path.abspath(config.PATH_ZEPHIR),'data','config%s.md5' % self.id_s)
797 if os.path.isfile(md5file):
798
799 data = file(md5file).read().strip().split('\n')
800
801 for line in data:
802 fic = line.split()[1]
803 if fic not in fics:
804 modifs.append("absent sur zephir : %s" % fic)
805 else:
806 md5s.append(fic)
807 for fic in fics:
808 if fic not in md5s:
809
810 modifs.append("non envoyé : %s" % fic)
811
812 cmd_md5 = getProcessOutputAndValue("/usr/bin/md5sum",
813 args = ["-c",md5file],
814 path = self.confdir,
815 env = {'LC_ALL': 'C'})
816 cmd_md5.addCallback(self._check_md5_res, md5s, modifs)
817 cmd_md5.addErrback(self._check_md5_res, md5s, modifs)
818 else:
819
820 self.maj_params({'md5s':[-1,""]})
821 self.edit_serveur({'md5s':-1})
822
824
825 out, err, code = result
826 self.edit_serveur({'md5s':1})
827 self.maj_params({'md5s':[1,""]})
828 for fic in md5s:
829 if not "%s: OK" % fic in out.split('\n'):
830 if fic == 'variables.eol':
831
832 modifs.append("contenu modifié : zephir.eol")
833 else:
834 modifs.append("contenu modifié : %s" % fic)
835 md5_ok = False
836 if modifs != []:
837 self.edit_serveur({'md5s':0})
838 self.maj_params({'md5s':[0,";".join(modifs).strip()]})
839
841 """vérifie l'état de mise à jour d'un serveur
842 """
843 if self.version == 'creole1':
844 return []
845
846 if type(debnames) != list:
847 debnames = [debnames]
848 liste_pkgs = []
849
850 dico = self.get_config()
851 type_maj = dico.get_value('type_maj')[0]
852 serv_maj = dico.get_value('serveur_maj')[0]
853 version = self.module_version
854 pkg_file = os.path.join(os.path.abspath(config.PATH_ZEPHIR),'data','packages%s.list' % self.id_s)
855
856 liste_pkgs, maj_infos = maj_checker.check_packages(self.maj_infos, pkg_file, debnames, version, serv_maj, type_maj, show_installed)
857 if maj_infos is not None and not debnames and not show_installed and maj_infos != self.maj_infos:
858
859 try:
860 nb_pack = len(maj_infos[0])
861 if len(maj_infos[0]) > 0:
862 self.edit_serveur({'maj':len(maj_infos[0])})
863 self.maj_params({'query_maj':[len(maj_infos[0]),time.ctime()]})
864 else:
865 self.edit_serveur({'maj':0})
866 self.maj_params({'query_maj':[0,time.ctime()]})
867 self.maj_infos = maj_infos
868 except:
869 traceback.print_exc()
870 pass
871 return liste_pkgs
872
874
875 pkg_file = os.path.join(os.path.abspath(config.PATH_ZEPHIR),'data','packages%s.list' % self.id_s)
876 if os.path.isfile(pkg_file):
877 for line in file(pkg_file):
878 pak_name, pak_version = line.split()
879 if pak_name == debname:
880 return maj_checker.check_min_version(pak_version, min_version)
881
882 return None
883
885 """prépare une nouvelle clé ssh pour la connexion uucp à zephir
886 """
887 new_key = os.path.join(self.confdir, 'new_key')
888 addr_file = os.path.join(self.confdir, 'new_addr')
889 if os.path.exists(new_key):
890 os.unlink(new_key)
891 if os.path.exists("%s.pub" % new_key):
892 os.unlink("%s.pub" % new_key)
893 for f_addr in [addr_file, '%s_ok' % addr_file]:
894 if os.path.exists(f_addr):
895 os.unlink(f_addr)
896 zephir_addr = new_addr or config.ADRESSE_ZEPHIR
897 res = os.system("""/usr/bin/ssh-keygen -N "" -b 1024 -t rsa -f %s -C uucp@%s""" % (new_key, zephir_addr))
898
899 if new_addr:
900 f_adr = open(addr_file, 'w')
901 f_adr.write(new_addr)
902 f_adr.close()
903 return res
904
905 - def get_key(self, old_key, new_key, confirm_ip):
906 """envoie une nouvelle clé à un serveur.
907 les 2 clés publiques (ancienne et nouvelles) doivent être passées en paramètre.
908 """
909 try:
910 old_key_path = os.path.join(self.confdir, 'cle_publique')
911 new_key_path = os.path.join(self.confdir, 'new_key.pub')
912 new_key_priv_path = os.path.join(self.confdir, 'new_key')
913 new_addr_path = os.path.join(self.confdir, 'new_addr')
914 old_data = file(old_key_path).read().strip()
915 old_data = base64.encodestring(old_data[old_data.index('ssh-rsa'):])
916 if old_data == old_key:
917
918 data_keys = []
919 new_data = file(new_key_path).read().strip()
920 new_data = base64.encodestring(new_data[new_data.index('ssh-rsa'):])
921 if new_data != new_key:
922 return 0, "nouvelle clé publique non reconnue"
923 if confirm_ip == True:
924 if os.path.isfile(new_addr_path):
925 os.rename(new_addr_path, '%s_ok' % new_addr_path)
926 return 1, ''
927 else:
928 return 0, "changement d'adresse non détecté sur zephir"
929 new_data_priv = base64.encodestring(file(new_key_priv_path).read().strip())
930 os.unlink(new_key_priv_path)
931 return 1, new_data_priv
932 else:
933 return 0, "ancienne clé publique non reconnue"
934 except:
935 return 0, "erreur de récupération des données"
936
950
952 """crée un dictionnaire creole2 et importe les valeurs du serveur"""
953 assert self.version == 'creole1'
954 assert int(module_dest) >= 1
955 assert int(variante_dest) >= 1
956
957 creoledirs = [os.path.join(os.path.abspath(config.PATH_MODULES),str(module_dest),'dicos')]
958 creoledirs.append(os.path.join(os.path.abspath(config.PATH_MODULES),str(module_dest),'variantes',str(variante_dest),'dicos'))
959
960 dico = ZephirDict(creoledirs, self.confdir, mode)
961
962 f_var = open(os.path.join(self.confdir, 'variante_migration'), 'w')
963 f_var.write(str(variante_dest))
964 f_var.close()
965 return dico
966
968 """fonction de récupération des données d'un serveur migré
969 check : vérifie seulement si des données sont migrables sur ce serveur
970 """
971
972 migration_files = {}
973 module = self.module[:self.module.rindex('-')]
974 if module in config.migration_files:
975 migration_files.update(config.migration_files[module])
976
977 if module in migration_perso:
978 for section in migration_perso[module].keys():
979 migration_files[section].extend(migration_perso[module][section])
980 dir_serv = os.path.join(self.confdir,'fichiers_zephir')
981 dir_bak = os.path.join(self.confdir+'-backup','fichiers_zephir')
982
983 if check == True:
984 if len(migration_files.keys()) > 0 and os.path.isdir(dir_bak):
985 return 1, True
986 else:
987 return 1, False
988
989 if not len(migration_files.keys()) > 0:
990 return 1, config.u("""pas de fichiers à migrer""")
991 if not os.path.isdir(dir_bak):
992 return 0, config.u("répertoire backup de migration non trouvé")
993 not_found = []
994 errors = []
995
996 for src, dst, convert in migration_files['files']:
997 fic_src = os.path.join(dir_bak,src)
998 fic_dst = os.path.join(dir_serv,dst)
999 if os.path.isdir(fic_src):
1000
1001 os.path.walk(fic_src, self.tree_copy, (fic_src, fic_dst, convert, errors, migration_files))
1002 elif os.path.isfile(fic_src):
1003 self.copy_fic(fic_src, fic_dst, convert, errors)
1004 else:
1005 not_found.append(src)
1006
1007 droits_zephir = []
1008 dests=[]
1009 for dest, options, user, group, mode in migration_files['rights']:
1010 if dest.endswith("*"):
1011
1012 dests = glob(os.path.join(dir_serv,dest))
1013 else:
1014 if os.path.exists(os.path.join(dir_serv,dest)):
1015 dests = [os.path.join(dir_serv,dest)]
1016 for fic_dest in dests:
1017 if os.path.basename(fic_dest) not in migration_files['exclude']:
1018 cmd_rights = 'chmod %s %s %s;chown %s %s.%s %s' % (options, mode, fic_dest, options, user, group, fic_dest)
1019 res = os.system(cmd_rights)
1020 if res != 0:
1021 errors.append('application des droits impossible : %s' % fic_dest)
1022 else:
1023
1024 droits_zephir.append("%s#%s#%s#%s#%s" % (fic_dest[fic_dest.index('fichiers_zephir'):],mode,user,group,'-R' in options))
1025
1026
1027 fic_droits = open(os.path.join(self.confdir, 'droits_zephir'),'w')
1028 fic_droits.write('\n'.join(droits_zephir))
1029 fic_droits.close()
1030
1031
1032 module_ng_orig = '%s-2.0' % self.module[:self.module.rindex('-')]
1033 module_file = '/usr/share/zephir/dictionnaires/fichiers_%s' % module_ng_orig
1034 serveur_file = os.path.join(self.confdir,'fichiers_zephir','fichiers_zephir')
1035 if os.path.isfile(module_file):
1036
1037 data = file(module_file).read().strip()
1038 if module in destinations_perso:
1039 data += "\n# fichiers ajoutés lors de la migration Eole 1 vers Eole NG"
1040 for dest in destinations_perso[module]:
1041 data += "\n%s" % dest
1042
1043
1044 final_data = "%s\n%s\n%%%%\n%s" % (config.FILE_SECTION,data,config.RPM_SECTION)
1045
1046
1047 dests = file(serveur_file,'w')
1048 dests.write(final_data)
1049 dests.close()
1050
1051 return 1, config.u((not_found,errors))
1052
1054 path_var = os.path.join(self.confdir, 'variante_migration')
1055 if os.path.isfile(path_var):
1056 return open(path_var).read().strip()
1057 else:
1058 return ''
1059
1061
1062 repl_dir = os.path.join(self.confdir, 'replication')
1063 if not os.path.exists(repl_dir):
1064 os.makedirs(repl_dir)
1065 script = os.path.join(repl_dir, 'replication-%s.conf' % rne)
1066
1067 try:
1068 bin_file = StringIO()
1069 data = base64.decodestring(content)
1070 fd = open(script,'wb')
1071
1072 bin_file.write(data)
1073 bin_file.seek(0)
1074 fd.write(bin_file.read())
1075 fd.close()
1076 except:
1077 traceback.print_exc()
1078 return 0, config.u("erreur de l'écriture du fichier %s" % script)
1079 return 1, "OK"
1080
1082 repl_dir = os.path.join(self.confdir, 'replication')
1083 try:
1084 assert os.path.isfile(os.path.join(repl_dir, filename))
1085 os.unlink(os.path.join(repl_dir, filename))
1086
1087 file(os.path.join(self.confdir, 'replication', '.modified'), 'w').close()
1088 except:
1089 return 0, config.u("Erreur lors de la suppression du fichier %s" % filename)
1090 return 1, "OK"
1091
1093
1094 if not os.path.isdir(os.path.join(self.confdir, 'replication')):
1095 repl_state = 0
1096 elif os.path.isfile(os.path.join(self.confdir, 'replication', '.modified')):
1097 repl_state = 2
1098 else:
1099 repl_state = 1
1100 return 1, repl_state
1101
1103
1104 conf_repl = []
1105
1106 if os.path.isdir(os.path.join(self.confdir, 'replication')):
1107 search_path = os.path.join(self.confdir, 'replication', 'replication-*.conf')
1108 try:
1109 for conf_file in glob(search_path):
1110 conf_repl.append(os.path.basename(conf_file))
1111 except:
1112 return 0, config.u("Erreur lors de la recherche des configurations de réplication")
1113 return 1, config.u(conf_repl)
1114
1115 - def tree_copy(self, args, dirname, fnames):
1116 fic_src, fic_dst, convert, errors, migration_files = args
1117 if not os.path.isdir(fic_dst):
1118 os.makedirs(fic_dst)
1119 for fic in fnames:
1120 if fic not in migration_files['exclude']:
1121 src = os.path.join(dirname, fic)
1122 dst = src.replace(fic_src, fic_dst)
1123 if os.path.exists(src):
1124 self.copy_fic(src, dst, convert, errors)
1125
1126 - def copy_fic(self, src, dst, convert, errors):
1127 """copie du fichier src sur dst
1128 convert: si True, convertit le fichier d'ISO-8859-1 vers UTF-8
1129 """
1130 if convert == True:
1131 cmd = '/usr/bin/iconv -f ISO-8859-1 -t UTF-8 -o "%s" "%s"' % (dst, src)
1132 else:
1133 cmd = '/bin/cp -f "%s" "%s"' % (src, dst)
1134 res = os.system(cmd)
1135 if res != 0:
1136 log.msg("erreur lors de la migration des données, la commande suivante a échoué :", cmd)
1137 errors.append(src)
1138
1139
1141 """dictionnaire des serveurs existants gérant les autorisations d'accès
1142 """
1143
1145
1146 self._groupes_serveurs = {}
1147 self._restrictions = {}
1148 self.stats = {}
1149
1150
1151 self._mod_var = self.get_mod_var()
1152 try:
1153 self.update_auths()
1154 except:
1155
1156 pass
1157
1159 cu = cx_pool.create()
1160
1161 try:
1162 cu.execute("select id, libelle, serveurs from groupes_serveurs")
1163 data = cu.fetchall()
1164 need_commit = False
1165 for groupe in data:
1166 id = int(groupe[0])
1167 libelle = str(groupe[1])
1168 serveurs = []
1169
1170 update_gr = False
1171 for serveur in eval(groupe[2]):
1172 if serveur in self:
1173 serveurs.append(serveur)
1174 else:
1175 update_gr = True
1176 if update_gr:
1177
1178 cu.execute("update groupes_serveurs set serveurs=%s where id=%s", (str(serveurs), int(id)))
1179 need_commit = True
1180 timestamp = time.time()
1181 date_creat = timestamp
1182 if self._groupes_serveurs.has_key(id):
1183 date_creat = self._groupes_serveurs[id][2][0]
1184 self._groupes_serveurs[id] = [libelle, serveurs, [date_creat, timestamp]]
1185 if need_commit:
1186 cx_pool.commit(cu)
1187 else:
1188 cx_pool.close(cu)
1189 except:
1190 traceback.print_exc()
1191 cx_pool.close(cu)
1192
1194 """récupére les variantes et leur module"""
1195 cu = cx_pool.create()
1196 try:
1197 cu.execute("select id, module from variantes")
1198 data = cu.fetchall()
1199 cx_pool.close(cu)
1200 except:
1201 data = []
1202 traceback.print_exc()
1203 cx_pool.close(cu)
1204 return dict(data)
1205
1207 params = []
1208 if user != None:
1209 user_clause = " where login=%s"
1210 params.append(user)
1211 else:
1212 user_clause = ""
1213
1214 cu = cx_pool.create()
1215 try:
1216
1217 cu.execute("select login, id_res, type_res from restrictions %s" % user_clause, params)
1218 data = cu.fetchall()
1219 for restriction in data:
1220 login, id_res, type_res = restriction
1221 if not self._restrictions.has_key(login):
1222 self._restrictions[login] = {}
1223 if self._restrictions[login].has_key(type_res):
1224 self._restrictions[login][type_res].append(id_res)
1225 else:
1226 self._restrictions[login][type_res] = [id_res]
1227 cx_pool.close(cu)
1228 except:
1229 traceback.print_exc()
1230 cx_pool.close(cu)
1231
1233 """ajoute une restriction pour un utilisateur et une ressource donnés
1234 type_res : nature des objets à restreindre
1235 id_res ; identifiant de l'objet autorisé
1236 les différents types reconnus sont : 'rne, group, id_mod, id_var' et les attributs
1237 de la classe serveur (id_s, module, version, ...)
1238 """
1239
1240 id_res = str(id_res)
1241 try:
1242 assert id_res in self._restrictions[credential][type_res]
1243 except:
1244 cu = cx_pool.create()
1245
1246 libelle, table, field = config.type_res_label[type_res]
1247 if field in ('rne','libelle'):
1248
1249 query = "select * from %s where %s ilike %%s" % (table, field)
1250 params = (id_res,)
1251 else:
1252
1253 query = "select * from %s where %s = %%s" % (table, field)
1254 params = (int(id_res),)
1255 try:
1256 cu.execute(query, params)
1257
1258 if cu.fetchone() == None:
1259 raise ValueError('identifiant de ressource inconnu')
1260 except Exception, e:
1261 cx_pool.close(cu)
1262 return False
1263 try:
1264 params = (credential, type_res, id_res)
1265 cu.execute("""insert into restrictions (login, type_res, id_res) values (E%s,E%s,E%s)""", params)
1266 except:
1267
1268 cx_pool.rollback(cu)
1269 return False
1270 cx_pool.commit(cu)
1271 if not self._restrictions.has_key(credential):
1272 self._restrictions[credential] = {}
1273 if not self._restrictions[credential].has_key(type_res):
1274 self._restrictions[credential][type_res] = []
1275 self._restrictions[credential][type_res].append(id_res)
1276 else:
1277
1278 pass
1279 return True
1280
1282 """renvoie la liste des restrictions d'un utilisateur
1283 """
1284 if not self._restrictions.has_key(credential):
1285 return []
1286 if type_res == None:
1287
1288 return self._restrictions[credential]
1289 else:
1290
1291 if self._restrictions[credential].has_key(type_res):
1292 return self._restrictions[credential][type_res]
1293 else:
1294 return []
1295
1297 """enleve une restriction d'un utilisateur
1298 """
1299 id_res = str(id_res)
1300 try:
1301 liste_res = self._restrictions[credential][type_res]
1302 assert id_res in liste_res
1303 except:
1304
1305 return False
1306
1307 cu = cx_pool.create()
1308 try:
1309 cu.execute("""delete from restrictions where login=%s and type_res=%s and id_res=%s""", (credential, type_res, id_res))
1310 cx_pool.commit(cu)
1311 except:
1312 traceback.print_exc()
1313 cx_pool.rollback(cu)
1314 return False
1315
1316 self._restrictions[credential][type_res].remove(id_res)
1317 if self._restrictions[credential][type_res] == []:
1318 del(self._restrictions[credential][type_res])
1319 return True
1320
1322 """renvoie les informations de permissions associées à un fichier
1323 """
1324
1325 permsfile = data_dir+os.sep+'droits_zephir'
1326 if os.path.isfile(permsfile):
1327 f_rights = file(permsfile)
1328 data = f_rights.read().strip().split('\n')
1329 f_rights.close()
1330 else:
1331 data = []
1332 mode = user = group = ""
1333 recursive = False
1334 if filepath != "":
1335 result = {filepath:[mode, user, group, recursive]}
1336 else:
1337 result = {}
1338 for line in data:
1339 if line.startswith(filepath+'#') or filepath == "":
1340 try:
1341 filename, mode, user, group, recursive = line.split('#')
1342 if recursive != '':
1343 recursive = eval(recursive)
1344 result[filename] = [mode, user, group, recursive]
1345 if filepath != "":
1346 break
1347 except:
1348
1349 pass
1350 return result
1351
1353 """enregistre les informations de permissions associées à un(des) fichier(s)
1354 @param data_dir: chemin ou trouver le fichier droits_zephir
1355 """
1356
1357 permsfile = data_dir+os.sep+'droits_zephir'
1358 data = self.get_file_perms(data_dir)
1359 data.update(rights)
1360
1361 lines = []
1362 for filepath in data.keys():
1363
1364 lines.append("%s#%s#%s#%s#%s" % (filepath, data[filepath][0], data[filepath][1], data[filepath][2],data[filepath][3]))
1365
1366 f_rights = file(permsfile,'w')
1367 f_rights.write('\n'.join(lines))
1368 f_rights.close()
1369 return True
1370
1372 """supprime les informations de permissions associées à un fichier (ou tous)
1373 """
1374
1375 permsfile = data_dir+os.sep+'droits_zephir'
1376 if not os.path.exists(permsfile):
1377
1378 return False
1379 if filepath != "":
1380 f_rights = file(permsfile)
1381 data = f_rights.read().strip().split('\n')
1382 f_rights.close()
1383 if recurse == True:
1384 search_pattern = filepath
1385 else:
1386 search_pattern = filepath + '#'
1387 for line in data:
1388 if line.startswith(search_pattern):
1389 data.remove(line)
1390 else:
1391 data = []
1392
1393 try:
1394 f_rights = file(permsfile,'w')
1395 f_rights.write('\n'.join(data))
1396 f_rights.close()
1397 except:
1398 return False
1399 return True
1400
1402
1403
1404 serv = dict.get(self,key)
1405 if self._restrictions.has_key(credential):
1406 for type_res, res in self._restrictions[credential].items():
1407 if res == []:
1408
1409 continue
1410 res_ok = True
1411
1412
1413 if type_res == 'rne':
1414 rne_ok = False
1415 for rne in res:
1416
1417 if rne.endswith('%'):
1418 if serv.rne.startswith(rne.split('%')[0]):
1419
1420 rne_ok = True
1421 break
1422 if not rne_ok:
1423 if not serv.rne in res:
1424 res_ok = False
1425 elif type_res == 'groupe':
1426
1427 serv_in_groupes = False
1428 for groupe in res:
1429 if serv.id_s in self._groupes_serveurs[int(groupe)][1]:
1430 serv_in_groupes = True
1431 break
1432 if serv_in_groupes == False:
1433 res_ok = False
1434 else:
1435
1436 if not str(getattr(serv,type_res)) in [str(i) for i in res]:
1437 res_ok = False
1438 if not res_ok:
1439
1440 raise ResourceAuthError("unauthorized resource : %s" % key)
1441
1443
1444 if self._restrictions.has_key(credential):
1445 if self._restrictions[credential].has_key('groupe'):
1446 if self._restrictions[credential]['groupe'] != []:
1447 if str(groupe) not in self._restrictions[credential]['groupe']:
1448
1449
1450 raise ResourceAuthError("unauthorized resource : %s" % groupe)
1451
1453
1454 if self._restrictions.has_key(credential):
1455 if self._restrictions[credential].has_key('id_mod'):
1456 if self._restrictions[credential]['id_mod'] != []:
1457 if str(id_mod) not in self._restrictions[credential]['id_mod']:
1458
1459 raise ResourceAuthError("unauthorized module : %s" % id_mod)
1460
1462
1463 if self._restrictions.has_key(credential):
1464 try:
1465 var_mod = str(self._mod_var[int(id_var)])
1466 except:
1467
1468 self._mod_var = self.get_mod_var()
1469 var_mod = str(self._mod_var[int(id_var)])
1470
1471 if self._restrictions[credential].has_key('id_mod'):
1472 if self._restrictions[credential]['id_mod'] != []:
1473 if var_mod not in self._restrictions[credential]['id_mod']:
1474 raise ResourceAuthError("accès au module %s interdit" % var_mod)
1475
1476 if self._restrictions[credential].has_key('id_var'):
1477 if self._restrictions[credential]['id_var'] != []:
1478 if str(id_var) not in self._restrictions[credential]['id_var']:
1479
1480 raise ResourceAuthError("accès à la variante %s interdit" % id_var)
1481
1483
1484 rne_ok = True
1485 if self._restrictions.has_key(credential):
1486 if self._restrictions[credential].has_key('rne'):
1487 if self._restrictions[credential]['rne'] != []:
1488 if str(rne) not in self._restrictions[credential]['rne']:
1489 rne_ok = False
1490 for etab in self._restrictions[credential]['rne']:
1491 if etab.endswith('%'):
1492 if str(rne).startswith(etab.split('%')[0]):
1493 rne_ok = True
1494 if not rne_ok:
1495
1496 raise ResourceAuthError("unauthorized module : %s" % rne)
1497
1498 - def get(self, credential, key):
1499 if key in self.keys():
1500 self.check_serv_credential(credential, key)
1501 else:
1502 raise KeyError, "serveur inexistant"
1503 return dict.get(self,key)
1504
1506 self.stats['nb_serv'] = len(self)
1507 return self.stats
1508
1510 """renvoie la liste des serveurs en alerte
1511 """
1512 servs=[]
1513 for id_serv in self.keys():
1514 try:
1515 serv = self.get(credential, int(id_serv))
1516 except ResourceAuthError:
1517
1518 continue
1519 if serv.get_status() not in [1, -1]:
1520 servs.append(serv)
1521 return servs
1522
1524 """renvoie la liste des serveurs en cours de migration/non migrés
1525 """
1526 servs=[[],[]]
1527 for id_serv in self.keys():
1528 try:
1529 serv = self.get(credential, int(id_serv))
1530 except ResourceAuthError:
1531
1532 continue
1533 params = serv.get_params()
1534 if params['migration_ok'] == 0:
1535 servs[0].append(serv)
1536 elif params['migration_ok'] == -1:
1537 servs[1].append(serv)
1538 return servs
1539
1541 """vérifie si des serveurs ont été modifiés
1542 @param serveurs : dictionnaires {idserveur:timestamp}
1543 @param last_check : Si != None, on renvoie les serveurs créés après cette date (timestamp)
1544 @return : liste d'id de serveurs
1545 """
1546 modifs = {}
1547 serv_pool = []
1548 for id_serv in [str(cle) for cle in self.keys()]:
1549 try:
1550 serv = self.get(credential, int(id_serv))
1551 except ResourceAuthError:
1552
1553 log.msg("server %s not authorized" % id_serv)
1554 if serveurs.has_key(id_serv):
1555 modifs[id_serv] = "deleted"
1556 else:
1557 serv_pool.append(str(serv.id_s))
1558 if serveurs.has_key(id_serv):
1559 if serv.modified > serveurs[id_serv]:
1560
1561 modifs[id_serv] = serv.modified
1562 elif last_check != None:
1563 if serv.created > last_check:
1564
1565
1566 modifs[id_serv] = serv.modified
1567
1568 for id_serv in serveurs.keys():
1569 if id_serv not in serv_pool:
1570 modifs[id_serv] = "deleted"
1571
1572 return modifs
1573
1575 """vérifie si des groupes ont été modifiés
1576 @param groupes : dictionnaires {idgroupe:timestamp}
1577 @param last_check : Si != None, on renvoie les serveurs créés après cette date (timestamp)
1578 @return : dictionnaire {id_gr:[libelle, serveurs, [date_creat, date_modif]]}
1579 """
1580 modifs = {}
1581
1582 for id_gr, data in self._groupes_serveurs.items():
1583 try:
1584 group = self.get_groupes(credential, id_gr)
1585 except KeyError, ResourceAuthError:
1586
1587 log.msg("group %s no longer exists or not authorized" % id_gr)
1588 modifs[str(id_gr)] = "deleted"
1589 else:
1590
1591 id_gr = str(id_gr)
1592 if groupes.has_key(id_gr):
1593 if data[2][1] > groupes[id_gr]:
1594
1595 modifs[id_gr] = data
1596 elif last_check != None:
1597 if data[2][0] > last_check:
1598
1599 modifs[id_gr] = data
1600 return modifs
1601
1602 - def add_groupe(self, credential, libelle, serveurs):
1603 query = """insert into groupes_serveurs (libelle,serveurs) values (E%s, %s)"""
1604 params = (libelle, str(serveurs))
1605 cu = cx_pool.create()
1606 try:
1607 cu.execute(query, params)
1608 except:
1609 traceback.print_exc()
1610 cx_pool.rollback(cu)
1611 return False
1612 cx_pool.commit(cu)
1613 self.update_groupes()
1614
1615 if self._restrictions.has_key(credential):
1616 if self._restrictions[credential].has_key('groupe'):
1617
1618 for id_gr in self._groupes_serveurs.keys():
1619 if self._groupes_serveurs[id_gr][0] == libelle:
1620 self.add_restriction(credential,'groupe',str(id_gr))
1621 return True
1622
1623 - def get_groupes(self, credential, id_groupe=None, alertes=False):
1624 if id_groupe != None:
1625 groupes = [int(id_groupe)]
1626 else:
1627 groupes = self._groupes_serveurs.keys()
1628
1629 res = []
1630 for groupe in groupes:
1631 try:
1632 self.check_gr_credential(credential, groupe)
1633 except:
1634
1635 continue
1636 libelle, serveurs, timestamps = self._groupes_serveurs[groupe]
1637
1638 res.append([int(groupe), libelle, serveurs])
1639 return res
1640
1641 - def edit_groupe(self, credential, id_groupe, libelle, serveurs):
1642
1643 id_groupe = int(id_groupe)
1644 self.check_gr_credential(credential, id_groupe)
1645
1646 cu = cx_pool.create()
1647 query = """update groupes_serveurs set libelle=E%s, serveurs=%s where id=%s"""
1648 params = (libelle,str(serveurs),int(id_groupe))
1649 try:
1650 cu.execute(query, params)
1651 except:
1652 traceback.print_exc()
1653 cx_pool.rollback(cu)
1654 return False
1655 cx_pool.commit(cu)
1656
1657 date_creat = self._groupes_serveurs[id_groupe][2][0]
1658 self._groupes_serveurs[id_groupe] = [libelle, serveurs, [date_creat,time.time()]]
1659 return True
1660
1662
1663 id_groupe = int(id_groupe)
1664 self.check_gr_credential(credential, id_groupe)
1665
1666 rech_params = ('[%d]' % id_groupe, '[%%, %d, %%]' % id_groupe, '[%%, %d]' % id_groupe, '[%d, %%]' % id_groupe)
1667 cursor = cx_pool.create()
1668 try:
1669 cursor.execute("""select login,groupes from users where groupes like %s or groupes like %s or groupes like %s or groupes like %s""", rech_params)
1670 data=cursor.fetchall()
1671
1672 for user in data:
1673
1674 groupes = eval(user[1])
1675 if id_groupe in groupes:
1676 groupes.remove(id_groupe)
1677 sql_update = """update users set groupes=%s where login=E%s"""
1678 params = (str(groupes), user[0])
1679 cursor.execute(sql_update, params)
1680
1681 cursor.execute("""delete from groupes_serveurs where id = %s""", (int(id_groupe),))
1682 cx_pool.commit(cursor)
1683 except:
1684 traceback.print_exc()
1685 cx_pool.rollback(cursor)
1686 return False
1687
1688 del(self._groupes_serveurs[id_groupe])
1689 return True
1690
1691
1693
1694 id_groupe = int(id_groupe)
1695 self.check_gr_credential(credential, id_groupe)
1696
1697
1698 for serv in serveurs:
1699 if serv not in self._groupes_serveurs[id_groupe][1]:
1700 self._groupes_serveurs[id_groupe][1].append(serv)
1701 self._groupes_serveurs[id_groupe][2] = [time.time(),time.time()]
1702 cu = cx_pool.create()
1703
1704 try:
1705 query = """update groupes_serveurs set serveurs=%s where id=%s"""
1706 params = (str(self._groupes_serveurs[id_groupe][1]), id_groupe)
1707 cu.execute(query, params)
1708 cx_pool.commit(cu)
1709 except:
1710 traceback.print_exc()
1711 cx_pool.rollback(cu)
1712
1713 - def add_serveur(self, credential, rne, libelle, materiel, processeur, disque_dur, date_install, installateur, tel, remarques, module_initial, module_actuel, variante, timestamp_serveur, timeout):
1714
1715 if self._restrictions.has_key(credential):
1716 if self._restrictions[credential].has_key('rne'):
1717 self.check_etab_credential(credential, rne)
1718 if self._restrictions[credential].has_key('id_mod'):
1719 if module_actuel not in self._restrictions[credential]['id_mod']:
1720 raise ResourceAuthError("unauthorized resource %s" % module_actuel)
1721 if self._restrictions[credential].has_key('variante'):
1722 cu = cx_pool.create()
1723 cu.execute('select libelle from variantes where id=%s', (int(variante),))
1724 libel_var = cu.fetchone()[0]
1725 cx_pool.close(cu)
1726
1727 if libel_var != 'standard' and variante not in self._restrictions[credential]['variante']:
1728 raise ResourceAuthError("unauthorized resource %s" % variante)
1729
1730 cu = cx_pool.create()
1731 query = """insert into serveurs (rne,libelle,materiel,processeur,disque_dur,date_install,installateur,tel,remarques,module_initial,module_actuel,variante,timestamp,timeout) values (E%s,E%s,E%s,E%s,E%s,E%s,E%s,%s,E%s,%s,%s,%s,%s,%s)"""
1732 params = (rne, libelle, materiel, processeur, disque_dur, date_install, installateur, tel, remarques, int(module_initial), int(module_actuel), int(variante), timestamp_serveur, int(timeout))
1733 cu.execute(query, params)
1734
1735 query = """select id from serveurs where rne=E%s and libelle=E%s and date_install=E%s and installateur=E%s and remarques=E%s and module_actuel=%s and variante=%s and timestamp=%s"""
1736 params = (rne, libelle, date_install, installateur, remarques, int(module_actuel), int(variante), timestamp_serveur)
1737 cu.execute(query, params)
1738 id_serveur = int(cu.fetchone()[0])
1739 self[id_serveur] = Serveur(self, id_serveur,cu)
1740 self.stats['no_contact'].append(id_serveur)
1741 self.stats['serv_modules'][str(module_actuel)] = self.stats['serv_modules'].get(str(module_actuel),0) + 1
1742 self.stats['serv_variantes'][str(variante)] = self.stats['serv_variantes'].get(str(variante),0) + 1
1743 cx_pool.commit(cu)
1744 return self[id_serveur]
1745
1765
1770
1787
1788
1790 """crée un pool de tous les serveurs existants
1791 """
1792
1793 pool=ServeurPool()
1794 cu = cx_pool.create()
1795 try:
1796 cu.execute("select id, rne, libelle, module_actuel, variante, timeout, etat, md5s, maj, no_alert, last_contact from serveurs")
1797 data = cu.fetchall()
1798 nbserv = len(data)
1799 no_contact = []
1800
1801 pool.stats['serv_modules'] = {}
1802 pool.stats['serv_variantes'] = {}
1803
1804 for var, module in pool._mod_var.items():
1805 if str(module) not in pool.stats['serv_modules']:
1806 pool.stats['serv_modules'][str(module)] = 0
1807 if str(var) not in pool.stats['serv_variantes']:
1808 pool.stats['serv_variantes'][str(var)] = 0
1809 for serv in data:
1810
1811 if serv[10] == None:
1812 no_contact.append(int(serv[0]))
1813
1814 pool[serv[0]] = Serveur(pool, serv[0], cu, serv[1:2])
1815 pool[serv[0]].update_data(cu, serv[2:10])
1816
1817 pool.stats['serv_modules'][str(serv[3])] = pool.stats['serv_modules'].get(str(serv[3]),0) + 1
1818 pool.stats['serv_variantes'][str(serv[4])] = pool.stats['serv_variantes'].get(str(serv[4]),0) + 1
1819 pool.stats['no_contact'] = no_contact
1820 pool.stats['nb_serv'] = len(pool)
1821
1822 pool.update_groupes()
1823 cx_pool.close(cu)
1824 except:
1825 traceback.print_exc()
1826 cx_pool.close(cu)
1827 return pool
1828
1829
1830
1831 text_characters = "".join(map(chr, range(32, 255)) + list("\n\r\t\b"))
1832 _null_trans = string.maketrans("", "")
1833
1834 -def istextfile(filename, blocksize = 1024):
1835 return istext(open(filename).read(blocksize))
1836
1838 if "\0" in s:
1839 return 0
1840
1841 if not s:
1842 return 1
1843
1844
1845
1846 t = s.translate(_null_trans, text_characters)
1847
1848
1849
1850 if len(t)/len(s) > 0.10:
1851 return 0
1852 return 1
1853