1
2
3
4
5
6
7
8
9
10
11
12
13 """module de gestion des serveurs
14 """
15 from zephir.backend.db_utils import *
16 from zephir.backend import config
17 from zephir.backend.config import log
18 from zephir.backend.uucp_utils import UUCPError, uucp_pool
19 from zephir.backend.config import u, FILE_SECTION, RPM_SECTION
20 from zephir.backend.xmlrpceole import XMLRPCEole as XMLRPC
21 from zephir.monitor.collecteur import ServeurStatus
22 from zephir.backend.lib_backend import ResourceAuthError, istextfile
23
24 import psycopg2 as PgSQL
25
26 import sys,os,shutil,time,dico,base64, traceback
27
29 """serveur XMLRPC zephir pour la gestion des serveurs
30 """
31
32 - def __init__(self,parent,agent_manager):
33 self.dbpool = db_connect()
34 self.dbpool.noisy = 0
35 XMLRPC.__init__(self)
36 self.agent_manager = agent_manager
37 self.parent = parent
38
40 """Formatage de la liste des serveurs
41 """
42 l=[]
43 auth_error = False
44 for serveur in serveurs:
45
46 try:
47 serv = self.parent.s_pool.get(cred_user,int(serveur[0]))
48 except ResourceAuthError:
49 auth_error = True
50 continue
51 l.append(self._format_serv(serveur, serv))
52 if l == [] and auth_error == True:
53
54 raise ResourceAuthError("""Vous n'avez accès à aucun serveur dans ce groupe""")
55 return 1,u(l)
56
104
106 """Formattage de la liste des logs
107 """
108
109 servs = {}
110 for ligne in lignes:
111 id_serveur = ligne[1]
112 try:
113 if id_serveur not in servs.keys():
114 self.parent.s_pool.get(cred_user,int(id_serveur))
115 except:
116 servs[id_serveur] = False
117 else:
118 servs[id_serveur] = True
119
120 l=[]
121 for ligne in lignes:
122 if servs[ligne[1]] == True:
123 l.append(
124 {'id':ligne[0]
125 ,'id_serveur':ligne[1]
126 ,'date':str(ligne[2])
127 ,'action':ligne[3]
128 ,'message':ligne[4]
129 ,'etat':ligne[5]})
130 return 1,u(l)
131
132
133
134
135
136
137 - def xmlrpc_regen_key(self,cred_user,serveurs, regen_certs=False, new_addr=None):
138 """prépare une nouvelle clé ssh pour la communication client/zephir
139 - génère la clé
140 - prépare une action de mise en place de la clé sur le client
141 """
142 if type(serveurs) != list:
143 serveurs = [serveurs]
144 erreurs = []
145 for id_serveur in serveurs:
146 try:
147 id_serveur = int(id_serveur)
148 serv = self.parent.s_pool.get(cred_user, id_serveur)
149 except:
150 erreurs.append("Serveur %s : inexistant ou accès refusé" % str(id_serveur))
151 if not os.path.isfile(os.path.join(serv.get_confdir(), 'cle_publique')):
152 erreurs.append("%s (%s): Le serveur n'est pas encore enregistré" % (serv.id_s, serv.rne))
153 else:
154 res = serv.regen_key(new_addr)
155 if res != 0:
156 erreurs.append("%s (%s): Erreur lors de la génération de la clé" % (serv.id_s, serv.rne))
157 else:
158
159 code, data = self.parent.getSubHandler('uucp')._send_files(serv,'pubkey',['new_key.pub'],uucp=1)
160 if code == 0:
161 erreurs.append("%s (%s): Echec d'envoi de la clé publique (%s)" % (serv.id_s, serv.rne, data))
162 else:
163 id_uucp = str(serv.get_rne())+'-'+str(serv.id_s)
164 if new_addr is None:
165
166
167
168 try:
169 if regen_certs:
170 res = uucp_pool.add_cmd(id_uucp,"zephir_client update_key regen_certs")
171 else:
172 res = uucp_pool.add_cmd(id_uucp,"zephir_client update_key")
173 except UUCPError,e:
174 erreurs.append("serveur %s (%s) : Erreur UUCP %s" % (serv.id_s, serv.rne, str(e)))
175 else:
176 try:
177 res = uucp_pool.add_cmd(id_uucp,"zephir_client change_ip")
178 except UUCPError,e:
179 erreurs.append("serveur %s (%s) : Erreur UUCP %s" % (serv.id_s, serv.rne, str(e)))
180 return 1, u(erreurs)
181
182 - def xmlrpc_get_key(self,cred_user,id_serveur,old_key,new_key,confirm_ip=False):
183 """retourne à un serveur une nouvelle clé ssh générée (appelé depuis le client)
184 la clé est renvoyée seulement si les clés publiques correspondent
185 confirm_ip : utilisé dans le cas d'un changement d'adresse de zephir pour confirmer
186 que l'adresse est bien prise en compte par le client
187 """
188 id_serveur = int(id_serveur)
189 serv = self.parent.s_pool.get(cred_user, id_serveur)
190
191 code, res = serv.get_key(old_key,new_key, confirm_ip)
192 return code, u(res)
193
195 """valide la mise en place d'une nouvelle clé et invalide l'ancienne
196 """
197 id_serveur = int(id_serveur)
198 serv = self.parent.s_pool.get(cred_user, id_serveur)
199 """met en place la nouvelle clé d'enregistrement côté zephir
200 Les clés publiques et privées doivent avoir été récupérées par le serveur"""
201 actual_key_path = os.path.join(serv.get_confdir(), 'cle_publique')
202 new_key_path = os.path.join(serv.get_confdir(), 'new_key.pub')
203 new_key_priv_path = os.path.join(serv.get_confdir(), 'new_key')
204 new_addr_path = os.path.join(serv.get_confdir(), 'new_addr_ok')
205 if not os.path.isfile(new_key_path) or os.path.isfile(new_key_priv_path):
206 return 0, """Nouvelles clés non récupérées par le serveur"""
207 cle_rsa = file(new_key_path).read().strip()
208
209 os.unlink(new_key_path)
210 if os.path.isfile(new_addr_path):
211 os.unlink(new_addr_path)
212 return self._conf_ssh('',serv.id_s,cle_rsa)
213
215 """annule la prise en compte d'une nouvelle adresse ip pour une liste de serveurs
216 """
217 if type(serveurs) != list:
218 serveurs = [serveurs]
219 erreurs = []
220 for id_serveur in serveurs:
221 try:
222 id_serveur = int(id_serveur)
223 serv = self.parent.s_pool.get(cred_user, id_serveur)
224 except:
225 erreurs.append("Serveur %s : inexistant ou accès refusé" % str(id_serveur))
226 continue
227 try:
228 params = serv.get_params()
229 if params.has_key('new_key') and params['new_key'][0] in (2,3):
230 id_uucp = str(serv.get_rne()) + '-' + str(serv.id_s)
231 uucp_pool.add_cmd(id_uucp,"zephir_client purge_ip")
232 except UUCPError,e:
233 erreurs.append("serveur %s (%s) : Erreur UUCP %s" % (serv.id_s, serv.rne, str(e)))
234 continue
235 for fic in ('new_key','new_key.pub','new_addr','new_addr_ok'):
236 serv_fic = os.path.join(serv.get_confdir(), fic)
237 if os.path.isfile(serv_fic):
238 os.unlink(serv_fic)
239 return 1, erreurs
240
242 """permet de vérifier si des serveurs ont été modifiés
243 """
244 return 1, u(self.parent.s_pool.check_serveurs(cred_user, serveurs, last_check))
245
247 """permet de vérifier si des serveurs ont été modifiés
248 """
249 return 1, u(self.parent.s_pool.check_groupes(cred_user, groupes, last_check))
250
252 """modifie un serveur Eole1 en serveur NG"""
253 try:
254 id_serveur = int(id_serveur)
255 serv = self.parent.s_pool.get(cred_user, id_serveur)
256 except KeyError:
257 return 0, u("""serveur inconnu""")
258 if variante_dest == None:
259
260 try:
261 variante_dest = serv.variante_migration()
262 assert int(variante_dest) > 0
263 except:
264 variante_dest = None
265 if variante_dest == None:
266 query = "select modules.id, modules.libelle, modules.version, variantes.id from modules,variantes \
267 where modules.id=%s and modules.id=variantes.module and variantes.libelle='standard'"
268 return self.dbpool.runQuery(query, (int(module_dest),)).addCallbacks(self._migrate_serveur2,db_client_failed,callbackArgs=[cred_user, serv, hw_infos, variante_dest, module_dest])
269 else:
270 query = "select modules.id, modules.libelle, modules.version, variantes.id from modules, variantes \
271 where modules.id=%s and modules.id=variantes.module and variantes.id=%s"
272 return self.dbpool.runQuery(query, (int(module_dest), int(variante_dest))).addCallbacks(self._migrate_serveur2,db_client_failed,callbackArgs=[cred_user, serv, hw_infos, variante_dest, module_dest])
273
274 - def _migrate_serveur2(self, data, cred_user, serv, hw_infos, variante_dest, module_dest):
275
276 try:
277 lib_new = data[0][1]
278 id_new_mod = int(data[0][0])
279 version_new = int(data[0][2])
280 id_variante = int(data[0][3])
281 lib_act = serv.module
282 version_act = serv.module_version
283 assert lib_new[:lib_new.rindex('-')] == lib_act[:lib_act.rindex('-')]
284 assert lib_new != lib_act and version_new > 1
285 if (version_act > 1) and (version_new != version_act + 1):
286
287 assert version_new in config.allowed_upgrades[lib_act[:lib_act.rindex('-')]][version_act]
288 except:
289 return 0,u("""la migration vers le module demandé n'est pas gérée""")
290 if serv.version != "creole1":
291
292 migrate = False
293 if variante_dest == None:
294
295 query = "select id_dest, module from migration_variantes, variantes where id_source=%s and id_dest = id and module = %s"
296 return self.dbpool.runQuery(query, (int(serv.id_var), int(module_dest))).addCallbacks(self._migrate_variante, db_client_failed, callbackArgs=[serv,id_new_mod,id_variante,hw_infos,cred_user,migrate])
297 else:
298
299 migrate = True
300 query = "select module_actuel, variante, materiel, processeur, disque_dur, date_install, installateur, tel, remarques, timeout from serveurs where id=%s" % (serv.id_s)
301 return self.dbpool.runQuery(query, (int(serv.id_s),)).addCallbacks(self._backup_serveur_data, db_client_failed,callbackArgs=[serv,id_new_mod,id_variante, hw_infos, cred_user, migrate])
302
303 - def _migrate_variante(self, data, serv,id_new_mod,id_variante, hw_infos, cred_user, migrate):
304 """récupère la variante à migrer automatiquement si disponible"""
305 if len(data) > 0:
306 id_var_mod = data[0][1]
307 if id_var_mod == id_new_mod:
308
309 id_variante = data[0][0]
310 query = "select module_actuel, variante, materiel, processeur, disque_dur, date_install, installateur, tel, remarques, timeout from serveurs where id=%s"
311 return self.dbpool.runQuery(query, (int(serv.id_s),)).addCallbacks(self._backup_serveur_data, db_client_failed,callbackArgs=[serv,id_new_mod,id_variante, hw_infos, cred_user, migrate])
312
313 - def _backup_serveur_data(self, data, serv, id_new_mod, id_variante, hw_infos, cred_user, migrate = True):
314 path_ori = serv.get_confdir()
315 if migrate == True:
316 path_bak = path_ori + "-backup"
317 else:
318 path_bak = path_ori + "-downgrade"
319
320 if os.path.exists(path_bak):
321 if migrate:
322
323 return 0, u("""répertoire de backup déjà présent: %s""" % path_bak)
324 else:
325
326 shutil.rmtree(path_bak)
327
328 sql_data = "::".join([str(val) for val in data[0]])
329 f_var_ori = file(os.path.join(path_ori,"sql_data.ori"),'w')
330 f_var_ori.write(sql_data)
331 f_var_ori.close()
332
333 res = os.system("/bin/mv %s %s" % (path_ori, path_bak))
334 if res != 0:
335 return 0, u("""erreur de création du répertoire de sauvegarde""")
336
337 materiel = ""
338 query_params = [int(id_new_mod), int(id_variante)]
339 for row in ['materiel','processeur','disque_dur','installateur', 'date_install']:
340 if hw_infos.has_key(row):
341 if hw_infos[row] != '':
342 materiel += ", %s=E%%s" % row
343 query_params.append(hw_infos[row])
344 query_params.append(int(serv.id_s))
345
346 query = "update serveurs set module_actuel=%s, variante=%s, params=''" + materiel + " where id=%s"
347 return self.dbpool.runOperation(query, query_params).addCallbacks(self._migrate_serveur_data, db_client_failed,callbackArgs=[serv,id_new_mod,id_variante,cred_user,migrate])
348
350
351 serv.update_data()
352 ret, msg = serv._cree_arbo_serveur()
353 if ret != 1:
354 self._revert_migration(serv, cred_user)
355 return ret, u(msg)
356
357 path_ori = serv.get_confdir()
358 if migrate:
359 path_bak = path_ori + "-backup"
360 else:
361 path_bak = path_ori + "-downgrade"
362 res = 0
363 self.copy_serveur_data(path_ori, path_bak, migrate)
364 serv.maj_params({'migration_ok':1})
365
366 if migrate == True:
367
368 try:
369 fic_cle_publique = os.path.join(path_bak,'cle_publique')
370
371 if os.path.isfile(fic_cle_publique):
372
373 backup_cle = open(fic_cle_publique,"r")
374 old_cle = backup_cle.read().strip().split('\n')[0]
375 backup_cle.close()
376
377 self._remove_ssh_key(old_cle)
378 except:
379 traceback.print_exc()
380 return self._update_conf_uucp(cred_user, serv.id_s, serv.rne, "")
381 else:
382 return 1, serv.id_s
383
385 """copie des fichiers compatibles lors d'une migration/update
386 """
387
388 if os.path.isfile(os.path.join(path_bak,'zephir.eol')) and not migrate:
389 res = os.system("/bin/cp -rf %s %s" % (os.path.join(path_bak,'zephir.eol'),os.path.join(path_ori,'zephir.eol')))
390 if res != 0:
391 return 0, u("""erreur de copie du fichier de configuration creole (zephir.eol)""")
392 if os.path.isfile(os.path.join(path_bak,'migration.eol')) and migrate:
393 res = os.system("/bin/cp -rf %s %s" % (os.path.join(path_bak,'migration.eol'),os.path.join(path_ori,'zephir.eol')))
394 if res != 0:
395 return 0, u("""erreur de copie du fichier de migration creole (migration.eol -> zephir.eol)""")
396
397 data_files = ['auth_keys','vpn']
398 if not migrate:
399 data_files.append('cle_publique')
400
401 for data_dir in ['fichiers_zephir', 'fichiers_perso', 'patchs', 'dicos/local','uucp']:
402 for data_file in os.listdir(os.path.join(path_bak,data_dir)):
403 if not os.path.islink(os.path.join(path_bak,data_dir,data_file)):
404 data_files.append(os.path.join(data_dir, data_file))
405 log.msg("\n !! copying data : %s !!\n" % (data_files))
406 res = 0
407 for fic in data_files:
408 if os.path.isdir(os.path.join(path_ori,fic)):
409 shutil.rmtree(os.path.join(path_ori,fic))
410 if os.path.exists(os.path.join(path_bak,fic)):
411 res = os.system("/bin/cp -rpf %s %s" % (os.path.join(path_bak,fic),os.path.join(path_ori,fic)))
412 if res != 0:
413 break
414 if res != 0:
415 return 0, u("""erreur de copie des fichiers de configuration uucp""")
416
418 """fonction de récupération des données d'un serveur migré
419 """
420 try:
421 id_serveur = int(id_serveur)
422 serv = self.parent.s_pool.get(cred_user, id_serveur)
423 return serv.migrate_data(check)
424 except KeyError:
425 return 0, u("""serveur inconnu""")
426
428 """fonction de création d'un fichier de configuration pour la migration (migration.eol)
429 """
430 try:
431 id_serveur = int(id_serveur)
432 serv = self.parent.s_pool.get(cred_user, id_serveur)
433 except KeyError:
434 return 0, u("""serveur invalide""")
435 if variante_dest == '':
436
437 variante_dest=serv.variante_migration()
438 if variante_dest == '':
439 return 0, u("""variante de destination non définie""")
440
441 query = 'select variantes.id, variantes.module, modules.version, modules.libelle from variantes,modules where variantes.id=%s and modules.id=variantes.module'
442 return self.dbpool.runQuery(query, (int(variante_dest),)).addCallbacks(self._migrate_config, db_client_failed,callbackArgs=[cred_user, serv, mode])
443
445
446 try:
447 id_variante = int(data[0][0])
448 id_new_mod = int(data[0][1])
449 version_new = int(data[0][2])
450 lib_new = str(data[0][3])
451 lib_act = serv.get_module().split('-')[0]
452 assert serv.version == "creole1" and version_new > 1
453 assert lib_new.split('-')[0] == lib_act.split('-')[0]
454 except:
455 return 0,u("""la migration vers le module demandé n'est pas gérée""")
456
457
458 try:
459 config_serv = serv.migrate_config(id_new_mod,id_variante,mode)
460 data = config_serv.get_dict()
461 except:
462 traceback.print_exc()
463 return 0, u("""erreur lors de l'import des données de configuration""")
464 return 1, u(data)
465
467 """retour en arrière sur la migration d'un serveur
468 """
469 try:
470 id_serveur = int(id_serveur)
471 serv = self.parent.s_pool.get(cred_user, id_serveur)
472 return self._revert_migration(serv,cred_user)
473 except (KeyError, ValueError):
474 return 0, u("""id de serveur non valide : %s""" % str(id_serveur))
475
477 path_ori = serv.get_confdir()
478 path_bak = path_ori + "-downgrade"
479 if not os.path.isdir(path_bak):
480 path_bak = path_ori + "-backup"
481 if not os.path.isdir(path_bak):
482 return 0, u("""répertoire de backup non retrouvé""")
483
484 f_var_ori = file(os.path.join(path_bak,"sql_data.ori"))
485 data_ori = f_var_ori.read().strip().split('::')
486 f_var_ori.close()
487 try:
488 assert len(data_ori) == 10
489 except:
490 return 0, u("""impossible de relire les données sql d'origine""")
491
492 data_ori.append(serv.id_s)
493 query = "update serveurs set \
494 module_actuel=%s,\
495 variante=%s,\
496 materiel=E'%s',\
497 processeur=E'%s',\
498 disque_dur=E'%s',\
499 date_install=E'%s',\
500 installateur=E'%s',\
501 tel=E'%s',\
502 remarques=E'%s',\
503 timeout=%s,\
504 params=null, maj=null where id=%s" % tuple(data_ori)
505 return self.dbpool.runOperation(query).addCallbacks(self._revert_migration2,db_client_failed,callbackArgs=[serv, path_ori, path_bak,cred_user])
506
508 fic_cle_publique = os.path.join(path_ori,'cle_publique')
509 try:
510
511 if os.path.isfile(fic_cle_publique):
512 backup_cle = open(fic_cle_publique,"r")
513 new_key = backup_cle.read().strip().split('\n')[0]
514 backup_cle.close()
515
516 self._remove_ssh_key(new_key)
517 except:
518 traceback.print_exc()
519
520 if os.path.isdir(path_ori):
521 shutil.rmtree(path_ori)
522 res = os.system("/bin/mv %s %s;/bin/sync" % (path_bak, path_ori))
523 if res != 0:
524 return 0, u("""erreur de mise en place des données sauvegardées""")
525 os.unlink(os.path.join(path_ori,"sql_data.ori"))
526 try:
527
528 if os.path.isfile(fic_cle_publique):
529
530 backup_cle = open(fic_cle_publique,"r")
531 old_key = backup_cle.read().strip().split('\n')[0]
532 backup_cle.close()
533
534 self._authorize_ssh_key(old_key)
535 except:
536 traceback.print_exc()
537
538 if os.path.isfile(os.path.join(path_ori,'uucp','sys')):
539 data_uucp = open(os.path.join(path_ori,'uucp','sys')).read().split('\n')
540 for line in data_uucp:
541 if line.startswith('call-password') and line.count(serv.rne) > 0:
542 passwd_uucp = line.strip().split()[-1]
543 self._update_conf_uucp(cred_user, serv.id_s, serv.rne, "", passwd_uucp)
544 break
545 serv.update_data()
546 serv.get_params()
547 return 1, "OK"
548
550 """regarde si un backup de migration est présent pour un serveur
551 """
552 try:
553 id_serveur = int(id_serveur)
554 serv = self.parent.s_pool.get(cred_user, id_serveur)
555 path_serv = serv.get_confdir()
556 except KeyError:
557 return 0, u("""serveur inconnu""")
558 if os.path.isdir(path_serv + '-backup'):
559 return 1, True
560 else:
561 return 1, False
562
564 """lancement telechargement pour migration sur un serveur"""
565 return self._download_upgrade(cred_user, id_serveur, version, delay)
566
568 """lancement telechargement pour migration sur un groupe de serveurs"""
569 erreurs=[]
570 for serveur in liste:
571 retour = self._download_upgrade(cred_user, serveur['id'], version, delay)
572 if retour[0] == 0:
573 erreurs.append("serveur "+str(serveur['id'])+' : '+retour[1])
574 if erreurs != []:
575 if len(erreurs) == len(liste):
576
577 return 0, u(erreurs)
578 else:
579 return 1, u(erreurs)
580 else:
581 return 1, []
582
584 """lancement du téléchargement des paquets de mise à jour pour upgrader
585 vers une version supérieure du système"""
586 try:
587 id_serveur = int(id_serveur)
588 serv = self.parent.s_pool.get(cred_user, id_serveur)
589 except (KeyError, ValueError):
590 return 0, u("""id de serveur non valide : %s""" % str(id_serveur))
591 serveur_version = serv.module_version
592 serveur_module = serv.module
593 serveur_module = serveur_module[:serveur_module.rindex('-')]
594
595 if version != serveur_version + 1:
596
597 try:
598 assert version in config.allowed_upgrades[serveur_module][serveur_version]
599 except:
600 return 0, u("Migration non supportée")
601 id_uucp = str(serv.get_rne()) + '-' + str(serv.id_s)
602 upgrade_version = config.DISTRIBS[version][1]
603 try:
604
605 uucp_pool.add_cmd(id_uucp,"zephir_client download_upgrade %s %s" % (upgrade_version, str(delay)))
606 except UUCPError, e:
607 return 0, u("Erreur UUCP (%s)" % str(e))
608 return 1, u("ok")
609
610 - def xmlrpc_add_serveur(self, cred_user, rne, libelle, materiel, processeur, disque_dur,
611 date_install, installateur, tel, remarques,
612 module_initial, module_actuel, timeout, variante=None, cle_rsa1="", id_groupe=-1
613 ):
614 """ajout d'un serveur dans la base zephir"""
615
616 if rne:
617
618 liste_donnees = [cred_user, rne, libelle, materiel, processeur, disque_dur, date_install, installateur, tel, remarques, module_initial, module_actuel, variante, timeout, cle_rsa1,id_groupe]
619 query = """select id from variantes where module = %s and libelle = 'standard'"""
620 return self.dbpool.runQuery(query, (int(module_actuel),)).addCallbacks(self._add_serveur1, db_client_failed,callbackArgs=liste_donnees)
621 else:
622
623 return 0,u("""arguments à fournir:
624 rne,libelle,materiel,processeur,disque_dur,date_install,
625 installateur,tel,remarques,module_initial,module_actuel,variante""")
626
627
628 - def _add_serveur1(self, search_result, cred_user, rne, libelle, materiel, processeur, disque_dur,
629 date_install, installateur, tel, remarques,
630 module_initial, module_actuel, variante, timeout, cle_rsa1="", id_groupe=-1
631 ):
632 """insertion du serveur dans la base de données"""
633
634 if variante is None or variante == "":
635 variante = search_result[0][0]
636 timestamp_serveur = str(time.time())
637 try:
638 timeout = int(timeout)
639 except:
640 timeout = 0
641
642 try:
643 serv = 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)
644 id_serveur = serv.id_s
645
646 if int(id_groupe) >= 0:
647 self.parent.s_pool.extend_groupe(cred_user,int(id_groupe),[id_serveur])
648 except Exception, e:
649 return 0, u(str(e))
650
651 result,errmsg = serv._cree_arbo_serveur()
652 if result == 0:
653
654 self.xmlrpc_del_serveur(cred_user, id_serveur)
655 return 0, u(errmsg)
656 else:
657 return self._update_conf_uucp(cred_user, serv.id_s, rne, cle_rsa1)
658
660
661 id_uucp = str(rne)+'-'+str(id_serveur)
662 if passwd_uucp == "":
663 passwd_uucp = str(rne)+'-'+str(id_serveur)+'-'+str(time.time())
664 id_uucp = str(rne)+'-'+str(id_serveur)
665
666 chaine_conf=config.CONFIG_UUCP % (id_serveur,id_uucp,id_uucp,passwd_uucp)
667 try:
668 if not os.path.isdir("/etc/uucp/serveurs/"):
669 os.makedirs("/etc/uucp/serveurs/")
670 fic_conf=open("/etc/uucp/serveurs/"+id_uucp+".sys","w")
671 fic_conf.write(chaine_conf)
672 fic_conf.close()
673 except:
674
675 self.xmlrpc_del_serveur(cred_user, id_serveur)
676 return 0,u("""erreur de création de la configuration uucp""")
677 else:
678
679 test=os.system('grep "sysfile /etc/uucp/serveurs/'+id_uucp+'.sys" /etc/uucp/config_zephir')
680 result = 0
681 if test != 0:
682
683 result=os.system('echo "sysfile /etc/uucp/serveurs/'+id_uucp+'.sys" >>/etc/uucp/config_zephir')
684 if result == 0:
685
686 try:
687 fic_pass=file('/etc/uucp/passwd_zephir')
688 lines=fic_pass.read().strip().split('\n')
689 fic_pass.close()
690
691 content=[]
692 for line in lines:
693
694 if not line.startswith(id_uucp+' '):
695 content.append(line)
696
697 content.append("%s %s" % (id_uucp,passwd_uucp))
698
699 fic_pass=file('/etc/uucp/passwd_zephir','w')
700 lines=fic_pass.write("\n".join(content))
701 fic_pass.close()
702 except:
703 result = 1
704 if result == 0:
705
706 return self._conf_uucp(id_serveur, rne, passwd_uucp, cle_rsa1)
707 if result != 0:
708 self.xmlrpc_del_serveur(cred_user, id_serveur)
709 return 0,u("""erreur de mise à jour de la configuration uucp""")
710
711 - def _conf_uucp(self,id_serveur,rne,passwd_uucp,cle_rsa1=""):
712 """création des fichiers de configuration uucp du serveur"""
713 path_dest=os.path.abspath(config.PATH_ZEPHIR)+'/conf/'+rne+os.sep+str(id_serveur)+os.sep+'uucp'
714
715
716 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)
717 os.system(cmd)
718
719 for filepath in ["config","sys","port"]:
720
721 try:
722 fic_ori=open(config.TEMPLATE_DIR+os.sep+filepath,'r')
723 lines = fic_ori.readlines()
724 fic_ori.close()
725 except:
726 return 0,u('erreur de lecture du fichier %s ' % filepath)
727 conf=[]
728 for line in lines:
729
730
731 line = line.replace('%%serveur%%',str(rne)+'-'+str(id_serveur))
732 line = line.replace('%%password%%',passwd_uucp)
733
734 conf.append(line)
735
736 try:
737 fic_dest=open(path_dest+os.sep+filepath,'w')
738 fic_dest.writelines(conf)
739 fic_dest.close()
740 except:
741 return 0,u('erreur de création du fichier %s ' % path_dest+os.sep+filepath)
742 if cle_rsa1 != "":
743
744 return self._conf_ssh('',id_serveur,base64.decodestring(cle_rsa1))
745 else:
746 return 1, id_serveur
747
749 """permet de récupérer la configuration uucp d'un serveur via xmlrpc"""
750 if cle_rsa1 == "":
751 return 0, u("""clé rsa invalide""")
752 if self.parent.s_pool.has_key(id_serveur):
753
754 self.parent.s_pool.update_contact(id_serveur)
755 return self._conf_ssh('',id_serveur,base64.decodestring(cle_rsa1))
756 else:
757 return 0, u("""erreur, serveur non retrouvé""")
758
759 - def _conf_ssh(self,cred_user,id_serveur,cle_rsa1):
760 """mise en place de la clé pour l'authentification d'uucp sur ssh"""
761 try:
762 id_serveur = int(id_serveur)
763 serv = self.parent.s_pool.get(cred_user, id_serveur)
764 except KeyError:
765 return 0, u("""serveur inconnu""")
766 path_dest=serv.get_confdir()
767
768 ligne_rsa = 'command="sudo /usr/sbin/uucico2 -D -l" '+cle_rsa1
769
770 try:
771 fic_cle_publique = os.path.join(path_dest,'cle_publique')
772
773 if os.path.isfile(fic_cle_publique):
774
775 backup_cle = open(fic_cle_publique,"r")
776 old_cle = backup_cle.read().strip().split('\n')[0]
777 backup_cle.close()
778
779 self._remove_ssh_key(old_cle)
780
781 backup_cle = open(fic_cle_publique,"w")
782 backup_cle.write(ligne_rsa)
783 backup_cle.close()
784 serv.maj_params({'cle_ok':1})
785
786 self._authorize_ssh_key(ligne_rsa)
787 except:
788
789 self.xmlrpc_del_serveur(cred_user,id_serveur)
790 return 0,u("Erreur d'ajout de la cle rsa sur le serveur")
791 else:
792
793 files = []
794 for path_conf in ['config','sys','port']:
795
796 file_conf=open(path_dest+os.sep+'uucp'+os.sep+path_conf,"r")
797 lines_conf=file_conf.read()
798 file_conf.close()
799
800
801 if path_conf == 'config':
802 if lines_conf.count('lockdir') == 0:
803 lines_conf = lines_conf + "\nlockdir /tmp"
804
805 files.append(base64.encodestring(lines_conf))
806
807 if os.path.exists(path_dest+os.sep+'zephir.eol'):
808
809 file_conf=open(path_dest+os.sep+'zephir.eol',"r")
810 lines_conf = file_conf.read()
811 file_conf.close()
812 files.append(base64.encodestring(lines_conf))
813 else:
814
815 files.append("")
816 return 1,id_serveur,files[0],files[1],files[2],files[3]
817
819 """ajoute une cle ssh dans authorized_keys
820 """
821 if os.path.isfile("/var/spool/uucp/.ssh/authorized_keys"):
822 auth_keys = open("/var/spool/uucp/.ssh/authorized_keys","r")
823 lines=auth_keys.read().strip().split('\n')
824 auth_keys.close()
825 else:
826 lines = []
827
828 lines.append(cle)
829
830 auth_keys = open("/var/spool/uucp/.ssh/authorized_keys","w")
831 auth_keys.write("\n".join(lines))
832 auth_keys.close()
833
835 """supprime une cle ssh de authorized_keys
836 """
837 auth_keys = open("/var/spool/uucp/.ssh/authorized_keys","r")
838 lines=auth_keys.read().strip().split('\n')
839 auth_keys.close()
840 new_lines = []
841 for line in lines:
842 if line.startswith(cle.strip()):
843
844 pass
845 else:
846
847 new_lines.append(line)
848
849 auth_keys = open("/var/spool/uucp/.ssh/authorized_keys","w")
850 auth_keys.write("\n".join(new_lines))
851 auth_keys.close()
852
854 """supression d'un serveur de la base zephir"""
855 try:
856 id_serveur = int(id_serveur)
857 serv = self.parent.s_pool.get(cred_user, id_serveur)
858 except ValueError, KeyError:
859
860 return 0, u("""donnez un identifiant de serveur valide""")
861
862
863
864
865
866 id_uucp = serv.rne+'-'+str(id_serveur)
867
868 query = """select id,libelle,serveurs from groupes_serveurs"""
869 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
870 cursor=cx.cursor()
871 cursor.execute(query)
872 groupes=cursor.fetchall()
873
874 for groupe in groupes:
875 serv_gr = eval(groupe[2])
876 if id_serveur in serv_gr:
877
878 serv_gr.remove(id_serveur)
879
880 if serv_gr == []:
881
882 self.xmlrpc_del_group(cred_user,int(groupe[0]))
883 else:
884 self.xmlrpc_edit_group(cred_user,int(groupe[0]),groupe[1],serv_gr)
885
886
887 cursor.close()
888 cx.close()
889
890 serveur_dir = serv.get_confdir()
891 self.parent.s_pool.del_serveur(cred_user, id_serveur)
892
893
894 cle_pub=""
895 if os.path.isfile(serveur_dir+os.sep+"cle_publique"):
896 fic_rsa=open(serveur_dir+os.sep+"cle_publique","r")
897 cle_pub = fic_rsa.read().strip().split('\n')[0]
898 fic_rsa.close()
899 try:
900 shutil.rmtree(serveur_dir)
901 except:
902 return 1, u("""erreur de supression du repertoire du serveur""")
903
904 if os.path.exists(os.path.abspath(config.PATH_ZEPHIR)+os.sep+"data"+os.sep+str(id_serveur)):
905 stat_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+"data"+os.sep+str(id_serveur)
906 else:
907 stat_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+"sites"+os.sep+str(id_serveur)
908 try:
909 shutil.rmtree(stat_dir)
910 except:
911
912 pass
913
914 for fic_data in ['config%s.md5' % str(id_serveur),'packages%s.list' % str(id_serveur)]:
915 if os.path.isfile(os.path.join(os.path.abspath(config.PATH_ZEPHIR),"data",fic_data)):
916 try:
917 os.unlink(os.path.join(os.path.abspath(config.PATH_ZEPHIR),"data",fic_data))
918 except:
919 pass
920 if os.path.exists("/var/spool/uucppublic/site%s.tar" % id_serveur):
921 try:
922 os.unlink("/var/spool/uucppublic/site%s.tar" % id_serveur)
923 os.unlink("/var/spool/uucppublic/site%s.md5" % id_serveur)
924 except:
925 pass
926
927
928 if os.path.exists("/var/spool/uucp/"+id_uucp):
929 shutil.rmtree("/var/spool/uucp/"+id_uucp)
930
931 try:
932 os.unlink("/etc/uucp/serveurs/"+id_uucp+".sys")
933 except:
934 pass
935 fic_config=open("/etc/uucp/config_zephir","r")
936 config_uucp=fic_config.readlines()
937 fic_config.close()
938 try:
939 config_uucp.remove('sysfile /etc/uucp/serveurs/'+id_uucp+'.sys\n')
940 except ValueError:
941 return 1, u("""configuration uucp non retouvée""")
942 else:
943 try:
944 fic_config=open("/etc/uucp/config_zephir","w")
945 fic_config.writelines(config_uucp)
946 fic_config.close()
947 except:
948 return 1, u("""erreur d'écriture dans /etc/uucp/config_zephir""")
949 else:
950
951 fic_config=open("/etc/uucp/passwd_zephir","r")
952 config_uucp=fic_config.readlines()
953 fic_config.close()
954 for line in config_uucp:
955 if line.startswith(id_uucp+' '):
956 config_uucp.remove(line)
957 try:
958 fic_config=open("/etc/uucp/passwd_zephir","w")
959 fic_config.writelines(config_uucp)
960 fic_config.close()
961 except:
962 return 1, u("""erreur d'écriture dans /etc/uucp/passwd_zephir""")
963
964 if cle_pub != "":
965 try:
966 self._remove_ssh_key(cle_pub)
967 except:
968
969 return 1, u("""clé rsa du serveur non retrouvée""")
970 return 1, 'ok'
971
973 """Liste des serveurs d'un etablissement
974 """
975 if rne :
976 query="""select * from serveurs where rne ilike %s"""
977 return self.dbpool.runQuery(query, (rne,)).addCallbacks(self._got_serveur,db_client_failed,callbackArgs=[cred_user])
978 else :
979 query="""select * from serveurs"""
980 return self.dbpool.runQuery(query).addCallbacks(self._got_serveur,db_client_failed,callbackArgs=[cred_user])
981
982
984 """récupération d'un serveur particulier (ou tous)
985 """
986 if id_serveur:
987 query="""select * from serveurs where id = %s"""
988 return self.dbpool.runQuery(query, (int(id_serveur),)).addCallbacks(self._got_serveur,db_client_failed,callbackArgs=[cred_user])
989 else :
990 query="""select * from serveurs"""
991 return self.dbpool.runQuery(query).addCallbacks(self._got_serveur,db_client_failed,callbackArgs=[cred_user])
992
994 """récupération d'un groupe de serveurs à partir de critères
995 """
996
997 if ('type_etab_lib' in criteres and criteres['type_etab_lib'] != '') or \
998 ('type_etab' in criteres and criteres['type_etab'] != ''):
999 query = ["select serveurs.* from serveurs, etablissements, types_etab "]
1000 else:
1001 query = ["select * from serveurs "]
1002 params = []
1003 if criteres != {}:
1004 query.append("where ")
1005 for nom_champ in criteres.keys():
1006 if criteres[nom_champ] != "":
1007 if nom_champ == 'type_etab_lib':
1008 query.append("(serveurs.rne = etablissements.rne) and \
1009 (etablissements.type = types_etab.id) and \
1010 (types_etab.libelle ilike E%s) and ")
1011 params.append(str(criteres[nom_champ]))
1012 elif nom_champ == 'type_etab':
1013 query.append("(serveurs.rne = etablissements.rne) and \
1014 (etablissements.type = types_etab.id) and \
1015 (etablissements.type = %s) and ")
1016 params.append(int(criteres[nom_champ]))
1017 else:
1018 query.append("(serveurs."+str(nom_champ))
1019 if (nom_champ == 'last_contact') or (nom_champ == 'etat' and criteres[nom_champ] == "null"):
1020 query.append(" is null) and ")
1021 elif nom_champ == 'etat' and criteres[nom_champ] != '':
1022 if criteres[nom_champ] == "alertes":
1023 query.append(" <> 1) and (etat is not null) and ")
1024 else:
1025 query.append(" = %s) and ")
1026 params.append(criteres[nom_champ])
1027 elif (nom_champ == 'md5s' and criteres[nom_champ] == "null"):
1028 query.append(" is null) and ")
1029 elif nom_champ in ['module_actuel','module_initial','variante','timeout','md5s', 'id','no_alert'] and criteres[nom_champ] != '':
1030 query.append(" = %s) and ")
1031 params.append(int(criteres[nom_champ]))
1032 elif nom_champ == 'date_install':
1033
1034 query.append(" %s) and " % str(criteres[nom_champ]))
1035 elif nom_champ == 'maj':
1036 if str(criteres[nom_champ]) == 'outdated':
1037 query.append(" > 0) and ")
1038 elif str(criteres[nom_champ]) == 'uptodate':
1039 query.append(" = 0) and ")
1040 else:
1041 query.append(" < 0 or %s is null) and " % str(nom_champ))
1042 else:
1043 query.append(" ilike E%s) and ")
1044 params.append(str(criteres[nom_champ]))
1045 query[-1] = query[-1][:query[-1].rindex('and')]
1046
1047 query.append("order by RNE,module_actuel")
1048 query = "".join(query)
1049 if variables != {}:
1050 return self.dbpool.runQuery(query, params).addCallbacks(self._groupe_serveur_vars, db_client_failed, callbackArgs=[variables, strict, cred_user])
1051 else:
1052 return self.dbpool.runQuery(query, params).addCallbacks(self._got_serveur, db_client_failed,callbackArgs=[cred_user])
1053
1055 """Recherche des serveurs en fonction d'un variable de configuration
1056 """
1057 l=[]
1058 auth_error = False
1059 for serveur in serveurs:
1060
1061 try:
1062 serv = self.parent.s_pool.get(cred_user,int(serveur[0]))
1063 except ResourceAuthError:
1064 auth_error = True
1065 continue
1066
1067 try:
1068 d = serv.get_config(encode=True)
1069 except:
1070
1071 continue
1072 val_found = False
1073 for var, criteres in variables.items():
1074 name, val, negate = criteres
1075 if d.version == "creole2":
1076 val = val.split('|')
1077 val = [value.strip() for value in val]
1078 try:
1079 if (d.get_value(name) == val and not negate) or (d.get_value(name) != val and negate):
1080 val_found = True
1081 if not strict:
1082
1083 break
1084 elif strict:
1085
1086 val_found = False
1087 break
1088 except:
1089
1090 pass
1091 if val_found:
1092 l.append(self._format_serv(serveur,serv))
1093 if l == [] and auth_error == True:
1094
1095 raise ResourceAuthError("""Vous n'avez accès à aucun serveur dans ce groupe""")
1096 return 1,u(l)
1097
1099 """renvoie un groupe à partir d'une liste d'id de serveurs
1100 """
1101 if liste_serveurs != []:
1102 params = []
1103
1104 query=["select * from serveurs where id=%s"]
1105 for serveur in liste_serveurs:
1106 params.append(int(serveur))
1107 query.append(" or id=%s")
1108 query = "".join(query)
1109 query = query[:query.rindex('or')]
1110 query += "order by rne,module_actuel"
1111 return self.dbpool.runQuery(query, params).addCallbacks(self._got_serveur, db_client_failed,callbackArgs=[cred_user])
1112
1113
1114
1115
1117 """ajoute une liste de serveurs à un groupe enregistré
1118 """
1119 if liste_serveurs != [] and type(liste_serveurs) == list:
1120 try:
1121 self.parent.s_pool.extend_groupe(cred_user,int(id_groupe),liste_serveurs)
1122 except (KeyError, ValueError):
1123 return 0, u("""groupe non trouvé dans la base""")
1124 else:
1125 return 1, "ok"
1126 else:
1127 return 1, u("liste de serveurs à insérer vide")
1128
1129
1131 """modification d'un serveur
1132 cette fonction prend en compte un dictionnaire qui indique les
1133 champs à modifier et leur nouvelle valeur. l'application cliente
1134 doit s'assurer que ces champs existent dans la base"""
1135
1136 modifs = {}
1137 if dico_modifs.has_key('timeout'):
1138 modifs['timeout'] = int(dico_modifs['timeout'])
1139 if dico_modifs.has_key('variante'):
1140 modifs['variante'] = int(dico_modifs['variante'])
1141 if dico_modifs.has_key('no_alert'):
1142 modifs['no_alert'] = int(dico_modifs['no_alert'])
1143
1144
1145 liste_serv = []
1146 for id_serveur in liste_serveurs:
1147 try:
1148 id_serveur = int(id_serveur)
1149 serv = self.parent.s_pool.get(cred_user, id_serveur)
1150 liste_serv.append(serv)
1151 except (KeyError, ValueError):
1152 return 0, u("""id de serveur non valide : %s""" % str(id_serveur))
1153
1154 if modifs != {}:
1155
1156 erreurs = []
1157 for serveur in liste_serv:
1158 code = 1
1159 if 'variante' in modifs.keys():
1160
1161 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
1162 cursor=cx.cursor()
1163 cursor.execute("""select module from variantes where id=%s""", (int(modifs['variante']),))
1164 var_mod=cursor.fetchone()
1165 cursor.close()
1166 cx.close()
1167 libelle = serveur.get_libelle()
1168 if serveur.id_mod in var_mod:
1169 code,raison = self.parent.s_pool.edit_serveur(serveur.id_s, dico_modifs)
1170 raison = "%s (%s) : erreur d'application de la variante" % (libelle,serveur.id_s)
1171 else:
1172 code = 0
1173 raison = "%s (%s) : le module ne correspond pas à la variante" % (libelle,serveur.id_s)
1174 if code == 0:
1175 erreurs.append(raison)
1176 else:
1177
1178 params = []
1179 query=["update serveurs set "]
1180 for cle in modifs.keys():
1181 query.append(str(cle))
1182 query.append("=%s, ")
1183 params.append(modifs[cle])
1184 query="".join(query)[:-2]
1185 query += """ where id=%s"""
1186 params.append(int(serveur.id_s))
1187
1188 try:
1189 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
1190 cursor=cx.cursor()
1191 cursor.execute(query, params)
1192 cursor.close()
1193 cx.commit()
1194 cx.close()
1195 except:
1196 erreurs.append("%s (%s) : erreur de modification de la base" % (serveur.get_libelle(),serveur.id_s))
1197
1198 serveur.update_data()
1199
1200 if erreurs != []:
1201 return 1, u(erreurs)
1202 else:
1203 return 1, u("OK")
1204 else:
1205 return 1,u("Pas de modifications à effectuer")
1206
1207
1209 """modification d'un serveur
1210 cette fonction prend en compte un dictionnaire qui indique les
1211 champs à modifier et leur nouvelle valeur. l'application cliente
1212 doit s'assurer que ces champs existent dans la base"""
1213 try:
1214 id_serveur = int(id_serveur)
1215 serv = self.parent.s_pool.get(cred_user, id_serveur)
1216 return self.parent.s_pool.edit_serveur(id_serveur, dico_modifs)
1217 except (KeyError, ValueError):
1218 return 0, u("""id de serveur non valide : %s""" % str(id_serveur))
1219
1220 - def multi_call(proxy, results, err_not_allowed=False):
1221 """renvoie le résultat d'une liste de deffered
1222 @param err_not_allowed: on sort en erreur à la première erreur si True"""
1223 result = []
1224 for res in results:
1225 code, res = res[1]
1226 if code == 0:
1227 if err_not_allowed:
1228 return code, res
1229 result.append(res)
1230 return 1, u(result)
1231
1233 """fonction qui renvoie différentes informations sur les(s) serveur(s) :
1234 - présence de dico.eol
1235 - présence de config.eol
1236 - présence de la clé rsa (uucp)
1237 - état des différentes actions
1238 """
1239 if type(id_serveur) == list:
1240 results = []
1241 for id_serv in id_serveur:
1242 code, res = self._get_status(cred_user,id_serv)
1243 if code == 1:
1244 results.append(u(res))
1245 return 1, results
1246 else:
1247 return self._get_status(cred_user,id_serveur)
1248
1259
1261 """retourne la liste des paquets non à jour"""
1262 try:
1263 id_serveur = int(id_serveur)
1264 serv = self.parent.s_pool.get(cred_user, id_serveur)
1265 res = serv.check_maj_status(show_installed, debnames)
1266 except (KeyError, ValueError):
1267 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1268 else:
1269 return 1, u(res)
1270
1272 """renvoie la liste des serveurs en alerte"""
1273 serveurs = self.parent.s_pool.get_alertes(cred_user)
1274
1275 res = []
1276 for serv in serveurs:
1277 if not serv.no_alert:
1278 res.append([serv.get_rne(), serv.get_etab(), serv.get_libelle(), serv.get_module(), serv.id_s, serv.get_status()])
1279
1280 return 1, u(res)
1281
1283 """renvoie la liste des serveurs en alerte"""
1284 serveurs = self.parent.s_pool.get_migration_status(cred_user)
1285
1286 res = [[],[]]
1287 for type_serv in [0,1]:
1288 for serv in serveurs[type_serv]:
1289 res[type_serv].append([serv.get_rne(), serv.get_etab(), serv.get_libelle(), serv.get_module(), serv.id_s, type_serv])
1290 return 1, u(res)
1291
1293 """ajoute des fichiers, patchs, dictionnaires à un serveur
1294 """
1295
1296 try:
1297 id_serveur = int(id_serveur)
1298 serv = self.parent.s_pool.get(cred_user, id_serveur)
1299 except (KeyError, ValueError):
1300 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1301
1302 if serv.version == 'creole1' and encode == True:
1303 for type_f, files in dico_files.items():
1304 if type_f in ['dicos','patchs','persos','fichiers_zeph']:
1305 encoded_files = []
1306 for fichier in dico_files[type_f]:
1307 content = unicode(base64.decodestring(fichier[1]),config.charset).encode('ISO-8859-1')
1308 localpath = ""
1309 if len(fichier) == 3:
1310 localpath = fichier[2]
1311 encoded_files.append([fichier[0], base64.encodestring(content),localpath])
1312 dico_files[type_f] = encoded_files
1313
1314
1315 dest_dir = serv.get_confdir()
1316
1317 if dico_files.has_key('dicos'):
1318 for dico in dico_files['dicos']:
1319 try:
1320 if dico[0] != "":
1321 if serv.version == 'creole1':
1322 f=open(dest_dir+os.sep+'dicos/'+os.sep+os.path.basename(dico[0].replace("\\","/")),'w')
1323 else:
1324 f=open(dest_dir+os.sep+'dicos/local/'+os.sep+os.path.basename(dico[0].replace("\\","/")),'w')
1325 f.write(base64.decodestring(dico[1]))
1326 f.close()
1327 except:
1328 return 0,u("erreur de sauvegarde de %s" % dico)
1329
1330 if dico_files.has_key('persos'):
1331 for template in dico_files['persos']:
1332 try:
1333 if template[0] != "":
1334 f=open(dest_dir+os.sep+'fichiers_perso'+os.sep+os.path.basename(template[0].replace("\\","/")),'w')
1335 f.write(base64.decodestring(template[1]))
1336 f.close()
1337 except:
1338 return 0,u("erreur de sauvegarde de %s" % template)
1339
1340 if dico_files.has_key('patchs'):
1341 for patch in dico_files['patchs']:
1342 try:
1343 if patch[0] != "":
1344 f=open(dest_dir+os.sep+'patchs'+os.sep+os.path.basename(patch[0].replace("\\","/")),'w')
1345 f.write(base64.decodestring(patch[1]))
1346 f.close()
1347 except:
1348 return 0,u("erreur de sauvegarde de %s" % patch)
1349
1350
1351 try:
1352 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir')
1353 old_content=f.read()
1354 f.close()
1355 fichiers=old_content.split('%%\n')[0]
1356 rpms=old_content.split('%%\n')[1]
1357 except:
1358 fichiers=FILE_SECTION
1359 rpms=RPM_SECTION
1360
1361 if dico_files.has_key('fichiers_zeph'):
1362 for fichier in dico_files['fichiers_zeph']:
1363 localpath = ""
1364 if len(fichier) == 3:
1365 localpath = fichier[2]
1366 nom_fic = fichier[0].replace("\\","/")
1367
1368 if fichier[0].endswith('/'):
1369 nom_fic = fichier[0][:-1]
1370 if fichier[0].endswith("\\"):
1371 nom_fic = fichier[0][:-2]
1372
1373 if nom_fic not in fichiers.split('\n') and localpath == "":
1374 fichiers = fichiers.strip() + '\n' + nom_fic +'\n'
1375
1376 try:
1377 if nom_fic != "":
1378 if localpath == "":
1379 f=open(os.path.join(dest_dir,'fichiers_zephir',os.path.basename(nom_fic)),'w')
1380 else:
1381 f=open(os.path.join(dest_dir,localpath,os.path.basename(nom_fic)),'w')
1382 f.write(base64.decodestring(fichier[1]))
1383 f.close()
1384 except:
1385 return 0,u("erreur de sauvegarde de %s" % fichier)
1386
1387
1388 if dico_files.has_key('rpms'):
1389 for rpm in dico_files['rpms']:
1390
1391 if rpm not in rpms.split('\n'):
1392 rpms = rpms.strip() + '\n' + rpm +'\n'
1393
1394 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1395 f.write(fichiers+"%%\n"+rpms)
1396 f.close()
1397
1398
1399 serv.check_md5conf()
1400
1401 return 1,u("ok")
1402
1404 """suppression de fichiers, patchs, dictionnaires d'un serveur
1405 """
1406 try:
1407 id_serveur = int(id_serveur)
1408 serv = self.parent.s_pool.get(cred_user, id_serveur)
1409 except (KeyError, ValueError):
1410 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1411
1412 dest_dir = serv.get_confdir()
1413
1414 if dico_files.has_key('dicos'):
1415 for dico in dico_files['dicos']:
1416 try:
1417 if dico != "":
1418 if serv.version == 'creole1':
1419 os.unlink(dest_dir+os.sep+'dicos'+os.sep+dico)
1420 else:
1421 os.unlink(dest_dir+os.sep+'dicos/local'+os.sep+dico)
1422 except:
1423 return 0,u("erreur de suppression de %s" % dico)
1424
1425
1426 if dico_files.has_key('persos'):
1427 for template in dico_files['persos']:
1428 try:
1429 if template != "":
1430 os.unlink(dest_dir+os.sep+'fichiers_perso'+os.sep+template)
1431 except:
1432 return 0,u("erreur de supression de %s" % template)
1433
1434 self.parent.s_pool.del_file_perms(dest_dir,'fichiers_perso'+os.sep+template)
1435
1436
1437 if dico_files.has_key('patchs'):
1438 for patch in dico_files['patchs']:
1439 try:
1440 if patch != "":
1441 os.unlink(dest_dir+os.sep+'patchs'+os.sep+patch)
1442 except:
1443 return 0,u("erreur de suppression de %s" % patch)
1444
1445 if dico_files.has_key('fichiers_zeph') or dico_files.has_key('rpms'):
1446
1447 try:
1448 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir')
1449 old_content=f.read()
1450 f.close()
1451 fichiers=old_content.split('%%\n')[0]
1452 rpms=old_content.split('%%\n')[1]
1453 except:
1454 fichiers="""# section 1
1455 # liste des fichiers à sauvegarder pour la variante
1456 # (ne pas modifier sauf pour créer ou mettre à jour la variante)"""
1457 rpms="""# section 2
1458 # inscrire les noms des paquetages qui seront installés à la mise à jour du serveur
1459 # (ils doivent être présents sur le serveur de mise à jour)"""
1460
1461
1462 if dico_files.has_key('fichiers_zeph'):
1463 liste=fichiers.split('\n')
1464 for fichier in dico_files['fichiers_zeph']:
1465
1466 if fichier in liste:
1467 liste.remove(fichier)
1468 fic_path = os.path.join(dest_dir,'fichiers_zephir',os.path.basename(fichier.replace("\\","/")))
1469 else:
1470 fic_path = os.path.join(dest_dir,fichier)
1471
1472 try:
1473 if fichier != "":
1474 if os.path.isdir(fic_path):
1475 shutil.rmtree(fic_path)
1476 elif os.path.isfile(fic_path):
1477 os.unlink(fic_path)
1478 except:
1479 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1480 f.write(fichiers+"%%\n"+rpms)
1481 f.close()
1482 return 0,u("erreur de suppression de %s" % fichier)
1483
1484 if fichier.startswith('/'):
1485 fic_sup = 'fichiers_zephir/'+os.path.basename(fichier.replace("\\","/"))
1486 else:
1487 fic_sup = fichier
1488 self.parent.s_pool.del_file_perms(dest_dir,fic_sup,True)
1489 fichiers = "\n".join(liste)
1490
1491
1492 if dico_files.has_key('rpms'):
1493 for rpm in dico_files['rpms']:
1494
1495 liste=rpms.split('\n')
1496 if rpm in liste:
1497 liste.remove(rpm)
1498 else:
1499 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1500 f.write(fichiers+"%%\n"+rpms)
1501 f.close()
1502 return 0,u("rpm non trouvé dans la liste : %s" % rpm)
1503
1504 rpms = "\n".join(liste)
1505
1506 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1507 f.write(fichiers+"%%\n"+rpms)
1508 f.close()
1509
1510
1511 serv.check_md5conf()
1512
1513 return 1,u("ok")
1514
1515 - def xmlrpc_get_file_content(self,cred_user,id_serveur,path,show_details=False):
1516 """renvoie le contenu d'un fichier de serveur
1517 si le fichier est un fichier binaire, renvoie la chaine BINARY"""
1518 try:
1519 id_serveur = int(id_serveur)
1520 serv = self.parent.s_pool.get(cred_user, id_serveur)
1521 except (KeyError, ValueError):
1522 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1523
1524 try:
1525 dest_dir=serv.get_confdir()
1526 except:
1527 return 0,u("""lecture du fichier: paramètres non valides""")
1528
1529 try:
1530 if serv.version == "creole1":
1531 path = path.replace('dicos/local','dicos')
1532
1533 if os.path.isdir(dest_dir + os.sep + path):
1534 dirfiles = os.listdir(dest_dir + os.sep + path)
1535 content = []
1536 if show_details:
1537 for f in dirfiles:
1538 f_local = os.path.join(dest_dir,path,f)
1539 f_info = config.get_file_info(f_local)
1540 content.append((f,f_info))
1541 else:
1542 content = dirfiles
1543 return 1, u(content)
1544 else:
1545
1546 if istextfile(dest_dir + os.sep + path):
1547 f=file(dest_dir + os.sep + path)
1548 content=f.read()
1549 f.close()
1550
1551 if serv.version == "creole1":
1552 try:
1553 content = unicode(content,'ISO-8859-1').encode(config.charset)
1554 except:
1555
1556 log.msg("echec d'encoding du fichier %s provenant d'un serveur eole1" % path)
1557 content = base64.encodestring(content)
1558 else:
1559 content = "BINARY"
1560 return 1, content
1561 except:
1562 return 0,u("""erreur de lecture du fichier""")
1563
1565 """récupère la liste des variables communes à un groupe de serveur"""
1566
1567 liste_serv = []
1568 for id_serveur in serveurs:
1569 try:
1570 serv = self.parent.s_pool.get(cred_user, id_serveur)
1571 liste_serv.append(serv)
1572 except (KeyError, ValueError):
1573 return 0, u("""serveur inconnu dans la base zephir : %s""" % str(id_serveur))
1574 liste_vars = {}
1575 liste_modules = []
1576 erreurs = []
1577 group_vars = []
1578 first_iter=1
1579 for serveur in liste_serv:
1580
1581 serveur_dir = serveur.get_confdir()
1582
1583 d = serveur.get_config('modif_config',encode=encode)
1584 if d == None:
1585
1586 erreurs.append("""le serveur %s (%s) n'a pas de fichier zephir.eol""" % (serveur.id_s,serveur.get_libelle()))
1587 else:
1588
1589 if d.version == "creole2":
1590 for master, slaves in d.dico.groups.items():
1591 if master not in group_vars:
1592 group_vars.append(master)
1593 for slave in slaves:
1594 if slave not in group_vars:
1595 group_vars.append(slave)
1596
1597 if first_iter == 1:
1598 for var in d.liste_vars.keys():
1599 if d.version == "creole2":
1600 liste_vars[var]=[" | ".join(d.get_value(var))]
1601 else:
1602 liste_vars[var]=[d.get_value(var)]
1603 first_iter = 0
1604 else:
1605 for var in liste_vars.keys():
1606 if var not in d.liste_vars.keys():
1607
1608 del(liste_vars[var])
1609 else:
1610 val=d.get_value(var)
1611 if d.version == "creole2":
1612 val = " | ".join(val)
1613 if val not in liste_vars[var]:
1614 liste_vars[var].append(val)
1615
1616 if serveur.id_mod not in liste_modules:
1617 liste_modules.append(serveur.id_mod)
1618
1619 return 1, u([liste_vars,liste_modules,erreurs,group_vars])
1620
1622 """modifie une variable commune à un groupe de serveur"""
1623
1624 liste_serv = []
1625 for id_serveur in serveurs:
1626 try:
1627 serv = self.parent.s_pool.get(cred_user, id_serveur)
1628 liste_serv.append(serv)
1629 except (KeyError, ValueError):
1630 return 0, u("""serveur inconnu dans la base zephir : %s""" % str(id_serveur))
1631 erreurs = []
1632 for serveur in liste_serv:
1633
1634 serveur_dir = serveur.get_confdir()
1635
1636 try:
1637 d = serveur.get_config('modif_config',encode)
1638 assert d is not None
1639 except Exception,e:
1640 erreurs.append('%s-%s (%s)' % (str(serv.id_s),serveur.get_libelle(),str(e)))
1641 else:
1642
1643 try:
1644 final_val = val
1645 d.get_var(var)
1646 if d.version == "creole2":
1647
1648 multi = True
1649 if d.dico.variables[var].multi == False:
1650 multi = False
1651 for master, slaves in d.dico.groups.items():
1652 if var in slaves:
1653 multi = True
1654 if multi:
1655 final_val = [value.strip() for value in val.split("|")]
1656 d.set_value(final_val)
1657 except Exception,e:
1658 traceback.print_exc()
1659 erreurs.append('%s-%s (%s)' % (str(serv.id_s),serveur.get_libelle(),str(e)))
1660 else:
1661
1662 res = serveur.save_config(d,'modif_config',encode,force=True)
1663 if res != "":
1664 erreurs.append(res)
1665 return 1, u(erreurs)
1666
1667 - def xmlrpc_get_dico(self,cred_user,id_serveur,mode='config',encode=False):
1668 """récupération du dictionnaire de configuration selon le mode demandé
1669 (gen_dico, gen_config, modification du fichier déjà rempli"""
1670 try:
1671 id_serveur = int(id_serveur)
1672 serv = self.parent.s_pool.get(cred_user, id_serveur)
1673 except (KeyError, ValueError):
1674 return 0, u("""Serveur inconnu : %s""" % str(id_serveur))
1675
1676 try:
1677 config_serv = serv.get_config(mode,encode)
1678 except Exception, e:
1679 return 0, u("""Erreur de lecture du dictionnaire : %s""" % str(e))
1680
1681 try:
1682 data = config_serv.get_dict()
1683 except Exception, e:
1684 return 0, u("""Erreur de lecture de la configuration : %s""" % str(e))
1685 return 1, u(data)
1686
1688 """renvoie un dictionnaire contenant la configuration du serveur demandé
1689 format {variable:valeur}"""
1690 try:
1691 id_serveur = int(id_serveur)
1692 serv = self.parent.s_pool.get(cred_user, id_serveur)
1693 except (KeyError, ValueError):
1694 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1695
1696 try:
1697 config_serv = serv.get_config('modif_config',encode)
1698 data = config_serv.parsedico()
1699 except Exception, e:
1700 return 0, u("""erreur de lecture du dictionnaire : %s""" % str(e))
1701
1702 return 1, u(data)
1703
1704 - def xmlrpc_save_conf(self,cred_user,id_serveur,dico_zeph,mode='config',encode=False):
1705 """sauvegarde d'un dictionnaire de configuration sur zephir
1706 (soit sur zephir.eol, soit sur dico.eol)"""
1707 try:
1708 id_serveur = int(id_serveur)
1709 serv = self.parent.s_pool.get(cred_user, id_serveur)
1710 except (KeyError, ValueError):
1711 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1712 try:
1713
1714 if mode.endswith('migration'):
1715
1716 variante = serv.variante_migration()
1717 assert int(variante) > 0
1718 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
1719 cursor=cx.cursor()
1720 cursor.execute("""select module from variantes where id=%s""", (int(variante),))
1721 var_mod=cursor.fetchone()[0]
1722 cursor.close()
1723 cx.close()
1724 d = serv.migrate_config(var_mod,variante,'modif_migration')
1725 else:
1726 d = serv.get_config('modif_config',encode)
1727
1728 d.init_from_zephir(dico_zeph)
1729 serv.save_config(d,mode,encode)
1730 except Exception, e:
1731 return 0,u(str(e))
1732 else:
1733 return 1,u('ok')
1734
1736 """sauvegarde d'un modèle de firewall
1737 """
1738 try:
1739 id_serveur = int(id_serveur)
1740 serv = self.parent.s_pool.get(cred_user, id_serveur)
1741 except (KeyError, ValueError):
1742 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1743 return self._save_bastion([serv],bastion_base64,'fichiers_zephir/modeles/%s.xml' % modele, encode)
1744
1746 """ récupère les informations sur les serveurs du groupe
1747 """
1748 query = """select serveurs from groupes_serveurs where id = %s"""
1749 return self.dbpool.runQuery(query, (int(groupe),)).addCallbacks(self._save_bastion_groupe,db_client_failed,callbackArgs=[cred_user,bastion_base64,modele,encode])
1750
1752 """sauvegarde d'un modèle de firewall sur un groupe de serveurs
1753 """
1754 try:
1755 serveurs=eval(data[0][0])
1756 except:
1757 return 0, u("impossible de retrouver les serveurs du groupe")
1758
1759 liste_serv = []
1760 for id_serveur in serveurs:
1761 try:
1762 serv = self.parent.s_pool.get(cred_user, int(id_serveur))
1763 except (KeyError, ValueError):
1764 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1765 if serv.get_module().startswith('amon'):
1766 liste_serv.append(serv)
1767 return self._save_bastion(liste_serv, bastion_base64, 'fichiers_zephir/modeles/%s.xml' % modele, encode)
1768
1769 - def _save_bastion(self,serveurs,fichier_base64,filename,encode):
1770 """sauvegarde d'un fichier dans l'arborescence d'un serveur"""
1771
1772 contenu = base64.decodestring(fichier_base64)
1773
1774 erreurs = []
1775 for serveur in serveurs:
1776
1777 serveur_dir = serveur.get_confdir()
1778
1779 try:
1780 d = serveur.get_config('modif_config',encode)
1781 try:
1782 if not os.path.isdir(serveur_dir+'/fichiers_zephir/modeles'):
1783 os.mkdir(serveur_dir+'/fichiers_zephir/modeles')
1784
1785
1786 modele=open(serveur_dir+'/fichiers_zephir/modeles'+os.sep+os.path.basename(filename),'w')
1787 modele.write(contenu)
1788 modele.close()
1789 except:
1790
1791 pass
1792 else:
1793
1794 d.get_var('type_amon')
1795 d.set_value(os.path.splitext(os.path.basename(filename))[0])
1796
1797 serveur.save_config(d,'modif_config',encode)
1798 except:
1799
1800 erreurs.append(str(serveur.id_s))
1801
1802
1803 try:
1804 f=open(serveur_dir+os.sep+'fichiers_zephir/fichiers_zephir')
1805 old_content=f.read()
1806 f.close()
1807 fichiers=old_content.split('%%\n')[0]
1808 rpms=old_content.split('%%\n')[1]
1809 except:
1810 fichiers=FILE_SECTION
1811 rpms=RPM_SECTION
1812
1813
1814 ligne = "/usr/share/eole/bastion/modeles"
1815 if ligne not in fichiers.split('\n'):
1816 fichiers = fichiers.strip() + '\n' + ligne +'\n'
1817 try:
1818 f=open(serveur_dir+os.sep+'fichiers_zephir/fichiers_zephir','w')
1819 f.write(fichiers+"%%\n"+rpms)
1820 f.close()
1821 except:
1822 erreur.append("ajout à la liste des fichiers zephir")
1823 if erreurs != []:
1824 return 0,u("""erreur de sauvegarde du fichier %s sur le(s) serveur(s) %s""" % (filename,",".join(erreurs)))
1825
1826 return 1,u('ok')
1827
1829 """récupération d'un modèle de firewall
1830 """
1831 try:
1832 id_serveur = int(id_serveur)
1833 serv = self.parent.s_pool.get(cred_user,id_serveur)
1834 except (KeyError, ValueError):
1835 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1836
1837 try:
1838 d = serv.get_config('modif_config',encode)
1839 modele=d.get_value('type_amon')
1840 if type(modele) == list:
1841 modele=modele[0]
1842 data_dir = os.path.join(serv.get_confdir(),'fichiers_zephir')
1843 model_files = [ os.path.join(data_dir, 'modeles/%s.xml' % modele),
1844 os.path.join(data_dir, '%s.xml' % modele),
1845 os.path.join(data_dir, 'variante/%s.xml' % modele)
1846 ]
1847 contenu = None
1848 for model_file in model_files:
1849 if os.path.isfile(model_file):
1850 fic_zephir = open(model_file)
1851 contenu = fic_zephir.read()
1852 fic_zephir.close()
1853 assert contenu is not None
1854 except:
1855 return 0,u("""fichier de modele non trouvé pour le serveur %s""" % serv.id_s)
1856 else:
1857 return 1,base64.encodestring(contenu),modele
1858
1859 - def xmlrpc_get_log(self,cred_user,id_serveur=None,mode='zlog',liste_types=[]):
1860 """rècupère les logs d'un serveur particulier
1861 mode : - zlog : tous les logs remontés par le serveur (ou spécifiés)
1862 - autre : récupère la liste des actions zephir effectuées sur ce serveur
1863 """
1864 params = []
1865 query = """select id,id_serveur,date,type,message,etat from log_serveur where """
1866 if id_serveur:
1867 query += """id_serveur=%s and"""
1868 params.append(int(id_serveur))
1869 if mode == 'zlog':
1870
1871 comp = ["<> 'COMMAND'"]
1872
1873 if liste_types != []:
1874 comp=[" in ('"]
1875 for typelog in liste_types:
1876 comp.append(typelog)
1877 comp.append("','")
1878 comp = comp[:-1]
1879 comp.append("')")
1880 else:
1881 comp = ["= 'COMMAND'"]
1882 query += """ type%s order by date desc, id desc""" % "".join(comp)
1883 return self.dbpool.runQuery(query, params).addCallbacks(self._got_log,db_client_failed,callbackArgs=[cred_user])
1884
1886 """supression des logs d'un certain type antérieurs à une certaine date
1887 Attention, cette purge est effectuée sur l'ensemble des serveurs du zephir !
1888 liste_serveurs : liste des serveurs dont on veut purger les logs
1889 liste_types : spécifie les types d'action à purger (ex : ['COMMAND','SURVEILLANCE','MAJ']
1890 """
1891
1892 cond_params = []
1893 if liste_types != []:
1894
1895 if 'TOUT' in liste_types:
1896 cond_types = ""
1897 else:
1898
1899 cond_liste = []
1900 for type_log in liste_types:
1901 cond_liste.append("type=%s")
1902 cond_params.append(type_log)
1903 cond_types = " and (" + " or ".join(cond_liste) + ")"
1904 else:
1905 return 0,u("paramètres invalides")
1906
1907 date = str(self.dbpool.dbapi.Timestamp(int(date[2]),int(date[1]),int(date[0]),0,0,0).adapted)
1908 for serveur in liste_serveurs:
1909
1910
1911 try:
1912 self.parent.s_pool.get(cred_user, int(serveur))
1913 except (KeyError, ValueError):
1914 return 0, u("""serveur inconnu : %s""" % str(serveur))
1915 if int(serveur) > 0 and type(date) == str and type(liste_types) == list:
1916 query = """delete from log_serveur where id_serveur=%s""" + cond_types + " and date <= %s"
1917 params = [int(serveur)]
1918 params.extend(cond_params)
1919 params.append(date)
1920 try:
1921
1922 self.dbpool.runOperation(query, params)
1923 except:
1924 pass
1925 else:
1926 return 0,u("paramètres invalides")
1927
1928 return 1,u("ok")
1929
1931 """retourne la liste des fichiers personnalisés pour ce serveur
1932 @param show_detail : ajoute une information pour chaque fichier de type fichiers divers (serveur et variante)
1933 types de fichiers dispos : missing, dir ou file
1934 """
1935 try:
1936 id_serveur = int(id_serveur)
1937 serv = self.parent.s_pool.get(cred_user,id_serveur)
1938 except (KeyError, ValueError):
1939 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
1940 else:
1941
1942 serveur_dir = serv.get_confdir()
1943
1944 dico_res={}
1945 try:
1946
1947 liste_dicos = []
1948 liste_dicos_var = []
1949 if serv.version == 'creole1':
1950 dico_dir = serveur_dir+os.sep+'dicos'
1951 else:
1952 dico_dir = serveur_dir+os.sep+'dicos/local'
1953 for fic in os.listdir(dico_dir):
1954 if fic == 'variante':
1955 pass
1956 elif fic.endswith('.eol') or fic.endswith('.xml'):
1957 liste_dicos.append(fic)
1958 dico_res['dicos'] = liste_dicos
1959 try:
1960
1961 for fic in os.listdir(serveur_dir+os.sep+'dicos/variante'):
1962 if fic.endswith('.eol') or fic.endswith('.xml'):
1963 liste_dicos_var.append(fic)
1964 dico_res['dicos_var'] = liste_dicos_var
1965 except OSError:
1966 dico_res['dicos_var'] = ['répertoire non trouvé !']
1967 except OSError:
1968 dico_res['dicos'] = ['répertoire non trouvé !']
1969 try:
1970
1971 dico_res['persos'] = os.listdir(serveur_dir+os.sep+'fichiers_perso')
1972 try:
1973 dico_res['persos'].remove('variante')
1974 except:
1975 pass
1976 except OSError:
1977 dico_res['persos'] = ['répertoire non trouvé !']
1978 try:
1979
1980 dico_res['persos_var'] = (os.listdir(serveur_dir+os.sep+'fichiers_perso/variante'))
1981 except OSError:
1982 dico_res['persos_var'] = ['répertoire non trouvé !']
1983 try:
1984
1985 dico_res['patchs'] = os.listdir(serveur_dir+os.sep+'patchs')
1986 try:
1987 dico_res['patchs'].remove('variante')
1988 except:
1989 pass
1990 except OSError:
1991 dico_res['patchs'] = ['répertoire non trouvé !']
1992 try:
1993
1994 dico_res['patchs_var'] = os.listdir(serveur_dir+os.sep+'patchs/variante')
1995 except OSError:
1996 dico_res['patchs_var'] = ['répertoire non trouvé !']
1997 try:
1998
1999
2000 fic = open(serveur_dir+'/fichiers_zephir/fichiers_zephir')
2001 data = fic.read().strip().split("\n")
2002 fic.close()
2003
2004 liste_pkg = []
2005 section_rpm = 0
2006 for ligne in data:
2007 ligne = ligne.strip()
2008 if section_rpm == 1:
2009
2010 if not ligne.startswith('#') and ligne != '':
2011
2012 liste_pkg.append(ligne)
2013 if ligne == '%%':
2014 section_rpm = 1
2015 dico_res['rpms'] = liste_pkg
2016 except IOError:
2017 dico_res['rpms'] = []
2018 try:
2019
2020
2021 fic = open(serveur_dir+'/fichiers_zephir/variante/fichiers_variante')
2022 data = fic.read().strip().split("\n")
2023 fic.close()
2024
2025 liste_pkg_var = []
2026 section_rpm = 0
2027 for ligne in data:
2028 ligne = ligne.strip()
2029 if section_rpm == 1:
2030
2031 if not ligne.startswith('#') and ligne != '':
2032
2033 liste_pkg_var.append(ligne)
2034 if ligne == '%%':
2035 section_rpm = 1
2036 dico_res['rpms_var'] = liste_pkg_var
2037 except IOError:
2038 dico_res['rpms_var'] = []
2039
2040 liste_fic=[]
2041
2042 try:
2043 f=open(serveur_dir+os.sep+'fichiers_zephir/fichiers_zephir')
2044 old_content=f.read()
2045 f.close()
2046 fichiers=old_content.split('%%\n')[0]
2047 except:
2048 fichiers=""
2049 for f in fichiers.split('\n'):
2050 if f.strip().startswith("""/"""):
2051 f_local = os.path.join(serveur_dir,'fichiers_zephir',os.path.basename(f.strip()))
2052 if show_details:
2053 f_info = config.get_file_info(f_local)
2054 liste_fic.append((f,f_info))
2055 elif os.path.exists(f_local):
2056 liste_fic.append(f)
2057 dico_res['fichiers_zeph'] = liste_fic
2058 liste_fic=[]
2059 try:
2060 f=open(serveur_dir+os.sep+'fichiers_zephir/variante/fichiers_variante')
2061 old_content=f.read()
2062 f.close()
2063 fichiers=old_content.split('%%\n')[0]
2064 except:
2065 fichiers=""
2066 for f in fichiers.split('\n'):
2067 if f.strip().startswith("/"):
2068 f_local = os.path.join(serveur_dir,'fichiers_zephir','variante',os.path.basename(f.strip()))
2069 if show_details:
2070 f_info = config.get_file_info(f_local)
2071 liste_fic.append((f,f_info))
2072 elif os.path.exists(f_local):
2073 liste_fic.append(f)
2074 dico_res['fichiers_var'] = liste_fic
2075
2076 return 1,u(dico_res)
2077
2079 """renvoie les informations de permissions associées à un fichier
2080 """
2081 try:
2082 id_serveur = int(id_serveur)
2083 serv = self.parent.s_pool.get(cred_user,id_serveur)
2084 except (KeyError, ValueError):
2085 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
2086 else:
2087 result = self.parent.s_pool.get_file_perms(serv.get_confdir(), filepath)
2088 return 1, u(result)
2089
2091 """renvoie les informations de permissions associées à un fichier
2092 """
2093 try:
2094 id_serveur = int(id_serveur)
2095 serv = self.parent.s_pool.get(cred_user,id_serveur)
2096 except (KeyError, ValueError):
2097 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
2098 else:
2099 result = self.parent.s_pool.del_file_perms(serv.get_confdir(), filepath)
2100 return 1, u(result)
2101
2103 """enregistre les informations de permissions associées à un(des) fichier(s)
2104 @param rights: dictionnaire au format suviant : {'filepath':[mode,ownership]}
2105 """
2106 try:
2107 id_serveur = int(id_serveur)
2108 serv = self.parent.s_pool.get(cred_user,id_serveur)
2109 except (KeyError, ValueError):
2110 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
2111 else:
2112 data_dir = serv.get_confdir()
2113 res = self.parent.s_pool.set_file_perms(rights, data_dir)
2114 if res:
2115 return 1,"OK"
2116 else:
2117 return 0, u("""erreur d'enregistrement des permissions""")
2118
2120 """copie les permissions définies sur le serveur id_src
2121 sur le groupe de serveurs serveurs
2122 @param keep: si True, on n'écrase pas les permissions restantes pour un fichier
2123 """
2124 try:
2125 id_src = int(id_src)
2126 src = self.parent.s_pool.get(cred_user,id_src)
2127
2128 perms = self.parent.s_pool.get_file_perms(src.get_confdir())
2129 except (KeyError, ValueError):
2130 return 0, u("""serveur inconnu : %s""" % str(id_src))
2131 else:
2132 forbidden = []
2133
2134 for id_dst in serveurs:
2135 try:
2136 id_dst = int(id_dst)
2137 dst = self.parent.s_pool.get(cred_user, id_dst)
2138 except:
2139 forbidden.append(id_dst)
2140 else:
2141 if id_dst != id_src:
2142
2143 existing = []
2144 if keep == True:
2145 existing = self.parent.s_pool.get_file_perms(dst.get_confdir()).keys()
2146
2147 updates = {}
2148 for ficperm, data in perms.items():
2149 if ficperm not in existing:
2150 updates[ficperm] = perms[ficperm]
2151
2152 self.parent.s_pool.set_file_perms(updates, dst.get_confdir())
2153
2154 return 1, u(forbidden)
2155
2157 """récupère l'etat général d'un ou plusieurs serveur(s)
2158 """
2159 if type(id_serveur) == list:
2160 results = []
2161 for id_serv in id_serveur:
2162 code, res = self._global_status(cred_user,id_serv)
2163 if code == 0:
2164 return code, res
2165 else:
2166 results.append(res)
2167 return 1, u(results)
2168 else:
2169 return self._global_status(cred_user,id_serveur)
2170
2172 """lit l'état d'un serveur dans la base
2173 """
2174 try:
2175 id_serveur = int(id_serveur)
2176 serv = self.parent.s_pool.get(cred_user,id_serveur)
2177 except (KeyError, ValueError):
2178 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
2179 etat = serv.get_status()
2180 if etat == None:
2181 return 1, -1
2182 if etat in [0,2]:
2183 return 1, 0
2184 else:
2185 return 1, etat
2186 return 0, u("""erreur de récupération des données""")
2187
2189 """renvoie les données de la dernière mesure des agents
2190 """
2191 if serveurs == None:
2192 serveurs = self.agent_manager.keys()
2193 elif type(serveurs) != list:
2194 serveurs = [serveurs]
2195 measures = []
2196 for id_serveur in serveurs:
2197 try:
2198 serv = self.parent.s_pool.get(cred_user,int(id_serveur))
2199 except (KeyError, ValueError):
2200
2201 pass
2202 if self.agent_manager[str(id_serveur)] != None:
2203 measures.append("%s:%s" % (str(id_serveur), str(self.agent_manager[str(id_serveur)].get_measure())))
2204
2205
2206 measures = "{" + ",".join(measures) + "}"
2207
2208 return 1, u(measures)
2209
2211 """récupère l'etat des agents d'un serveur
2212 """
2213 if type(id_serveur) == list:
2214 results = []
2215 for id_serv in id_serveur:
2216 try:
2217 code, res = self._agents_status(cred_user,id_serv)
2218 assert code == 1
2219 results.append(u(res))
2220 except:
2221 results.append({})
2222 return 1, results
2223 else:
2224 return self._agents_status(cred_user,id_serveur)
2225
2246
2247
2248
2249
2250
2252 """enregistre un groupe de serveurs dans la base
2253 """
2254 if self.parent.s_pool.add_groupe(cred_user, libelle, serveurs):
2255 return 1, "ok"
2256 else:
2257 return 0, u("erreur lors de l'insertion du groupe")
2258
2260 """supprime un groupe de serveurs de la base
2261 """
2262 try:
2263 id_groupe = int(id_groupe)
2264 self.parent.s_pool.del_groupe(cred_user, id_groupe)
2265 except (KeyError, ValueError):
2266 return 0, u("""id de groupe invalide : %s""" % str(id_groupe))
2267 return 1, "ok"
2268
2270 """modifie un groupe existant
2271 """
2272 try:
2273 id_groupe = int(id_groupe)
2274 self.parent.s_pool.edit_groupe(cred_user, id_groupe, libelle, serveurs)
2275 except (KeyError, ValueError):
2276 return 0, u("""id de groupe invalide : %s""" % str(id_groupe))
2277 return 1, "ok"
2278
2280 """récupère un ou plusieur groupe de serveurs dans la base
2281 """
2282 try:
2283 liste_gr = self.parent.s_pool.get_groupes(cred_user, id_groupe)
2284 except (KeyError, ValueError):
2285 return 0, u("""id de groupe invalide : %s""" % str(id_groupe))
2286 return 1, u(liste_gr)
2287
2289 """autorise la connexion ssh par clé pour un utilisateur
2290 """
2291 query="""select login from users where login = %s"""
2292 return self.dbpool.runQuery(query, (username,)).addCallbacks(self._authorize_user, db_client_failed, callbackArgs=[username, serveurs])
2293
2295 try:
2296 user = data[0][0]
2297 except:
2298 return 0, u("L'utilisateur %s est inconnu" % username)
2299 for serveur in serveurs:
2300 query="""insert into serveur_auth values (%s,E%s)"""
2301 self.dbpool.runOperation(query, (int(serveur), user)).addErrback(db_client_failed)
2302 return 1, u('ok')
2303
2305 """enlève la connexion ssh par clé pour un utilisateur
2306 """
2307 liste=[int(i) for i in serveurs]
2308 query="""delete from serveur_auth where login=%s and (id_serveur=""" + " or id_serveur=".join(["%s" for serv in liste]) + ")"
2309 params = [username]
2310 params.extend(liste)
2311 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,'ok'], db_client_failed)
2312
2314 """liste des tags de procédures interdites pour un serveur
2315 """
2316 if serveur is None:
2317 query = """select tag,libelle from procedures"""
2318 return self.dbpool.runQuery(query).addCallbacks(self._get_locks, db_client_failed)
2319 else:
2320 query = """select lock_serveur.tag,libelle from lock_serveur,procedures where lock_serveur.tag=procedures.tag and id_serveur=%s"""
2321 return self.dbpool.runQuery(query, (int(serveur),)).addCallbacks(self._get_locks, db_client_failed)
2322
2324 """formatte la sortie pour la recherche des fonctions lockées"""
2325 locks=[]
2326 for tag in data:
2327 locks.append([tag[0],tag[1]])
2328 return 1, u(locks)
2329
2331 """interdit un type de procédure sur un ensemble de serveurs
2332 tags : liste des tags à interdire
2333 """
2334 if type(serveurs) != list:
2335
2336 serveurs=[serveurs]
2337 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
2338 cursor=cx.cursor()
2339 erreur= ""
2340 for serveur in serveurs:
2341 try:
2342 id_serveur = int(serveur)
2343 serv = self.parent.s_pool.get(cred_user,id_serveur)
2344 except (KeyError, ValueError):
2345 erreur = """serveur %s non retrouvé""" % str(serveur)
2346 try:
2347
2348 if len(notags) > 0:
2349 cursor.executemany("delete from lock_serveur where id_serveur=%s and tag=%s", [(serveur, tag) for tag in notags])
2350
2351 query = "insert into lock_serveur (id_serveur,tag) values (%s,%s)"
2352 cursor.executemany(query, [(serveur, tag) for tag in tags])
2353 except Exception,e:
2354 erreur = """erreur de mise à jour des locks : serveur %s""" % (str(serveur))
2355
2356 if erreur != "":
2357 cx.rollback()
2358 cx.close()
2359 return 0, u(erreur)
2360
2361 cursor.close()
2362 cx.commit()
2363 cx.close()
2364 return 1, 'OK'
2365
2367 """récupère le délai de connexion des serveurs (en secondes)
2368 """
2369 try:
2370 id_serveur = int(id_serveur)
2371 serv = self.parent.s_pool.get(cred_user,id_serveur)
2372 except (KeyError, ValueError):
2373 return 0, u("""serveur inconnu : %s""" % str(id_serveur))
2374 try:
2375 timeout = serv.get_timeout()
2376 except:
2377 return 0, "erreur de récupération du timeout"
2378 return 1, timeout
2379
2392