Package zephir :: Package backend :: Module serveurs_rpc
[hide private]
[frames] | no frames]

Source Code for Module zephir.backend.serveurs_rpc

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