1
2
3
4
5
6
7
8
9
10
11
12
13 """module de gestion des serveurs
14 """
15 from twisted.python import log
16 from zephir.backend.db_utils import *
17 from zephir.backend import config
18 from zephir.backend.config import u
19 from zephir.backend.xmlrpceole import XMLRPCEole as XMLRPC
20 from zephir.monitor.collecteur import ServeurStatus
21 from zephir.backend.lib_backend import ResourceAuthError, istextfile
22
23 import psycopg2 as PgSQL
24
25 import sys,os,shutil,time,dico,base64, traceback
26
27 FILE_SECTION = """# section 1
28 # liste des fichiers à sauvegarder+# (ne pas modifier sauf pour créer ou mettre à jour la variante)"""
29 RPM_SECTION = """# section 2
30 # inscrire les noms des paquetages qui seront installés à la mise à jour du serveur
31 # (ils doivent être présents sur le serveur de mise à jour)"""
32
34 """serveur XMLRPC zephir pour la gestion des serveurs
35 """
36
37 - def __init__(self,parent,agent_manager,bdd='zephir-parc'):
38 self.dbpool = db_connect()
39 self.dbpool.noisy = 0
40 XMLRPC.__init__(self)
41 self.agent_manager = agent_manager
42 self.parent = parent
43
45 """Formatage de la liste des serveurs
46 """
47 l=[]
48 auth_error = False
49 for serveur in serveurs:
50
51 try:
52 serv = self.parent.s_pool.get(cred_user,int(serveur[0]))
53 except ResourceAuthError:
54 auth_error = True
55 continue
56 if serveur[14] is None:
57 timeout = 0
58 else:
59 timeout =int(serveur[14])
60 if serveur[17] == None:
61 params = serv.get_params()
62 else:
63 params = serveur[17]
64 if serveur[18] == None:
65 maj_serv = -1
66 else:
67 maj_serv = serveur[18]
68 if serveur[19] == None:
69 md5_serv = -1
70 else:
71 md5_serv = serveur[19]
72 l.append(
73 {'id':serveur[0],
74 'rne':serveur[1],
75 'libelle':serveur[2],
76 'materiel':serveur[3],
77 'processeur':serveur[4],
78 'disque_dur':serveur[5],
79 'date_install':str(serveur[6]),
80 'installateur':serveur[7],
81 'tel':serveur[8],
82 'remarques':serveur[9],
83 'module_initial':serveur[10],
84 'module_actuel':serveur[11],
85 'variante':serveur[12],
86 'timeout':timeout,
87 'timestamp':serv.modified,
88 'etat':serv.get_status(),
89 'params':params,
90 'maj':maj_serv,
91 'md5s':md5_serv,
92 })
93 if l == [] and auth_error == True:
94
95 raise ResourceAuthError("""Vous n'avez accès à aucun serveur dans ce groupe""")
96 return 1,u(l)
97
99 """Formattage de la liste des logs
100 """
101
102 servs = {}
103 for ligne in lignes:
104 id_serveur = ligne[1]
105 try:
106 if id_serveur not in servs.keys():
107 self.parent.s_pool.get(cred_user,int(id_serveur))
108 except:
109 servs[id_serveur] = False
110 else:
111 servs[id_serveur] = True
112
113 l=[]
114 for ligne in lignes:
115 if servs[ligne[1]] == True:
116 l.append(
117 {'id':ligne[0]
118 ,'id_serveur':ligne[1]
119 ,'date':str(ligne[2])
120 ,'action':ligne[3]
121 ,'message':ligne[4]
122 ,'etat':ligne[5]})
123 return 1,u(l)
124
125
126
127
128
129
131 """crée l'arborescence zephir d'un nouveau serveur"""
132
133 serveur_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'conf'+os.sep+str(rne)+os.sep+str(id_serveur)
134 try:
135 os.makedirs(serveur_dir)
136 except:
137 return 0,u("""erreur de création du répertoire du serveur""")
138
139
140 try:
141 os.makedirs(serveur_dir+os.sep+'fichiers_zephir')
142 os.makedirs(serveur_dir+os.sep+'fichiers_perso')
143 os.makedirs(serveur_dir+os.sep+'dicos')
144 os.makedirs(serveur_dir+os.sep+'patchs')
145 except:
146 shutil.rmtree(serveur_dir)
147 return 0,u("""erreur de création du répertoire des fichiers spécifiques au module""")
148
149
150 if os.path.isdir(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/dicos'):
151
152 os.makedirs(serveur_dir+os.sep+'dicos/local')
153 retour = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/dicos '+serveur_dir+'/dicos/module')
154 retour = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/module.eol '+serveur_dir+'/module.eol')
155 else:
156
157 retour = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/dictionnaire'+' '+serveur_dir+'/dictionnaire')
158 if retour != 0:
159 shutil.rmtree(serveur_dir)
160 return 0, u("""erreur de lien sur le dictionnaire""")
161
162
163
164 retour = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+os.sep+'dico.eol'+' '+serveur_dir+os.sep+'dico.eol')
165 if retour == 0:
166 retour = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+os.sep+'droits_zephir'+' '+serveur_dir+os.sep+'droits_variante')
167
168 if retour == 0:
169 retour = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+'/patchs'+' '+serveur_dir+'/patchs/variante')
170
171 if retour == 0:
172 retour = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+'/dicos'+' '+serveur_dir+'/dicos/variante')
173
174 if retour == 0:
175 retour = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+'/fichiers_perso'+' '+serveur_dir+'/fichiers_perso/variante')
176
177 if retour == 0:
178 retour = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+'/fichiers_zephir'+' '+serveur_dir+'/fichiers_zephir/variante')
179 if retour == 0:
180 try:
181 os.makedirs(serveur_dir+os.sep+'uucp')
182 except:
183 shutil.rmtree(serveur_dir)
184 return 0, u("""erreur de création du répertoire uucp""")
185
186 if retour != 0:
187 shutil.rmtree(serveur_dir)
188 return 0, u("""erreur de création des liens vers la variante""")
189 else:
190 return 1,u('ok')
191
193 """permet de vérifier si des serveurs ont été modifiés
194 """
195 return 1, u(self.parent.s_pool.check_serveurs(cred_user, serveurs, last_check))
196
198 """permet de vérifier si des serveurs ont été modifiés
199 """
200 return 1, u(self.parent.s_pool.check_groupes(cred_user, groupes, last_check))
201
203 """modifie un serveur Eole1 vers NG"""
204 if variante_dest == None:
205 query = "select modules.id, modules.libelle, modules.version, variantes.id from modules,variantes \
206 where modules.id=%s and modules.id=variantes.module and variantes.libelle='standard'" % str(module_dest)
207 else:
208 query = "select modules.id, modules.libelle, modules.version, variantes.id from modules, variantes \
209 where modules.id=%s and modules.id=variantes.module and variantes.id=%s" % (str(module_dest), str(variante_dest))
210 return self.dbpool.runQuery(query).addCallbacks(self._migrate_serveur,db_client_failed,callbackArgs=[cred_user, id_serveur, hw_infos])
211
213 try:
214 id_serveur = int(id_serveur)
215 serv = self.parent.s_pool.get(cred_user, id_serveur)
216 except KeyError:
217 return 0, u("""serveur inconnu""")
218
219 try:
220 lib_new = data[0][1]
221 id_new_mod = int(data[0][0])
222 version_new = int(data[0][2])
223 id_variante = int(data[0][3])
224 lib_act = serv.get_module().split('-')[0]
225 assert serv.version == "creole1" and version_new == 2
226 assert lib_new.split('-')[0] == lib_act.split('-')[0]
227 except:
228 return 0,u("""la migration vers le module demandé n'est pas gérée""")
229 query = "select module_actuel, variante, materiel, processeur, disque_dur, date_install, installateur, tel, remarques, timeout from serveurs where id=%s" % (id_serveur)
230 return self.dbpool.runQuery(query).addCallbacks(self._backup_serveur_data, db_client_failed,callbackArgs=[serv,id_new_mod,id_variante, hw_infos, cred_user])
231
233 path_ori = serv.get_confdir()
234 path_bak = path_ori + "-backup"
235
236 if os.path.exists(path_bak):
237 return 0, u("""répertoire de backup déjà présent: %s""" % path_bak)
238
239 sql_data = "::".join([str(val).replace("'","''") for val in data[0]])
240 f_var_ori = file(os.path.join(path_ori,"sql_data.ori"),'w')
241 f_var_ori.write(sql_data)
242 f_var_ori.close()
243
244 res = os.system("/bin/mv %s %s" % (path_ori, path_bak))
245 if res != 0:
246 return 0, u("""erreur de création du répertoire de backup""")
247
248 materiel = ""
249 for row in ['materiel','processeur','disque_dur','installateur', 'date_install']:
250 if hw_infos.has_key(row):
251 if hw_infos[row] != '':
252 materiel += ", %s='%s'" % (row, hw_infos[row])
253
254 query = "update serveurs set module_actuel=%s, variante=%s, params=''%s where id=%s" % (id_new_mod, id_variante, materiel, serv.id_s)
255 return self.dbpool.runOperation(query).addCallbacks(self._migrate_serveur_data, db_client_failed,callbackArgs=[serv,id_new_mod,id_variante,cred_user])
256
258
259 ret, msg = self._cree_arbo_serveur(serv.id_s,id_mod,serv.rne,id_var)
260 if ret != 1:
261 self.revert_migration(None, serv)
262 return ret, msg
263 serv.update_data()
264
265
266 path_ori = serv.get_confdir()
267 path_bak = path_ori + "-backup"
268 res = 0
269 for fic in ('auth_keys','vpn'):
270 if os.path.isdir(os.path.join(path_ori,fic)):
271 shutil.rmtree(os.path.join(path_ori,fic))
272 if os.path.exists(os.path.join(path_bak,fic)):
273 res = os.system("/bin/cp -rf %s %s" % (os.path.join(path_bak,fic),os.path.join(path_ori,fic)))
274 if res != 0:
275 break
276 if res != 0:
277 return 0, u("""erreur de copie des fichiers de configuration uucp""")
278
279 try:
280 fic_cle_publique = os.path.join(path_bak,'cle_publique')
281
282 if os.path.isfile(fic_cle_publique):
283
284 backup_cle = open(fic_cle_publique,"r")
285 old_cle = backup_cle.read().strip().split('\n')[0]
286 backup_cle.close()
287
288 self._remove_ssh_key(old_cle)
289 except:
290 traceback.print_exc()
291
292 return self._update_conf_uucp(cred_user, serv.id_s, serv.rne, "")
293
295 """fonction de récupération des données d'un serveur migré
296 """
297 try:
298 id_serveur = int(id_serveur)
299 serv = self.parent.s_pool.get(cred_user, id_serveur)
300 return serv.migrate_data(check)
301 except KeyError:
302 return 0, u("""serveur inconnu""")
303
304
306 """retour en arrière sur la migration d'un serveur
307 """
308 try:
309 id_serveur = int(id_serveur)
310 serv = self.parent.s_pool.get(cred_user, id_serveur)
311 return self._revert_migration(serv)
312 except KeyError, ValueError:
313 return 0, u("""id de serveur non valide : %s""" % str(id_serveur))
314
316 path_ori = serv.get_confdir()
317 path_bak = path_ori + "-backup"
318 if not os.path.isdir(path_bak):
319 return 0, u("""répertoire de backup non retrouvé""")
320
321 f_var_ori = file(os.path.join(path_bak,"sql_data.ori"))
322 data_ori = f_var_ori.read().strip().split('::')
323 f_var_ori.close()
324 try:
325 assert len(data_ori) == 10
326 except:
327 return 0, u("""impossible de relire les données sql d'origine""")
328
329 data_ori.append(serv.id_s)
330 query = "update serveurs set \
331 module_actuel=%s,\
332 variante=%s,\
333 materiel='%s',\
334 processeur='%s',\
335 disque_dur='%s',\
336 date_install='%s',\
337 installateur='%s',\
338 tel='%s',\
339 remarques='%s',\
340 timeout=%s,\
341 params=null, maj=null where id=%s" % tuple(data_ori)
342 return self.dbpool.runOperation(query).addCallbacks(self._revert_migration2,db_client_failed,callbackArgs=[serv, path_ori, path_bak])
343
345 fic_cle_publique = os.path.join(path_ori,'cle_publique')
346 try:
347
348 if os.path.isfile(fic_cle_publique):
349 backup_cle = open(fic_cle_publique,"r")
350 new_key = backup_cle.read().strip().split('\n')[0]
351 backup_cle.close()
352
353 self._remove_ssh_key(new_key)
354 except:
355 traceback.print_exc()
356 if os.path.isdir(path_ori):
357 shutil.rmtree(path_ori)
358 res = os.system("/bin/mv %s %s" % (path_bak, path_ori))
359 if res != 0:
360 return 0, u("""erreur de mise en place des données sauvegardées""")
361 os.unlink(os.path.join(path_ori,"sql_data.ori"))
362 try:
363
364 if os.path.isfile(fic_cle_publique):
365
366 backup_cle = open(fic_cle_publique,"r")
367 old_cle = backup_cle.read().strip().split('\n')[0]
368 backup_cle.close()
369
370 self._authorize_ssh_key(old_cle)
371 except:
372 traceback.print_exc()
373 serv.update_data()
374 return 1, "OK"
375
377 """regarde si un backup de migration est présent pour un serveur
378 """
379 try:
380 id_serveur = int(id_serveur)
381 serv = self.parent.s_pool.get(cred_user, id_serveur)
382 path_serv = serv.get_confdir()
383 except KeyError:
384 return 0, u("""serveur inconnu""")
385 if os.path.isdir(path_serv + '-backup'):
386 return 1, True
387 else:
388 return 1, False
389
390 - def xmlrpc_add_serveur(self,cred_user, rne, libelle, materiel, processeur, disque_dur,
391 date_install, installateur, tel, remarques,
392 module_initial, module_actuel, timeout, variante=None, cle_rsa1=""
393 ):
394 """ajout d'un serveur dans la base zephir"""
395
396 if rne:
397
398 liste_donnees = [cred_user, rne, libelle, materiel, processeur, disque_dur, date_install, installateur, tel, remarques, module_initial, module_actuel, variante, timeout, cle_rsa1]
399 query = """select id from variantes where module = %s and libelle = 'standard'""" % module_actuel
400 return self.dbpool.runQuery(query).addCallbacks(self._add_serveur1, db_client_failed,callbackArgs=liste_donnees)
401 else:
402
403 return 0,u("""arguments à fournir:
404 rne,libelle,materiel,processeur,disque_dur,date_install,
405 installateur,tel,remarques,module_initial,module_actuel,variante""")
406
407
408 - def _add_serveur1(self, search_result, cred_user, rne, libelle, materiel, processeur, disque_dur,
409 date_install, installateur, tel, remarques,
410 module_initial, module_actuel, variante, timeout, cle_rsa1=""
411 ):
412 """insertion du serveur dans la base de données"""
413
414 if variante is None:
415 variante = search_result[0][0]
416 timestamp_serveur = str(time.time())
417 try:
418 timeout = int(timeout)
419 except:
420 timeout = 0
421
422 try:
423 id_serveur = self.parent.s_pool.add_serveur(cred_user, rne,libelle,materiel,processeur,disque_dur,date_install,installateur,tel,remarques,module_initial,module_actuel,variante,timestamp_serveur,timeout)
424 except Exception, e:
425 return 0, u(str(e))
426
427 result,errmsg = self._cree_arbo_serveur(id_serveur,module_actuel,rne,variante)
428 if result == 0:
429
430 self.xmlrpc_del_serveur(cred_user, id_serveur)
431 return 0, u(errmsg)
432 else:
433 return self._update_conf_uucp(cred_user, id_serveur, rne, cle_rsa1)
434
436
437 id_uucp = str(rne)+'-'+str(id_serveur)
438 passwd_uucp = str(rne)+'-'+str(id_serveur)+'-'+str(time.time())
439 id_uucp = str(rne)+'-'+str(id_serveur)
440
441 chaine_conf=config.CONFIG_UUCP % (id_serveur,id_uucp,id_uucp,passwd_uucp)
442 try:
443 if not os.path.isdir("/etc/uucp/serveurs/"):
444 os.makedirs("/etc/uucp/serveurs/")
445 fic_conf=open("/etc/uucp/serveurs/"+id_uucp+".sys","w")
446 fic_conf.write(chaine_conf)
447 fic_conf.close()
448 except:
449
450 self.xmlrpc_del_serveur(cred_user, id_serveur)
451 return 0,u("""erreur de création de la configuration uucp""")
452 else:
453
454 test=os.system('grep "sysfile /etc/uucp/serveurs/'+id_uucp+'.sys" /etc/uucp/config_zephir')
455 result = 0
456 if test != 0:
457
458 result=os.system('echo "sysfile /etc/uucp/serveurs/'+id_uucp+'.sys" >>/etc/uucp/config_zephir')
459 if result == 0:
460
461 try:
462 fic_pass=file('/etc/uucp/passwd_zephir')
463 lines=fic_pass.read().strip().split('\n')
464 fic_pass.close()
465
466 content=[]
467 for line in lines:
468
469 if not line.startswith(id_uucp+' '):
470 content.append(line)
471
472 content.append("%s %s" % (id_uucp,passwd_uucp))
473
474 fic_pass=file('/etc/uucp/passwd_zephir','w')
475 lines=fic_pass.write("\n".join(content))
476 fic_pass.close()
477 except:
478 result = 1
479 if result == 0:
480
481 return self._conf_uucp(id_serveur, rne, passwd_uucp, cle_rsa1)
482 if result != 0:
483 self.xmlrpc_del_serveur(cred_user, id_serveur)
484 return 0,u("""erreur de mise à jour de la configuration uucp""")
485
486
487 - def _conf_uucp(self,id_serveur,rne,passwd_uucp,cle_rsa1=""):
488 """création des fichiers de configuration uucp du serveur"""
489 path_dest=os.path.abspath(config.PATH_ZEPHIR)+'/conf/'+rne+os.sep+str(id_serveur)+os.sep+'uucp'
490
491
492 cmd = """cp %s/call %s/dial %s/dialcode %s/passwd %s""" % (config.TEMPLATE_DIR,config.TEMPLATE_DIR,config.TEMPLATE_DIR,config.TEMPLATE_DIR,path_dest)
493 os.system(cmd)
494
495 for filepath in ["config","sys","port"]:
496
497 try:
498 fic_ori=open(config.TEMPLATE_DIR+os.sep+filepath,'r')
499 lines = fic_ori.readlines()
500 fic_ori.close()
501 except:
502 return 0,u('erreur de lecture du fichier %s ' % filepath)
503 conf=[]
504 for line in lines:
505
506
507 line = line.replace('%%serveur%%',str(rne)+'-'+str(id_serveur))
508 line = line.replace('%%password%%',passwd_uucp)
509
510 conf.append(line)
511
512 try:
513 fic_dest=open(path_dest+os.sep+filepath,'w')
514 fic_dest.writelines(conf)
515 fic_dest.close()
516 except:
517 return 0,u('erreur de création du fichier %s ' % path_dest+os.sep+filepath)
518 if cle_rsa1 != "":
519
520 return self._conf_ssh('',id_serveur,base64.decodestring(cle_rsa1))
521 else:
522 return 1, id_serveur
523
525 """permet de récupérer la configuration uucp d'un serveur via xmlrpc"""
526 if cle_rsa1 == "":
527 return 0, u("""clé rsa invalide""")
528 if self.parent.s_pool.has_key(id_serveur):
529
530 self.parent.s_pool.update_contact(id_serveur)
531 return self._conf_ssh('',id_serveur,base64.decodestring(cle_rsa1))
532 else:
533 return 0, u("""erreur, serveur non retrouvé""")
534
535 - def _conf_ssh(self,cred_user,id_serveur,cle_rsa1):
536 """mise en place de la clé pour l'authentification d'uucp sur ssh"""
537 try:
538 id_serveur = int(id_serveur)
539 serv = self.parent.s_pool.get(cred_user, id_serveur)
540 except KeyError:
541 return 0, u("""serveur inconnu""")
542 path_dest=serv.get_confdir()
543
544 ligne_rsa = 'command="sudo /usr/sbin/uucico2 -D -l" '+cle_rsa1
545
546 try:
547 fic_cle_publique = os.path.join(path_dest,'cle_publique')
548
549 if os.path.isfile(fic_cle_publique):
550
551 backup_cle = open(fic_cle_publique,"r")
552 old_cle = backup_cle.read().strip().split('\n')[0]
553 backup_cle.close()
554
555 self._remove_ssh_key(old_cle)
556
557 backup_cle = open(fic_cle_publique,"w")
558 backup_cle.write(ligne_rsa)
559 backup_cle.close()
560 serv.maj_params({'cle_ok':1})
561
562 self._authorize_ssh_key(ligne_rsa)
563 except:
564
565 self.xmlrpc_del_serveur(cred_user,id_serveur)
566 return 0,u("Erreur d'ajout de la cle rsa sur le serveur")
567 else:
568
569 files = []
570 for path_conf in ['config','sys','port']:
571
572 file_conf=open(path_dest+os.sep+'uucp'+os.sep+path_conf,"r")
573 lines_conf=file_conf.read()
574 file_conf.close()
575
576
577 if path_conf == 'config':
578 if lines_conf.count('lockdir') == 0:
579 lines_conf = lines_conf + "\nlockdir /tmp"
580
581 files.append(base64.encodestring(lines_conf))
582
583 if os.path.exists(path_dest+os.sep+'zephir.eol'):
584
585 file_conf=open(path_dest+os.sep+'zephir.eol',"r")
586 lines_conf = file_conf.read()
587 file_conf.close()
588 files.append(base64.encodestring(lines_conf))
589 else:
590
591 files.append("")
592 return 1,id_serveur,files[0],files[1],files[2],files[3]
593
595 """ajoute une cle ssh dans authorized_keys
596 """
597 if os.path.isfile("/var/spool/uucp/.ssh/authorized_keys"):
598 auth_keys = open("/var/spool/uucp/.ssh/authorized_keys","r")
599 lines=auth_keys.read().strip().split('\n')
600 auth_keys.close()
601 else:
602 lines = []
603
604 lines.append(cle)
605
606 auth_keys = open("/var/spool/uucp/.ssh/authorized_keys","w")
607 auth_keys.write("\n".join(lines))
608 auth_keys.close()
609
611 """supprime une cle ssh de authorized_keys
612 """
613 auth_keys = open("/var/spool/uucp/.ssh/authorized_keys","r")
614 lines=auth_keys.read().strip().split('\n')
615 auth_keys.close()
616 new_lines = []
617 for line in lines:
618 if line.startswith(cle.strip()):
619
620 pass
621 else:
622
623 new_lines.append(line)
624
625 auth_keys = open("/var/spool/uucp/.ssh/authorized_keys","w")
626 auth_keys.write("\n".join(new_lines))
627 auth_keys.close()
628
630 """supression d'un serveur de la base zephir"""
631 try:
632 id_serveur = int(id_serveur)
633 serv = self.parent.s_pool.get(cred_user, id_serveur)
634 except ValueError, KeyError:
635
636 return 0, u("""donnez un identifiant de serveur valide""")
637
638
639
640
641
642 id_uucp = serv.rne+'-'+str(id_serveur)
643
644 query = """select id,libelle,serveurs from groupes_serveurs"""
645 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
646 cursor=cx.cursor()
647 cursor.execute(query)
648 groupes=cursor.fetchall()
649
650 for groupe in groupes:
651 serv_gr = eval(groupe[2])
652 if id_serveur in serv_gr:
653
654 serv_gr.remove(id_serveur)
655
656 if serv_gr == []:
657
658 self.xmlrpc_del_group(cred_user,int(groupe[0]))
659 else:
660 self.xmlrpc_edit_group(cred_user,int(groupe[0]),groupe[1],serv_gr)
661
662
663 cursor.close()
664 cx.commit()
665 cx.close()
666
667 serveur_dir = serv.get_confdir()
668 self.parent.s_pool.del_serveur(cred_user, id_serveur)
669
670
671 cle_pub=""
672 if os.path.isfile(serveur_dir+os.sep+"cle_publique"):
673 fic_rsa=open(serveur_dir+os.sep+"cle_publique","r")
674 cle_pub = fic_rsa.read().strip().split('\n')[0]
675 fic_rsa.close()
676 try:
677 shutil.rmtree(serveur_dir)
678 except:
679 return 1, u("""erreur de supression du repertoire du serveur""")
680
681 if os.path.exists(os.path.abspath(config.PATH_ZEPHIR)+os.sep+"data"+os.sep+str(id_serveur)):
682 stat_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+"data"+os.sep+str(id_serveur)
683 else:
684 stat_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+"sites"+os.sep+str(id_serveur)
685 try:
686 shutil.rmtree(stat_dir)
687 except:
688
689 pass
690 if os.path.exists("/var/spool/uucppublic/site%s.tar" % id_serveur):
691 try:
692 os.unlink("/var/spool/uucppublic/site%s.tar" % id_serveur)
693 os.unlink("/var/spool/uucppublic/site%s.md5" % id_serveur)
694 except:
695 pass
696
697
698 if os.path.exists("/var/spool/uucp/"+id_uucp):
699 shutil.rmtree("/var/spool/uucp/"+id_uucp)
700
701 try:
702 os.unlink("/etc/uucp/serveurs/"+id_uucp+".sys")
703 except:
704 pass
705 fic_config=open("/etc/uucp/config_zephir","r")
706 config_uucp=fic_config.readlines()
707 fic_config.close()
708 try:
709 config_uucp.remove('sysfile /etc/uucp/serveurs/'+id_uucp+'.sys\n')
710 except ValueError:
711 return 1, u("""configuration uucp non retouvée""")
712 else:
713 try:
714 fic_config=open("/etc/uucp/config_zephir","w")
715 fic_config.writelines(config_uucp)
716 fic_config.close()
717 except:
718 return 1, u("""erreur d'écriture dans /etc/uucp/config_zephir""")
719 else:
720
721 fic_config=open("/etc/uucp/passwd_zephir","r")
722 config_uucp=fic_config.readlines()
723 fic_config.close()
724 for line in config_uucp:
725 if line.startswith(id_uucp+' '):
726 config_uucp.remove(line)
727 try:
728 fic_config=open("/etc/uucp/passwd_zephir","w")
729 fic_config.writelines(config_uucp)
730 fic_config.close()
731 except:
732 return 1, u("""erreur d'écriture dans /etc/uucp/passwd_zephir""")
733
734 if cle_pub != "":
735 try:
736 self._remove_ssh_key(cle_pub)
737 except:
738
739 return 1, u("""clé rsa du serveur non retrouvée""")
740 return 1, 'ok'
741
743 """Liste des serveurs d'un etablissement
744 """
745 if rne :
746 query="""select * from serveurs where rne ilike '%s'""" % rne
747 else :
748 query="""select * from serveurs"""
749
750 return self.dbpool.runQuery(query).addCallbacks(self._got_serveur,db_client_failed,callbackArgs=[cred_user])
751
753 """récupération d'un serveur particulier (ou tous)
754 """
755 if id_serveur:
756 query="""select * from serveurs where id = '%s'""" % id_serveur
757 else :
758 query="""select * from serveurs"""
759 return self.dbpool.runQuery(query).addCallbacks(self._got_serveur,db_client_failed,callbackArgs=[cred_user])
760
762 """récupération d'un groupe de serveurs à partir de critères
763 """
764
765 requete=["select * from serveurs where "]
766 for nom_champ in criteres.keys():
767 if criteres[nom_champ] != "":
768 requete.append("("+str(nom_champ))
769 if (nom_champ == 'last_contact') or (nom_champ == 'etat' and criteres[nom_champ] == "null"):
770 requete.append(" is null) and ")
771 elif (nom_champ == 'md5s' and criteres[nom_champ] == "null"):
772 requete.append(" is null) and ")
773 elif nom_champ in ['etat','module_actuel','module_initial','variante','timestamp','md5s']:
774 requete.append(" = %s) and " % criteres[nom_champ])
775 elif nom_champ == 'date_install':
776 requete.append(" %s) and " % str(criteres[nom_champ]))
777 elif nom_champ == 'maj':
778 if str(criteres[nom_champ]) == 'outdated':
779 requete.append(" > 0) and ")
780 elif str(criteres[nom_champ]) == 'uptodate':
781 requete.append(" = 0) and ")
782 else:
783 requete.append(" < 0 or %s is null) and " % str(nom_champ))
784 else:
785 requete.append(" ilike '%")
786 requete.append(str(criteres[nom_champ]).replace("'","\\\'"))
787 requete.append("%') and ")
788
789 requete = "".join(requete)
790 if criteres.keys() != []:
791 requete = requete[:requete.rindex('and')]
792 else:
793 requete = requete[:requete.rindex('where')]
794 requete += "order by RNE,module_actuel"
795 return self.dbpool.runQuery(requete).addCallbacks(self._got_serveur, db_client_failed,callbackArgs=[cred_user])
796
798 """renvoie un groupe à partir d'une liste d'id de serveurs
799 """
800 if liste_serveurs != []:
801
802 requete=["select * from serveurs where id="]
803 for serveur in liste_serveurs:
804 requete.append(str(serveur))
805 requete.append(" or id=")
806
807 requete = "".join(requete)
808 requete = requete[:requete.rindex('or')]
809 requete += "order by RNE,module_actuel"
810 return self.dbpool.runQuery(requete).addCallbacks(self._got_serveur, db_client_failed,callbackArgs=[cred_user])
811
812
813
814
816 """ajoute une liste de serveurs à un groupe enregistré
817 """
818 if liste_serveurs != [] and type(liste_serveurs) == list:
819 try:
820 self.parent.s_pool.extend_groupe(cred_user,int(id_groupe),liste_serveurs)
821 except KeyError, ValueError:
822 return 0, u("""groupe non trouvé dans la base""")
823 else:
824 return 1, "ok"
825 else:
826 return 1, u("liste de serveurs à insérer vide")
827
828
830 """modification d'un serveur
831 cette fonction prend en compte un dictionnaire qui indique les
832 champs à modifier et leur nouvelle valeur. l'application cliente
833 doit s'assurer que ces champs existent dans la base"""
834
835 modifs = {}
836 if dico_modifs.has_key('timeout'):
837 modifs['timeout'] = int(dico_modifs['timeout'])
838 if dico_modifs.has_key('variante'):
839 modifs['variante'] = int(dico_modifs['variante'])
840
841
842 liste_serv = []
843 for id_serveur in liste_serveurs:
844 try:
845 id_serveur = int(id_serveur)
846 serv = self.parent.s_pool.get(cred_user, id_serveur)
847 liste_serv.append(serv)
848 except KeyError, ValueError:
849 return 0, u("""id de serveur non valide : %s""" % str(id_serveur))
850
851 if modifs != {}:
852
853 erreurs = []
854 for serveur in liste_serv:
855 code = 1
856 if 'variante' in modifs.keys():
857
858 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
859 cursor=cx.cursor()
860 cursor.execute("""select module from variantes where id=%s""" % int(modifs['variante']))
861 var_mod=cursor.fetchone()
862 cursor.close()
863 cx.close()
864 libelle = serveur.get_libelle()
865 if serveur.id_mod in var_mod:
866 code,raison = self.parent.s_pool.edit_serveur(serveur.id_s, dico_modifs)
867 raison = "%s (%s) : erreur d'application de la variante" % (libelle,serveur.id_s)
868 else:
869 code = 0
870 raison = "%s (%s) : le module ne correspond pas à la variante" % (libelle,serveur.id_s)
871 if code == 0:
872 erreurs.append(raison)
873 else:
874
875 requete=["update serveurs set "]
876 for cle in modifs.keys():
877 requete.append(str(cle))
878 requete.append("=")
879 requete.append(str(modifs[cle]).replace("'","\\\'"))
880 requete.append(", ")
881 query="".join(requete)[:-2]
882 query += """ where id=%s""" % serveur.id_s
883
884 try:
885 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
886 cursor=cx.cursor()
887 cursor.execute(query)
888 cursor.close()
889 cx.commit()
890 cx.close()
891 except:
892 erreurs.append("%s (%s) : erreur de modification de la base" % (serveur.get_libelle(),serveur.id_s))
893
894 serveur.update_data()
895
896 if erreurs != []:
897 return 1, u(erreurs)
898 else:
899 return 1, u("OK")
900 else:
901 return 1,u("Pas de modifications à effectuer")
902
903
905 """modification d'un serveur
906 cette fonction prend en compte un dictionnaire qui indique les
907 champs à modifier et leur nouvelle valeur. l'application cliente
908 doit s'assurer que ces champs existent dans la base"""
909 try:
910 id_serveur = int(id_serveur)
911 serv = self.parent.s_pool.get(cred_user, id_serveur)
912 return self.parent.s_pool.edit_serveur(id_serveur, dico_modifs)
913 except KeyError, ValueError:
914 return 0, u("""id de serveur non valide : %s""" % str(id_serveur))
915
916 - def multi_call(proxy, results, err_not_allowed=False):
917 """renvoie le résultat d'une liste de deffered
918 @param err_not_allowed: on sort en erreur à la première erreur si True"""
919 result = []
920 for res in results:
921 code, res = res[1]
922 if code == 0:
923 if err_not_allowed:
924 return code, res
925 result.append(res)
926 return 1, u(result)
927
929 """fonction qui renvoie différentes informations sur les(s) serveur(s) :
930 - présence de dico.eol
931 - présence de config.eol
932 - présence de la clé rsa (uucp)
933 - état des différentes actions
934 """
935 if type(id_serveur) == list:
936 results = []
937 for id_serv in id_serveur:
938 code, res = self._get_status(cred_user,id_serv)
939 if code == 1:
940 results.append(u(res))
941 return 1, results
942 else:
943 return self._get_status(cred_user,id_serveur)
944
955
957 """renvoie la liste des serveurs en alerte"""
958 serveurs = self.parent.s_pool.get_alertes(cred_user)
959
960 res = []
961 for serv in serveurs:
962 res.append([serv.get_rne(), serv.get_etab(), serv.get_libelle(), serv.get_module(), serv.id_s, serv.get_status()])
963
964 return 1, u(res)
965
967 """ajoute des fichiers, patchs, dictionnaires à un serveur
968 """
969
970 try:
971 id_serveur = int(id_serveur)
972 serv = self.parent.s_pool.get(cred_user, id_serveur)
973 except KeyError, ValueError:
974 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
975
976 if serv.version == 'creole1' and encode == True:
977 for type_f, files in dico_files.items():
978 if type_f in ['dicos','patchs','persos','fichiers_zeph']:
979 encoded_files = []
980 for fichier in dico_files[type_f]:
981 content = unicode(base64.decodestring(fichier[1]),config.charset).encode('ISO-8859-1')
982 localpath = ""
983 if len(fichier) == 3:
984 localpath = fichier[2]
985 encoded_files.append([fichier[0], base64.encodestring(content),localpath])
986 dico_files[type_f] = encoded_files
987
988
989 dest_dir = serv.get_confdir()
990
991 if dico_files.has_key('dicos'):
992 for dico in dico_files['dicos']:
993 try:
994 if dico[0] != "":
995 if serv.version == 'creole1':
996 f=open(dest_dir+os.sep+'dicos/'+os.sep+os.path.basename(dico[0].replace("\\","/")),'w')
997 else:
998 f=open(dest_dir+os.sep+'dicos/local/'+os.sep+os.path.basename(dico[0].replace("\\","/")),'w')
999 f.write(base64.decodestring(dico[1]))
1000 f.close()
1001 except:
1002 return 0,u("erreur de sauvegarde de %s" % dico)
1003
1004 if dico_files.has_key('persos'):
1005 for template in dico_files['persos']:
1006 try:
1007 if template[0] != "":
1008 f=open(dest_dir+os.sep+'fichiers_perso'+os.sep+os.path.basename(template[0].replace("\\","/")),'w')
1009 f.write(base64.decodestring(template[1]))
1010 f.close()
1011 except:
1012 return 0,u("erreur de sauvegarde de %s" % template)
1013
1014 if dico_files.has_key('patchs'):
1015 for patch in dico_files['patchs']:
1016 try:
1017 if patch[0] != "":
1018 f=open(dest_dir+os.sep+'patchs'+os.sep+os.path.basename(patch[0].replace("\\","/")),'w')
1019 f.write(base64.decodestring(patch[1]))
1020 f.close()
1021 except:
1022 return 0,u("erreur de sauvegarde de %s" % patch)
1023
1024
1025 try:
1026 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir')
1027 old_content=f.read()
1028 f.close()
1029 fichiers=old_content.split('%%\n')[0]
1030 rpms=old_content.split('%%\n')[1]
1031 except:
1032 fichiers=FILE_SECTION
1033 rpms=RPM_SECTION
1034
1035 if dico_files.has_key('fichiers_zeph'):
1036 for fichier in dico_files['fichiers_zeph']:
1037 localpath = ""
1038 if len(fichier) == 3:
1039 localpath = fichier[2]
1040 nom_fic = fichier[0].replace("\\","/")
1041
1042 if fichier[0].endswith('/'):
1043 nom_fic = fichier[0][:-1]
1044 if fichier[0].endswith("\\"):
1045 nom_fic = fichier[0][:-2]
1046
1047 if nom_fic not in fichiers.split('\n') and localpath == "":
1048 fichiers = fichiers.strip() + '\n' + nom_fic +'\n'
1049
1050 try:
1051 if nom_fic != "":
1052 if localpath == "":
1053 f=open(os.path.join(dest_dir,'fichiers_zephir',os.path.basename(nom_fic)),'w')
1054 else:
1055 f=open(os.path.join(dest_dir,localpath,os.path.basename(nom_fic)),'w')
1056 f.write(base64.decodestring(fichier[1]))
1057 f.close()
1058 except:
1059 return 0,u("erreur de sauvegarde de %s" % fichier)
1060
1061
1062 if dico_files.has_key('rpms'):
1063 for rpm in dico_files['rpms']:
1064
1065 if rpm not in rpms.split('\n'):
1066 rpms = rpms.strip() + '\n' + rpm +'\n'
1067
1068 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1069 f.write(fichiers+"%%\n"+rpms)
1070 f.close()
1071
1072
1073 serv.check_md5conf()
1074
1075 return 1,u("ok")
1076
1078 """suppression de fichiers, patchs, dictionnaires d'un serveur
1079 """
1080 try:
1081 id_serveur = int(id_serveur)
1082 serv = self.parent.s_pool.get(cred_user, id_serveur)
1083 except KeyError, ValueError:
1084 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1085
1086 dest_dir = serv.get_confdir()
1087
1088 if dico_files.has_key('dicos'):
1089 for dico in dico_files['dicos']:
1090 try:
1091 if dico != "":
1092 if serv.version == 'creole1':
1093 os.unlink(dest_dir+os.sep+'dicos'+os.sep+dico)
1094 else:
1095 os.unlink(dest_dir+os.sep+'dicos/local'+os.sep+dico)
1096 except:
1097 return 0,u("erreur de suppression de %s" % dico)
1098
1099
1100 if dico_files.has_key('persos'):
1101 for template in dico_files['persos']:
1102 try:
1103 if template != "":
1104 os.unlink(dest_dir+os.sep+'fichiers_perso'+os.sep+template)
1105 except:
1106 return 0,u("erreur de supression de %s" % template)
1107
1108 self.parent.s_pool.del_file_perms(dest_dir,'fichiers_perso'+os.sep+template)
1109
1110
1111 if dico_files.has_key('patchs'):
1112 for patch in dico_files['patchs']:
1113 try:
1114 if patch != "":
1115 os.unlink(dest_dir+os.sep+'patchs'+os.sep+patch)
1116 except:
1117 return 0,u("erreur de suppression de %s" % patch)
1118
1119 if dico_files.has_key('fichiers_zeph') or dico_files.has_key('rpms'):
1120
1121 try:
1122 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir')
1123 old_content=f.read()
1124 f.close()
1125 fichiers=old_content.split('%%\n')[0]
1126 rpms=old_content.split('%%\n')[1]
1127 except:
1128 fichiers="""# section 1
1129 # liste des fichiers à sauvegarder pour la variante
1130 # (ne pas modifier sauf pour créer ou mettre à jour la variante)"""
1131 rpms="""# section 2
1132 # inscrire les noms des paquetages qui seront installés à la mise à jour du serveur
1133 # (ils doivent être présents sur le serveur de mise à jour)"""
1134
1135
1136 if dico_files.has_key('fichiers_zeph'):
1137 liste=fichiers.split('\n')
1138 for fichier in dico_files['fichiers_zeph']:
1139
1140 if fichier in liste:
1141 liste.remove(fichier)
1142 fic_path = os.path.join(dest_dir,'fichiers_zephir',os.path.basename(fichier.replace("\\","/")))
1143 else:
1144 fic_path = os.path.join(dest_dir,fichier)
1145
1146 try:
1147 if fichier != "":
1148 if os.path.isdir(fic_path):
1149 shutil.rmtree(fic_path)
1150 else:
1151 os.unlink(fic_path)
1152 except:
1153 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1154 f.write(fichiers+"%%\n"+rpms)
1155 f.close()
1156 return 0,u("erreur de suppression de %s" % fichier)
1157
1158 if fichier.startswith('/'):
1159 fic_sup = 'fichiers_zephir/'+os.path.basename(fichier.replace("\\","/"))
1160 else:
1161 fic_sup = fichier
1162 self.parent.s_pool.del_file_perms(dest_dir,fic_sup,True)
1163 fichiers = "\n".join(liste)
1164
1165
1166 if dico_files.has_key('rpms'):
1167 for rpm in dico_files['rpms']:
1168
1169 liste=rpms.split('\n')
1170 if rpm in liste:
1171 liste.remove(rpm)
1172 else:
1173 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1174 f.write(fichiers+"%%\n"+rpms)
1175 f.close()
1176 return 0,u("rpm non trouvé dans la liste : %s" % rpm)
1177
1178 rpms = "\n".join(liste)
1179
1180 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1181 f.write(fichiers+"%%\n"+rpms)
1182 f.close()
1183
1184
1185 serv.check_md5conf()
1186
1187 return 1,u("ok")
1188
1189 - def xmlrpc_get_file_content(self,cred_user,id_serveur,path):
1190 """renvoie le contenu d'un fichier de serveur
1191 si le fichier est un fichier binaire, renvoie la chaine BINARY"""
1192 try:
1193 id_serveur = int(id_serveur)
1194 serv = self.parent.s_pool.get(cred_user, id_serveur)
1195 except KeyError, ValueError:
1196 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1197
1198 try:
1199 dest_dir=serv.get_confdir()
1200 except:
1201 return 0,u("""lecture du fichier: paramètres non valides""")
1202
1203 try:
1204 if serv.version == "creole1":
1205 path = path.replace('dicos/local','dicos')
1206
1207 if os.path.isdir(dest_dir + os.sep + path):
1208 content = os.listdir(dest_dir + os.sep + path)
1209 return 1, u(content)
1210 else:
1211
1212 if istextfile(dest_dir + os.sep + path):
1213 f=file(dest_dir + os.sep + path)
1214 content=f.read()
1215 f.close()
1216
1217 if serv.version == "creole1":
1218 try:
1219 content = unicode(content,'ISO-8859-1').encode(config.charset)
1220 except:
1221
1222 print "echec d'encoding du fichier %s provenant d'un serveur eole1" % path
1223 content = base64.encodestring(content)
1224 else:
1225 content = "BINARY"
1226 return 1, content
1227 except:
1228 return 0,u("""erreur de lecture du fichier""")
1229
1231 """récupère la liste des variables communes à un groupe de serveur"""
1232
1233 liste_serv = []
1234 for id_serveur in serveurs:
1235 try:
1236 serv = self.parent.s_pool.get(cred_user, id_serveur)
1237 liste_serv.append(serv)
1238 except KeyError, ValueError:
1239 return 0, u("""serveur inconnu dans la base zephir : %s""" % str(id_serveur))
1240 liste_vars = {}
1241 liste_modules = []
1242 erreurs = []
1243 first_iter=1
1244 for serveur in liste_serv:
1245
1246 serveur_dir = serveur.get_confdir()
1247
1248 d = serveur.get_config('modif_config',encode=encode)
1249 if d == None:
1250
1251 erreurs.append("""le serveur %s (%s) n'a pas de fichier zephir.eol""" % (serveur.id_s,serveur.get_libelle()))
1252 else:
1253
1254 if first_iter == 1:
1255 for var in d.liste_vars.keys():
1256 liste_vars[var]=[d.get_value(var)]
1257 first_iter = 0
1258 else:
1259 for var in liste_vars.keys():
1260 if var not in d.liste_vars.keys():
1261
1262 del(liste_vars[var])
1263 else:
1264 val=d.get_value(var)
1265 if d.version == "creole2":
1266 val = ",".join(val)
1267 if val not in liste_vars[var]:
1268 liste_vars[var].append(val)
1269
1270 if serveur.id_mod not in liste_modules:
1271 liste_modules.append(serveur.id_mod)
1272
1273 return 1, u([liste_vars,liste_modules,erreurs])
1274
1276 """modifie une variable commune à un groupe de serveur"""
1277
1278 liste_serv = []
1279 for id_serveur in serveurs:
1280 try:
1281 serv = self.parent.s_pool.get(cred_user, id_serveur)
1282 liste_serv.append(serv)
1283 except KeyError, ValueError:
1284 return 0, u("""serveur inconnu dans la base zephir : %s""" % str(id_serveur))
1285 erreurs = []
1286 for serveur in liste_serv:
1287
1288 serveur_dir = serveur.get_confdir()
1289
1290 try:
1291 d = serveur.get_config('modif_config',encode)
1292 assert d is not None
1293 except Exception,e:
1294 erreurs.append('%s-%s (%s)' % (str(serv),serveur.get_libelle(),str(e)))
1295 else:
1296
1297 try:
1298 d.get_var(var)
1299 if d.version == "creole 2":
1300 val = val.split(",")
1301 d.set_value(val)
1302 except Exception,e:
1303 erreurs.append('%s-%s (%s)' % (str(serv),serveur.get_libelle(),str(e)))
1304 else:
1305
1306 res = serveur.save_config(d,'modif_config',encode)
1307 if res != "":
1308 erreurs.append(res)
1309 return 1, u(erreurs)
1310
1311 - def xmlrpc_get_dico(self,cred_user,id_serveur,mode='config',encode=False):
1312 """récupération du dictionnaire de configuration selon le mode demandé
1313 (gen_dico, gen_config, modification du fichier déjà rempli"""
1314 try:
1315 id_serveur = int(id_serveur)
1316 serv = self.parent.s_pool.get(cred_user, id_serveur)
1317 except KeyError, ValueError:
1318 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1319
1320 try:
1321 config_serv = serv.get_config(mode,encode)
1322 except Exception, e:
1323 return 0, u("""erreur de lecture du dictionnaire : %s""" % str(e))
1324
1325 data = config_serv.get_dict()
1326 return 1, data
1327
1329 """renvoie un dictionnaire contenant la configuration du serveur demandé
1330 format {variable:valeur}"""
1331 try:
1332 id_serveur = int(id_serveur)
1333 serv = self.parent.s_pool.get(cred_user, id_serveur)
1334 except KeyError, ValueError:
1335 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1336
1337 try:
1338 config_serv = serv.get_config('modif_config',encode)
1339 data = config_serv.parsedico()
1340 except Exception, e:
1341 return 0, u("""erreur de lecture du dictionnaire : %s""" % str(e))
1342
1343 return 1, u(data)
1344
1345 - def xmlrpc_save_conf(self,cred_user,id_serveur,dico_zeph,mode='config',encode=False):
1346 """sauvegarde d'un dictionnaire de configuration sur zephir
1347 (soit sur zephir.eol, soit sur dico.eol)"""
1348 try:
1349 id_serveur = int(id_serveur)
1350 serv = self.parent.s_pool.get(cred_user, id_serveur)
1351 except KeyError, ValueError:
1352 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1353 try:
1354
1355 d = serv.get_config('modif_config',encode)
1356 d.init_from_zephir(dico_zeph)
1357 serv.save_config(d,mode,encode)
1358 except Exception, e:
1359 return 0,u(str(e))
1360 else:
1361 return 1,u('ok')
1362
1364 """sauvegarde d'un modèle de firewall
1365 """
1366 try:
1367 id_serveur = int(id_serveur)
1368 serv = self.parent.s_pool.get(cred_user, id_serveur)
1369 except KeyError, ValueError:
1370 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1371 return self._save_bastion([serv],bastion_base64,'fichiers_zephir/modeles/%s.xml' % modele, encode)
1372
1374 """ récupère les informations sur les serveurs du groupe
1375 """
1376 query = """select serveurs from groupes_serveurs where id = %s""" % groupe
1377 return self.dbpool.runQuery(query).addCallbacks(self._save_bastion_groupe,db_client_failed,callbackArgs=[cred_user,bastion_base64,modele,encode])
1378
1380 """sauvegarde d'un modèle de firewall sur un groupe de serveurs
1381 """
1382 try:
1383 serveurs=eval(data[0][0])
1384 except:
1385 return 0, u("impossible de retrouver les serveurs du groupe")
1386
1387 liste_serv = []
1388 for id_serveur in serveurs:
1389 try:
1390 serv = self.parent.s_pool.get(cred_user, int(id_serveur))
1391 except KeyError, ValueError:
1392 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1393 if serv.get_module().startswith('amon-'):
1394 liste_serv.append(serv)
1395 return self._save_bastion(liste_serv, bastion_base64, 'fichiers_zephir/modeles/%s.xml' % modele, encode)
1396
1397 - def _save_bastion(self,serveurs,fichier_base64,filename,encode):
1398 """sauvegarde d'un fichier dans l'arborescence d'un serveur"""
1399
1400 contenu = base64.decodestring(fichier_base64)
1401
1402 erreurs = []
1403 for serveur in serveurs:
1404
1405 serveur_dir = serveur.get_confdir()
1406
1407 try:
1408 d = serveur.get_config('modif_config',encode)
1409 try:
1410 if not os.path.isdir(serveur_dir+'/fichiers_zephir/modeles'):
1411 os.mkdir(serveur_dir+'/fichiers_zephir/modeles')
1412
1413
1414 modele=open(serveur_dir+'/fichiers_zephir/modeles'+os.sep+os.path.basename(filename),'w')
1415 modele.write(contenu)
1416 modele.close()
1417 except:
1418
1419 pass
1420 else:
1421
1422 d.get_var('type_amon')
1423 d.set_value(os.path.splitext(os.path.basename(filename))[0])
1424
1425 serveur.save_config(d,'modif_config',encode)
1426 except:
1427
1428 erreurs.append(str(serveur.id_s))
1429
1430
1431 try:
1432 f=open(serveur_dir+os.sep+'fichiers_zephir/fichiers_zephir')
1433 old_content=f.read()
1434 f.close()
1435 fichiers=old_content.split('%%\n')[0]
1436 rpms=old_content.split('%%\n')[1]
1437 except:
1438 fichiers=FILE_SECTION
1439 rpms=RPM_SECTION
1440
1441
1442 ligne = "/usr/share/eole/bastion/modeles"
1443 if ligne not in fichiers.split('\n'):
1444 fichiers = fichiers.strip() + '\n' + ligne +'\n'
1445 try:
1446 f=open(serveur_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1447 f.write(fichiers+"%%\n"+rpms)
1448 f.close()
1449 except:
1450 erreur.append("ajout à la liste des fichiers zephir")
1451 if erreurs != []:
1452 return 0,u("""erreur de sauvegarde du fichier %s sur le(s) serveur(s) %s""" % (filename,",".join(erreurs)))
1453
1454 return 1,u('ok')
1455
1457 """récupération d'un modèle de firewall
1458 """
1459 try:
1460 id_serveur = int(id_serveur)
1461 serv = self.parent.s_pool.get(cred_user,id_serveur)
1462 except KeyError, ValueError:
1463 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1464
1465 try:
1466 d = serv.get_config('modif_config',encode)
1467 modele=d.get_value('type_amon')
1468 if type(modele) == list:
1469 modele=modele[0]
1470 data_dir = os.path.join(serv.get_confdir(),'fichiers_zephir')
1471 model_files = [ os.path.join(data_dir, 'modeles/%s.xml' % modele),
1472 os.path.join(data_dir, '%s.xml' % modele),
1473 os.path.join(data_dir, 'variante/%s.xml' % modele)
1474 ]
1475 contenu = None
1476 for model_file in model_files:
1477 if os.path.isfile(model_file):
1478 fic_zephir = open(model_file)
1479 contenu = fic_zephir.read()
1480 fic_zephir.close()
1481 assert contenu is not None
1482 except:
1483 return 0,u("""fichier de modele non trouvé pour le serveur %s""" % serv.id_s)
1484 else:
1485 return 1,base64.encodestring(contenu),modele
1486
1487 - def xmlrpc_get_log(self,cred_user,id_serveur=None,mode='zlog',liste_types=[]):
1488 """rècupère les logs d'un serveur particulier
1489 mode : - zlog : tous les logs remontés par le serveur (ou spécifiés)
1490 - autre : récupère la liste des actions zephir effectuées sur ce serveur
1491 """
1492 comp_id = ""
1493 if id_serveur:
1494 comp_id = """id_serveur=%s and""" % id_serveur
1495
1496 if mode == 'zlog':
1497
1498 comp = ["<> 'COMMAND'"]
1499
1500 if liste_types != []:
1501 comp=[" in ('"]
1502 for typelog in liste_types:
1503 comp.append(typelog)
1504 comp.append("','")
1505 comp = comp[:-1]
1506 comp.append("')")
1507 else:
1508 comp = ["= 'COMMAND'"]
1509
1510 query="""select id,id_serveur,date,type,message,etat from log_serveur where %s type%s order by date desc, id desc""" % (comp_id, "".join(comp))
1511 return self.dbpool.runQuery(query).addCallbacks(self._got_log,db_client_failed,callbackArgs=[cred_user])
1512
1514 """supression des logs d'un certain type antérieurs à une certaine date
1515 Attention, cette purge est effectuée sur l'ensemble des serveurs du zephir !
1516 liste_serveurs : liste des serveurs dont on veut purger les logs
1517 liste_types : spécifie les types d'action à purger (ex : ['COMMAND','SURVEILLANCE','MAJ']
1518 """
1519
1520 if liste_types != []:
1521
1522 if 'TOUT' in liste_types:
1523 cond_types = ""
1524 else:
1525
1526 cond_liste = []
1527 for type_log in liste_types:
1528 cond_liste.append("type='%s'" % type_log)
1529 cond_types = "and (" + " or ".join(cond_liste) + ")"
1530 else:
1531 return 0,u("paramètres invalides")
1532
1533 date = str(self.dbpool.dbapi.Timestamp(int(date[2]),int(date[1]),int(date[0]),0,0,0).adapted)
1534 for serveur in liste_serveurs:
1535
1536
1537 try:
1538 self.parent.s_pool.get(cred_user, int(serveur))
1539 except KeyError, ValueError:
1540 return 0, u("""serveur inconnu : %s""" % str(serveur))
1541 if int(serveur) > 0 and type(date) == str and type(liste_types) == list:
1542 query = """delete from log_serveur where id_serveur=%s %s and date <= '%s'""" % (serveur,cond_types,date)
1543 try:
1544
1545 self.dbpool.runOperation(query)
1546 except:
1547 pass
1548 else:
1549 return 0,u("paramètres invalides")
1550
1551 return 1,u("ok")
1552
1553
1555 """retourne la liste des fichiers personnalisés pour ce serveur
1556 """
1557 try:
1558 id_serveur = int(id_serveur)
1559 serv = self.parent.s_pool.get(cred_user,id_serveur)
1560 except KeyError, ValueError:
1561 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1562 else:
1563
1564 serveur_dir = serv.get_confdir()
1565
1566 dico_res={}
1567 try:
1568
1569 liste_dicos = []
1570 liste_dicos_var = []
1571 if serv.version == 'creole1':
1572 dico_dir = serveur_dir+os.sep+'dicos'
1573 else:
1574 dico_dir = serveur_dir+os.sep+'dicos/local'
1575 for fic in os.listdir(dico_dir):
1576 if fic == 'variante':
1577 pass
1578 elif fic.endswith('.eol') or fic.endswith('.xml'):
1579 liste_dicos.append(fic)
1580 dico_res['dicos'] = liste_dicos
1581 try:
1582
1583 for fic in os.listdir(serveur_dir+os.sep+'dicos/variante'):
1584 if fic.endswith('.eol') or fic.endswith('.xml'):
1585 liste_dicos_var.append(fic)
1586 dico_res['dicos_var'] = liste_dicos_var
1587 except OSError:
1588 dico_res['dicos_var'] = ['répertoire non trouvé !']
1589 except OSError:
1590 dico_res['dicos'] = ['répertoire non trouvé !']
1591 try:
1592
1593 dico_res['persos'] = os.listdir(serveur_dir+os.sep+'fichiers_perso')
1594 try:
1595 dico_res['persos'].remove('variante')
1596 except:
1597 pass
1598 except OSError:
1599 dico_res['persos'] = ['répertoire non trouvé !']
1600 try:
1601
1602 dico_res['persos_var'] = (os.listdir(serveur_dir+os.sep+'fichiers_perso/variante'))
1603 except OSError:
1604 dico_res['persos_var'] = ['répertoire non trouvé !']
1605 try:
1606
1607 dico_res['patchs'] = os.listdir(serveur_dir+os.sep+'patchs')
1608 try:
1609 dico_res['patchs'].remove('variante')
1610 except:
1611 pass
1612 except OSError:
1613 dico_res['patchs'] = ['répertoire non trouvé !']
1614 try:
1615
1616 dico_res['patchs_var'] = os.listdir(serveur_dir+os.sep+'patchs/variante')
1617 except OSError:
1618 dico_res['patchs_var'] = ['répertoire non trouvé !']
1619 try:
1620
1621
1622 fic = open(serveur_dir+'/fichiers_zephir/fichiers_zephir')
1623 data = fic.read().strip().split("\n")
1624 fic.close()
1625
1626 liste_pkg = []
1627 section_rpm = 0
1628 for ligne in data:
1629 ligne = ligne.strip()
1630 if section_rpm == 1:
1631
1632 if not ligne.startswith('#') and ligne != '':
1633
1634 liste_pkg.append(ligne)
1635 if ligne == '%%':
1636 section_rpm = 1
1637 dico_res['rpms'] = liste_pkg
1638 except IOError:
1639 dico_res['rpms'] = []
1640 try:
1641
1642
1643 fic = open(serveur_dir+'/fichiers_zephir/variante/fichiers_variante')
1644 data = fic.read().strip().split("\n")
1645 fic.close()
1646
1647 liste_pkg_var = []
1648 section_rpm = 0
1649 for ligne in data:
1650 ligne = ligne.strip()
1651 if section_rpm == 1:
1652
1653 if not ligne.startswith('#') and ligne != '':
1654
1655 liste_pkg_var.append(ligne)
1656 if ligne == '%%':
1657 section_rpm = 1
1658 dico_res['rpms_var'] = liste_pkg_var
1659 except IOError:
1660 dico_res['rpms_var'] = []
1661
1662 liste_fic=[]
1663
1664 try:
1665 f=open(serveur_dir+os.sep+'fichiers_zephir/fichiers_zephir')
1666 old_content=f.read()
1667 f.close()
1668 fichiers=old_content.split('%%\n')[0]
1669 except:
1670 fichiers=""
1671 for f in fichiers.split('\n'):
1672 if f.strip().startswith("""/"""):
1673 liste_fic.append(f)
1674 dico_res['fichiers_zeph'] = liste_fic
1675 liste_fic=[]
1676 try:
1677 f=open(serveur_dir+os.sep+'fichiers_zephir/variante/fichiers_variante')
1678 old_content=f.read()
1679 f.close()
1680 fichiers=old_content.split('%%\n')[0]
1681 except:
1682 fichiers=""
1683 for f in fichiers.split('\n'):
1684 if f.strip().startswith("/"):
1685 liste_fic.append(f)
1686 dico_res['fichiers_var'] = liste_fic
1687
1688 return 1,u(dico_res)
1689
1691 """renvoie les informations de permissions associées à un fichier
1692 """
1693 try:
1694 id_serveur = int(id_serveur)
1695 serv = self.parent.s_pool.get(cred_user,id_serveur)
1696 except KeyError, ValueError:
1697 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1698 else:
1699 result = self.parent.s_pool.get_file_perms(serv.get_confdir(), filepath)
1700 return 1, u(result)
1701
1703 """renvoie les informations de permissions associées à un fichier
1704 """
1705 try:
1706 id_serveur = int(id_serveur)
1707 serv = self.parent.s_pool.get(cred_user,id_serveur)
1708 except KeyError, ValueError:
1709 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1710 else:
1711 result = self.parent.s_pool.del_file_perms(serv.get_confdir(), filepath)
1712 return 1, u(result)
1713
1715 """enregistre les informations de permissions associées à un(des) fichier(s)
1716 @param rights: dictionnaire au format suviant : {'filepath':[mode,ownership]}
1717 """
1718 try:
1719 id_serveur = int(id_serveur)
1720 serv = self.parent.s_pool.get(cred_user,id_serveur)
1721 except KeyError, ValueError:
1722 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1723 else:
1724 data_dir = serv.get_confdir()
1725 res = self.parent.s_pool.set_file_perms(rights, data_dir)
1726 if res:
1727 return 1,"OK"
1728 else:
1729 return 0, u("""erreur d'enregistrement des permissions""")
1730
1732 """copie les permissions définies sur le serveur id_src
1733 sur le groupe de serveurs serveurs
1734 @param keep: si True, on n'écrase pas les permissions restantes pour un fichier
1735 """
1736 try:
1737 id_src = int(id_src)
1738 src = self.parent.s_pool.get(cred_user,id_src)
1739
1740 perms = self.parent.s_pool.get_file_perms(src.get_confdir())
1741 except KeyError, ValueError:
1742 return 0, u("""serveur inconnu : %s""" % str(id_src))
1743 else:
1744 forbidden = []
1745
1746 for id_dst in serveurs:
1747 try:
1748 id_dst = int(id_dst)
1749 dst = self.parent.s_pool.get(cred_user, id_dst)
1750 except:
1751 forbidden.append(id_dst)
1752 else:
1753 if id_dst != id_src:
1754
1755 existing = []
1756 if keep == True:
1757 existing = self.parent.s_pool.get_file_perms(dst.get_confdir()).keys()
1758
1759 updates = {}
1760 for ficperm, data in perms.items():
1761 if ficperm not in existing:
1762 updates[ficperm] = perms[ficperm]
1763
1764 self.parent.s_pool.set_file_perms(updates, dst.get_confdir())
1765
1766 return 1, u(forbidden)
1767
1769 """récupère l'etat général d'un ou plusieurs serveur(s)
1770 """
1771 if type(id_serveur) == list:
1772 results = []
1773 for id_serv in id_serveur:
1774 code, res = self._global_status(cred_user,id_serv)
1775 if code == 0:
1776 return code, res
1777 else:
1778 results.append(res)
1779 return 1, u(results)
1780 else:
1781 return self._global_status(cred_user,id_serveur)
1782
1784 """lit l'état d'un serveur dans la base
1785 """
1786 try:
1787 id_serveur = int(id_serveur)
1788 serv = self.parent.s_pool.get(cred_user,id_serveur)
1789 except KeyError, ValueError:
1790 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1791 etat = serv.get_status()
1792 if etat == None:
1793 return 1, -1
1794 if etat in [0,2]:
1795 return 1, 0
1796 else:
1797 return 1, etat
1798 return 0, u("""erreur de récupération des données""")
1799
1801 """renvoie les données de la dernière mesure des agents
1802 """
1803 if serveurs == None:
1804 serveurs = self.agent_manager.keys()
1805 elif type(serveurs) != list:
1806 serveurs = [serveurs]
1807 measures = []
1808 for id_serveur in serveurs:
1809 try:
1810 serv = self.parent.s_pool.get(cred_user,int(id_serveur))
1811 except KeyError, ValueError:
1812
1813 pass
1814 if self.agent_manager[str(id_serveur)] != None:
1815 measures.append("%s:%s" % (str(id_serveur), str(self.agent_manager[str(id_serveur)].get_measure())))
1816
1817
1818 measures = "{" + ",".join(measures) + "}"
1819
1820 return 1, u(measures)
1821
1823 """récupère l'etat des agents d'un serveur
1824 """
1825 if type(id_serveur) == list:
1826 results = []
1827 for id_serv in id_serveur:
1828 code, res = self._agents_status(cred_user,id_serv)
1829 if code == 1:
1830 results.append(u(res))
1831 return 1, results
1832 else:
1833 return self._agents_status(cred_user,id_serveur)
1834
1855
1856
1857
1858
1859
1861 """enregistre un groupe de serveurs dans la base
1862 """
1863 if self.parent.s_pool.add_groupe(cred_user, libelle, serveurs):
1864 return 1, "ok"
1865 else:
1866 return 0, u("erreur lors de l'insertion du groupe")
1867
1869 """supprime un groupe de serveurs de la base
1870 """
1871 try:
1872 id_groupe = int(id_groupe)
1873 self.parent.s_pool.del_groupe(cred_user, id_groupe)
1874 except KeyError, ValueError:
1875 return 0, u("""id de groupe invalide : %s""" % str(id_groupe))
1876 return 1, "ok"
1877
1879 """modifie un groupe existant
1880 """
1881 try:
1882 id_groupe = int(id_groupe)
1883 self.parent.s_pool.edit_groupe(cred_user, id_groupe, libelle, serveurs)
1884 except KeyError, ValueError:
1885 return 0, u("""id de groupe invalide : %s""" % str(id_groupe))
1886 return 1, "ok"
1887
1889 """récupère un ou plusieur groupe de serveurs dans la base
1890 """
1891 try:
1892 liste_gr = self.parent.s_pool.get_groupes(cred_user, id_groupe)
1893 except KeyError, ValueError:
1894 return 0, u("""id de groupe invalide : %s""" % str(id_groupe))
1895 return 1, u(liste_gr)
1896
1898 """autorise la connexion ssh par clé pour un utilisateur
1899 """
1900 for serveur in serveurs:
1901 query="""insert into serveur_auth values (%s,'%s')""" % (serveur,username)
1902 self.dbpool.runOperation(query).addErrback(db_client_failed)
1903
1904 return 1, u('ok')
1905
1907 """enlève la connexion ssh par clé pour un utilisateur
1908 """
1909 liste=[str(i) for i in serveurs]
1910 end_query = " or id_serveur=".join(liste)
1911 query="""delete from serveur_auth where login = '%s' and (id_serveur=%s)""" % (username, end_query)
1912
1913 return self.dbpool.runOperation(query).addCallbacks(lambda x : [1,'ok'], db_client_failed)
1914
1916 """liste des tags de procédures interdites pour un serveur
1917 """
1918 if serveur is None:
1919 query = """select tag,libelle from procedures"""
1920 else:
1921 query = """select lock_serveur.tag,libelle from lock_serveur,procedures where lock_serveur.tag=procedures.tag and id_serveur=%s""" % serveur
1922 return self.dbpool.runQuery(query).addCallbacks(self._get_locks, db_client_failed)
1923
1925 """formatte la sortie pour la recherche des fonctions lockées"""
1926 locks=[]
1927 for tag in data:
1928 locks.append([tag[0],tag[1]])
1929 return 1, u(locks)
1930
1932 """interdit un type de procédure sur un ensemble de serveurs
1933 tags : liste des tags à interdire
1934 """
1935 if type(serveurs) != list:
1936
1937 serveurs=[serveurs]
1938 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
1939 cursor=cx.cursor()
1940 erreur= ""
1941 query_tags = []
1942 for tag in tags:
1943 query_tags.append({'tag':tag})
1944 for serveur in serveurs:
1945 try:
1946 id_serveur = int(serveur)
1947 serv = self.parent.s_pool.get(cred_user,id_serveur)
1948 except KeyError, ValueError:
1949 erreur = """serveur %s non retrouvé""" % str(serveur)
1950 try:
1951
1952 if len(notags) > 0:
1953 cursor.execute("delete from lock_serveur where id_serveur=%s and tag in ('%s')" % (serveur, "','".join(notags)))
1954
1955 query = "insert into lock_serveur (id_serveur,tag) values (" + str(serveur) + ", %(tag)s)"
1956 cursor.executemany(query, query_tags)
1957 except Exception,e:
1958 erreur = """erreur de mise à jour des locks : serveur %s""" % (str(serveur))
1959
1960 if erreur != "":
1961 cx.rollback()
1962 cx.close()
1963 return 0, u(erreur)
1964
1965 cursor.close()
1966 cx.commit()
1967 return 1, 'OK'
1968
1970 """récupère le délai de connexion des serveurs (en secondes)
1971 """
1972 try:
1973 id_serveur = int(id_serveur)
1974 serv = self.parent.s_pool.get(cred_user,id_serveur)
1975 except KeyError, ValueError:
1976 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1977 try:
1978 timeout = serv.get_timeout()
1979 except:
1980 return 0, "erreur de récupération du timeout"
1981 return 1, timeout
1982