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