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