Package zephir :: Package backend :: Module uucp_rpc
[frames] | no frames]

Source Code for Module zephir.backend.uucp_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  # uucp_rpc.py 
   9  # 
  10  # fonctions xmlrpc pour la gestion des actions sur les serveurs dans Zephir 
  11  # 
  12  ########################################################################### 
  13  """Module gérant les actions sur les serveurs (via uucp) 
  14  """ 
  15  from zephir.backend.db_utils import * 
  16  from zephir.backend.uucp_utils import uucp_pool, UUCPError, COMMANDS 
  17  from zephir.backend import config 
  18  from zephir.backend.config import u, log 
  19  from zephir.backend.xmlrpceole import XMLRPCEole as XMLRPC 
  20  from zephir.backend.lib_backend import AptChecker 
  21  from zephir.monitor.collecteur import AgentCollecteur, ServeurStatus 
  22  from zephir.lib_zephir import save_modes 
  23  from twisted.internet import defer, reactor, threads 
  24   
  25  import sys,os,shutil,time,smtplib,re,time,base64,glob,email 
  26  from email.header import Header 
  27  from datetime import datetime 
  28  import traceback 
  29  import psycopg2 as PgSQL 
  30  from cStringIO import StringIO 
  31   
32 -class RPCUucp(XMLRPC):
33 """serveur XMLRPC zephir pour la gestion des actions sur les serveurs 34 """ 35
36 - def __init__(self,parent,agent_manager):
37 self.dbpool = db_connect() 38 self.dbpool.noisy = 0 39 XMLRPC.__init__(self) 40 self.agent_manager = agent_manager 41 self.parent=parent 42 # booléen pour empêcher le lancement de plusieurs boucles 43 # de vérification des timeouts 44 self.scan_delay = config.SCAN_DELAY 45 # au lancement, on modifie la date de dernier contact 46 # des serveurs pour éviter des alertes injustifiées 47 self.start_time = str(time.time())
48
49 - def _send_files(self,serv,archive,files,uucp=0):
50 """met en queue des fichiers ou répertoires pour un serveur distant 51 et stocke la somme md5 des fichiers envoyés dans le fichier cheksum.txt du 52 systeme en question (dans zephir/conf/rne/serveur/)""" 53 # définition du nodename uucp du système 54 id_uucp = str(serv.get_rne())+'-'+str(serv.id_s) 55 # chemin vers les fichiers du serveur sur zephir 56 serveur_dir = serv.get_confdir() 57 cmd_tar = ['cd ',serveur_dir,';','/bin/tar','--same-owner','-chpf',archive+'.tar'] 58 # création du fichier tar à envoyer 59 for fic in files: 60 # on vérifie l'existence du fichier 61 if os.path.exists(os.path.join(serveur_dir,fic)): 62 cmd_tar.append(fic) 63 else: 64 # cas spécial : lien sur dico.eol, zephir.eol, droits_zephir et droits_variante (si conf pas encore saisie) 65 if fic not in ['dico.eol','zephir.eol', 'droits_variante', 'droits_zephir']: 66 # un fichier n'est pas trouvé, on annule 67 return 0, u("""fichier %s introuvable""" % os.path.join(serveur_dir,fic) ) 68 cmd_tar.append('>/dev/null 2>&1') 69 res=os.system(" ".join(cmd_tar)) 70 if res != 0: 71 return 0, u("""erreur de creation de l'archive %s.tar dans %s""" % (archive,serveur_dir)) 72 # calcul et stockage d'un checksum md5 de l'archive 73 cmd_checksum = """cd %s ;md5sum -b %s.tar > %s.md5""" % (serveur_dir,archive,archive) 74 os.system(cmd_checksum) 75 if uucp: 76 # envoi de l'archive par uucp si demandé 77 try: 78 res = uucp_pool.add_file(id_uucp,os.path.join(serveur_dir,archive+".tar")) 79 except UUCPError,e: 80 return 0, u("Erreur UUCP %s" % str(e)) 81 return 1,u(archive+'.tar')
82
83 - def xmlrpc_reconfigure(self,cred_user,id_serveur,delay=0):
84 """prépare la reconfiguration d'un serveur""" 85 try: 86 id_serveur = int(id_serveur) 87 serv = self.parent.s_pool.get(cred_user,id_serveur) 88 except (KeyError, ValueError): 89 return 0, u("serveur inconnu dans la base zephir") 90 else: 91 if delay != 0: 92 delay_opt = " %s" % str(delay) 93 else: 94 delay_opt = "" 95 id_uucp = str(serv.get_rne())+'-'+str(id_serveur) 96 try: 97 res = uucp_pool.add_cmd(id_uucp,"zephir_client reconfigure%s" % delay_opt) 98 except UUCPError,e: 99 return 0, u("Erreur UUCP %s" % str(e)) 100 return 1, u('ok')
101
102 - def xmlrpc_service_restart_groupe(self,cred_user,liste,service, delay=0):
103 """prépare le redémarrage d'un service sur un groupe""" 104 erreurs=[] 105 old_clients=[] 106 for serveur in liste: 107 new_cli = False 108 if delay: 109 try: 110 id_serveur = int(serveur['id']) 111 serv = self.parent.s_pool.get(cred_user, id_serveur) 112 new_cli = serv.check_min_version(self.parent.maj_checker, 'zephir-client', '2.3-eole54~1') 113 except (KeyError, ValueError): 114 return 0, u("serveur inconnu dans la base zephir") 115 if new_cli: 116 # si un délai est demandé on n'applique pas l'action aux serveurs non compatibles 117 retour = self.xmlrpc_service_restart(cred_user, serveur['id'], service, delay) 118 else: 119 retour = (1, "ok") 120 old_clients.append(id_serveur) 121 else: 122 retour = self.xmlrpc_service_restart(cred_user, serveur['id'], service, delay) 123 if retour[0] == 0: 124 erreurs.append(str(serveur['id'])+' : '+retour[1]) 125 if erreurs != []: 126 return 0, u(erreurs) 127 else: 128 return 1, u(old_clients)
129
130 - def xmlrpc_service_restart(self,cred_user,id_serveur,service, delay=0):
131 """exécution de la commande uucp pour redémarrer un service""" 132 try: 133 id_serveur = int(id_serveur) 134 serv = self.parent.s_pool.get(cred_user, id_serveur) 135 except (KeyError, ValueError): 136 return 0, u("serveur inconnu dans la base zephir") 137 else: 138 if delay != 0: 139 delay_opt = " %s" % str(delay) 140 else: 141 delay_opt = "" 142 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur) 143 # appel uucp 144 try: 145 uucp_pool.add_cmd(id_uucp,"zephir_client service_restart %s%s" % (service, delay_opt)) 146 except UUCPError,e: 147 return 0, u("erreur uucp (%s)" % str(e)) 148 return 1,u("ok")
149
150 - def xmlrpc_reboot_groupe(self,cred_user,liste, delay=0):
151 """prépare le redémarrage d'un groupe de serveurs""" 152 erreurs=[] 153 for serveur in liste: 154 retour = self.xmlrpc_reboot(cred_user, serveur['id'], delay) 155 if retour[0] == 0: 156 erreurs.append(str(serveur['id'])+' : '+retour[1]) 157 if erreurs != []: 158 return 0, u(erreurs) 159 else: 160 return 1, u('ok')
161
162 - def xmlrpc_reboot(self,cred_user,id_serveur, delay=0):
163 """exécution de la commande uucp pour redémarrer un serveur""" 164 try: 165 id_serveur = int(id_serveur) 166 serv = self.parent.s_pool.get(cred_user, id_serveur) 167 except (KeyError, ValueError): 168 return 0, u("serveur inconnu dans la base zephir") 169 else: 170 if delay != 0: 171 delay_opt = " %s" % str(delay) 172 else: 173 delay_opt = "" 174 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur) 175 # appel uucp 176 try: 177 uucp_pool.add_cmd(id_uucp,"zephir_client reboot%s" % delay_opt) 178 except UUCPError,e: 179 return 0, u("serveur %s : erreur uucp (%s)" % (str(id_serveur), str(e))) 180 return 1,u("ok")
181 182
183 - def xmlrpc_configure(self,cred_user,id_serveur,restart=0,content=0):
184 """prépare la configuration automatique d'un serveur 185 (envoi des fichiers de configuration)""" 186 187 return self._configure(id_serveur, restart, cred_user, content)
188
189 - def xmlrpc_configure_groupe(self,cred_user,liste,restart=0,content=0):
190 """prépare la configuration automatique d'un groupe de serveurs 191 (envoi des fichiers de configuration)""" 192 erreurs = [] 193 old_clients = [] 194 for serveur in liste: 195 retour = self._configure(serveur['id'], restart, cred_user, content) 196 if retour[0] == 0: 197 erreurs.append(str(serveur['id'])+' : '+retour[1]) 198 else: 199 old_clients.extend(retour[1]) 200 if erreurs != []: 201 return 0, u(erreurs) 202 else: 203 return 1, u(old_clients)
204
205 - def _configure(self, id_serveur,restart,cred_user,content):
206 """envoie les fichiers de configuration et demande un configure-zephir""" 207 try: 208 id_serveur = int(id_serveur) 209 serv = self.parent.s_pool.get(cred_user, id_serveur) 210 except (KeyError, ValueError): 211 return 0, u("serveur inconnu dans la base zephir") 212 query = """select users.cle from users,serveur_auth where users.login=serveur_auth.login and serveur_auth.id_serveur=%s""" 213 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD) 214 cursor=cx.cursor() 215 cursor.execute(query, (int(id_serveur),)) 216 data=cursor.fetchall() 217 cursor.close() 218 cx.close() 219 id_uucp = str(serv.get_rne())+'-'+str(id_serveur) 220 # définition du répertoire du serveur 221 serveur_dir = serv.get_confdir() 222 # définition des fichiers à transférer 223 try: 224 cles = "" 225 # on prépare le fichier des clefs ssh à transférer 226 for cle in data: 227 if cle[0]: 228 cles += base64.decodestring(cle[0]) + "\n" 229 cles.strip() 230 fic_cle = open(serveur_dir+os.sep+'auth_keys','w') 231 fic_cle.writelines(base64.encodestring(cles)) 232 fic_cle.close() 233 except: 234 return 0, u("erreur de création du fichier des cles de connexion ssh") 235 old_clients = [] 236 # si le client présent sur le serveur n'est pas assez récent, on fait une sauvegarde complète 237 files = ['dicos','patchs','fichiers_perso','fichiers_zephir','zephir.eol','dico.eol','auth_keys','droits_zephir', 'droits_variante'] 238 if serv.version != 'creole1' and serv.check_min_version(self.parent.maj_checker, 'zephir-client', '2.2-eole97'): 239 # envoi partiel 240 if content not in config.data_files: 241 return 0, u("le type de données à envoyer est invalide") 242 files = config.data_files[content][1] 243 else: 244 # client trop ancien : envoi de toutes les données 245 old_clients = [id_serveur] 246 if 'fichiers_zephir' in files: 247 if self.parent.dictpool.check_module(serv.id_mod): 248 # synchronisation des paquets de dictionnaires avant envoi 249 self.parent.dictpool.sync_serveur_packages(serv.id_s) 250 # appel de la fonction d'envoi et de calcul des md5 251 code, message = self._send_files(serv,'config-zephir',files,uucp=1) 252 try: 253 os.unlink('auth_keys') 254 except: 255 pass 256 if code == 0: 257 return code, u(message) 258 else: 259 # les fichiers sont prêts à l'envoi, on demande un 260 # configure sur le serveur distant 261 try: 262 res = uucp_pool.add_cmd(id_uucp,"zephir_client configure") 263 except UUCPError, e: 264 return 0, u("Erreur uucp : %s" % str(e)) 265 if restart == 1: 266 # on demande un reconfigure 267 code, data = self.xmlrpc_reconfigure(cred_user, id_serveur) 268 if code == 1: 269 return 1, u(old_clients) 270 else: 271 return code, data 272 else: 273 return 1, u(old_clients)
274
275 - def xmlrpc_save_conf(self,cred_user,id_serveur,mode=0):
276 """prépare la sauvegarde de configuration d'un serveur""" 277 # on vérifie l'existence du serveur dans la base 278 return self._save_conf(cred_user, id_serveur, mode)
279
280 - def xmlrpc_save_conf_groupe(self,cred_user,liste,mode=0):
281 """prépare la sauvegarde de configuration d'un serveur""" 282 erreurs=[] 283 old_clients = [] 284 for serveur in liste: 285 retour = self._save_conf(cred_user, serveur['id'], mode) 286 if retour[0] == 0: 287 erreurs.append(str(serveur['id'])+' : '+retour[1]) 288 else: 289 old_clients.extend(retour[1]) 290 if erreurs != []: 291 return 0, u(erreurs) 292 else: 293 return 1, u(old_clients)
294
295 - def _save_conf(self,cred_user,id_serveur,mode):
296 """exécution de la commande uucp pour la mise à jour""" 297 try: 298 id_serveur = int(id_serveur) 299 serv = self.parent.s_pool.get(cred_user, id_serveur) 300 except (KeyError, ValueError): 301 return 0, u("serveur inconnu dans la base zephir") 302 else: 303 old_clients = [] 304 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur) 305 # appel uucp 306 # vérification du mode demandé 307 cmd_mode = "" 308 if serv.version != 'creole1' and mode in save_modes: 309 # pour éviter les problèmes avec d'anciens clients, on ne passe pas 310 # le mode si le client n'est pas assez récent 311 if serv.check_min_version(self.parent.maj_checker, 'zephir-client', '2.2-eole97'): 312 cmd_mode = " %s" % str(mode) 313 else: 314 old_clients.append(id_serveur) 315 try: 316 uucp_pool.add_cmd(id_uucp,"zephir_client save_files%s" % cmd_mode) 317 except UUCPError,e: 318 return 0, u("erreur uucp (%s)" % str(e)) 319 return 1, (old_clients)
320
321 - def xmlrpc_maj(self,cred_user,id_serveur,reconf = 0, delay = "", options = ""):
322 """prépare la mise à jour d'un serveur Eole par l'intermédiare d'uucp""" 323 # on vérifie l'existence du serveur dans la base 324 if delay > 0: 325 # mise à jour différée : reconfigure est géré par la mise à jour ead 326 reconf = 0 327 return self._maj(cred_user, id_serveur, reconf, delay, options)
328
329 - def xmlrpc_maj_groupe(self,cred_user,liste,reconf = 0, delay = "", options = ""):
330 """prépare la mise à jour d'un groupe de serveurs Eole par l'intermédiare d'uucp""" 331 erreurs=[] 332 for serveur in liste: 333 retour = self._maj(cred_user, serveur['id'],reconf,delay,options) 334 if retour[0] == 0: 335 erreurs.append("serveur "+str(serveur['id'])+' : '+retour[1]) 336 if erreurs != []: 337 return 0, u(erreurs) 338 else: 339 return 1, u('ok')
340
341 - def _maj(self, cred_user, id_serveur, reconf, delay,options):
342 """exécution de la commande uucp pour la mise à jour""" 343 try: 344 id_serveur = int(id_serveur) 345 serv = self.parent.s_pool.get(cred_user,id_serveur) 346 except (KeyError, ValueError): 347 return 0, u("serveur inconnu dans la base zephir") 348 else: 349 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur) 350 # construction de la commande 351 try: 352 assert int(delay) > 0 353 # si delai, on ne lance pas reconfigure par une action (lancé par la maj différée) 354 reconf = 0 355 except: 356 delay = "" 357 try: 358 if serv.version == 'creole1': 359 uucp_pool.add_cmd(id_uucp,"zephir_client maj_auto %s" % (str(delay))) 360 else: 361 uucp_pool.add_cmd(id_uucp,"zephir_client maj_auto %s %s" % (str(delay), options)) 362 except UUCPError, e: 363 return 0, u("Erreur UUCP (%s)" % str(e)) 364 # si cela est demandé, on reconfigure le serveur 365 # query = """insert into log_serveur (id_serveur,date,type,message,etat) values (%s,'%s','%s','Mise a jour',0)""" % (int(id_serveur),str(time.ctime()),'COMMAND') 366 # self.dbpool.runOperation(query) 367 if reconf == 1: 368 return self.xmlrpc_reconfigure(cred_user, id_serveur) 369 else: 370 return 1, u("ok")
371
372 - def xmlrpc_maj_client(self,cred_user,id_serveur):
373 """prépare la mise à jour de zephir-client sur un serveur""" 374 # on vérifie l'existence du serveur dans la base 375 return self._maj_client(cred_user, id_serveur)
376
377 - def xmlrpc_maj_client_groupe(self,cred_user,liste):
378 """prépare la mise à jour de zephir-client sur un groupe de serveurs""" 379 erreurs=[] 380 for serveur in liste: 381 retour = self._maj_client(cred_user, serveur['id']) 382 if retour[0] == 0: 383 erreurs.append("serveur "+str(serveur['id'])+' : '+retour[1]) 384 if erreurs != []: 385 return 0, u(erreurs) 386 else: 387 return 1, u('ok')
388
389 - def _maj_client(self,cred_user,id_serveur):
390 """exécution de la commande uucp pour la mise à jour de zephir-client""" 391 try: 392 id_serveur = int(id_serveur) 393 serv = self.parent.s_pool.get(cred_user,id_serveur) 394 except (KeyError, ValueError): 395 return 0, u("serveur inconnu dans la base zephir") 396 else: 397 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur) 398 # construction de la commande 399 try: 400 uucp_pool.add_cmd(id_uucp,"zephir_client maj_client") 401 except UUCPError, e: 402 return 0, u("Erreur UUCP (%s)" % str(e)) 403 else: 404 return 1, u("ok")
405
406 - def xmlrpc_sphynx_add(self,cred_user,id_sphynx,id_amon,content):
407 """stocke la configuration RVP d'un amon vers ce sphynx""" 408 try: 409 id_sphynx = int(id_sphynx) 410 id_amon = int(id_amon) 411 sphynx = self.parent.s_pool.get(cred_user,id_sphynx) 412 amon = self.parent.s_pool.get(cred_user,id_amon) 413 except (KeyError, ValueError): 414 return 0, u("serveur inconnu dans la base zephir") 415 # on regarde si ce tunnel existe déjà 416 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD) 417 cursor=cx.cursor() 418 query = """select id_amon from conf_vpn where id_sphynx=%s""" 419 cursor.execute(query, (int(id_sphynx),)) 420 data=cursor.fetchall() 421 cursor.close() 422 cx.close() 423 # chemin de sauvegarde de l'archive contenant la conf RVP 424 sphynx_dir = sphynx.get_confdir() 425 if not os.path.exists(sphynx_dir + os.sep + 'vpn'): 426 os.makedirs(sphynx_dir + os.sep + 'vpn') 427 archive = sphynx_dir + os.sep + 'vpn' + os.sep + str(id_amon) + '.tar.gz' 428 # mise à jour de la table des tunnels configurés 429 confs = [ligne[0] for ligne in data] 430 if int(id_amon) in confs: 431 # on a déjà une conf vpn pour cet amon, mise à jour 432 query = """update conf_vpn set etat=%s where id_sphynx=%s and id_amon=%s""" 433 params = (0, int(id_sphynx), int(id_amon)) 434 else: 435 # sinon, insertion 436 query = """insert into conf_vpn (id_sphynx,id_amon,etat) values (%s,%s,%s)""" 437 params = (int(id_sphynx), int(id_amon), 0) 438 return self.dbpool.runOperation(query, params).addCallbacks(self._sphynx_add,db_client_failed,callbackArgs=[archive,content])
439
440 - def _sphynx_add(self,result,archive,content):
441 """écriture de la conf RVP""" 442 try: 443 file = StringIO() 444 data = base64.decodestring(content) 445 fd = open(archive,'wb') 446 # sauvegarde du fichier 447 file.write(data) 448 file.seek(0) 449 fd.write(file.read()) 450 fd.close() 451 except: 452 return 0, u("erreur de sauvegarde de l'archive") 453 return 1, "OK"
454
455 - def xmlrpc_sphynx_del(self,cred_user,id_sphynx,id_amon,del_row=0):
456 """supprime la configuration RVP d'un amon vers ce sphynx""" 457 try: 458 id_sphynx = int(id_sphynx) 459 id_amon = int(id_amon) 460 sphynx = self.parent.s_pool.get(cred_user,id_sphynx) 461 amon = self.parent.s_pool.get(cred_user,id_amon) 462 except (KeyError, ValueError): 463 return 0, u("serveur inconnu dans la base zephir") 464 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD) 465 cursor=cx.cursor() 466 query = """select etat from conf_vpn where id_sphynx=%s and id_amon=%s""" 467 params = (int(id_sphynx), int(id_amon)) 468 cursor.execute(query, params) 469 data=cursor.fetchone() 470 etat = data[0] 471 cursor.close() 472 cx.close() 473 try: 474 # chemin de l'archive contenant la conf RVP 475 sphynx_dir = sphynx.get_confdir() 476 archive = sphynx_dir + os.sep + 'vpn' + os.sep + str(id_amon) + '.tar.gz' 477 os.unlink(archive) 478 except: 479 if del_row == 0: 480 return 0, u("fichier de configuration RVP non supprimé (ou inexistant)") 481 if del_row == 1: 482 query = """delete from conf_vpn where id_sphynx=%s and id_amon=%s""" 483 params = (int(id_sphynx), int(id_amon)) 484 else: 485 nouv_etat=2 486 # si l'archive n'a pas été récupérée : anomalie 487 if int(etat) == 0: 488 nouv_etat=3 489 query = """update conf_vpn set etat=%s where id_sphynx=%s and id_amon=%s""" 490 params = (int(nouv_etat), int(id_sphynx), int(id_amon)) 491 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,u("OK")],db_client_failed)
492
493 - def xmlrpc_sphynx_get(self,cred_user,id_sphynx,id_amon):
494 """envoie la configuration RVP d'un amon vers ce sphynx""" 495 try: 496 id_sphynx = int(id_sphynx) 497 id_amon = int(id_amon) 498 sphynx = self.parent.s_pool.get(cred_user,id_sphynx) 499 amon = self.parent.s_pool.get(cred_user,id_amon) 500 except (KeyError, ValueError): 501 return 0, u("serveur inconnu dans la base zephir") 502 try: 503 # chemin de l'archive contenant la conf RVP 504 sphynx_dir = sphynx.get_confdir() 505 archive = sphynx_dir + os.sep + 'vpn' + os.sep + str(id_amon) + '.tar.gz' 506 file_conf=open(archive) 507 content=base64.encodestring(file_conf.read()) 508 file_conf.close() 509 except: 510 return 0, u("fichier de configuration RVP non trouvé") 511 query = """update conf_vpn set etat=1 where id_sphynx=%s and id_amon=%s""" 512 params = (int(id_sphynx), int(id_amon)) 513 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,content],db_client_failed)
514
515 - def xmlrpc_sphynx_list(self,cred_user,id_sphynx):
516 """liste les configs RVP amon présentes pour un sphynx""" 517 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD) 518 cursor=cx.cursor() 519 query = """select id_amon,etat from conf_vpn where id_sphynx=%s order by etat,id_amon desc""" % id_sphynx 520 cursor.execute(query, (int(id_sphynx),)) 521 data=cursor.fetchall() 522 cursor.close() 523 cx.close() 524 # on retourne l'id amon et son état 525 liste_amons=[] 526 for ligne in data: 527 liste_amons.append([int(ligne[0]),int(ligne[1])]) 528 return 1,liste_amons
529
530 - def xmlrpc_add_replication(self, cred_user, id_serv, id_client, content):
531 """ajoute un fichier de configuration pour réplication d'un annuaire sur seshat (ou autre)""" 532 try: 533 id_serv = int(id_serv) 534 id_client = int(id_client) 535 serv = self.parent.s_pool.get(cred_user,id_serv) 536 client = self.parent.s_pool.get(cred_user,id_client) 537 except (KeyError, ValueError): 538 return 0, u("serveur inconnu dans la base zephir") 539 try: 540 rne = client.parsedico()['numero_etab'] 541 assert rne != "" 542 except: 543 # si pas défini dans la configuration, on prend le rne 544 # de l'établissement du serveur dans la base zephir 545 rne = client.rne 546 code, message = serv.add_replication(rne, content, id_client) 547 if code == 0: 548 return code, message 549 else: 550 # configuration ajoutée, on demande automatiquement 551 # une prise en compte sur le serveur de réplication 552 return self._update_replication(serv)
553
554 - def xmlrpc_del_replication(self, cred_user, id_serv, conf_file):
555 """supprime un fichier de configuration de réplication""" 556 try: 557 id_serv = int(id_serv) 558 serv = self.parent.s_pool.get(cred_user,id_serv) 559 except (KeyError, ValueError): 560 return 0, u("serveur inconnu dans la base zephir") 561 return serv.del_replication(conf_file)
562
563 - def xmlrpc_update_replication(self, cred_user, id_serveur):
564 """prépare l'envoi des configurations de réplication à un serveur central, 565 et demande une regénération de la configuration 566 """ 567 try: 568 id_serveur = int(id_serveur) 569 serv = self.parent.s_pool.get(cred_user,id_serveur) 570 except (KeyError, ValueError): 571 return 0, u("serveur inconnu dans la base zephir") 572 # on effectue une mise à jour des informations sur les établissements répliqués 573 # (infos utilisées par eole-sso et par le service dispatcher) 574 try: 575 self.parent.s_pool.check_replication_infos(id_serveur) 576 except: 577 traceback.print_exc() 578 log.msg('Erreur de mise à jour du fichier etabs.ini') 579 return self._update_replication(serv)
580
581 - def _update_replication(self, serv):
582 # définition du répertoire du serveur 583 id_uucp = '%s-%s' % (str(serv.get_rne()), str(serv.id_s)) 584 code, message = self._send_files(serv, 'replication', ['replication'], uucp=1) 585 if code == 0: 586 return code, u(message) 587 else: 588 # les fichiers sont prêts à l'envoi, on demande la prise en compte sur le serveur seshat 589 try: 590 res = uucp_pool.add_cmd(id_uucp, "zephir_client update_replication") 591 except UUCPError, e: 592 return 0, u("Erreur uucp : %s" % str(e)) 593 if os.path.isfile(os.path.join(serv.get_confdir(), 'replication', '.modified')): 594 os.unlink(os.path.join(serv.get_confdir(), 'replication', '.modified')) 595 return 1, "OK"
596
597 - def xmlrpc_get_replication_info(self, cred_user, id_serveur):
598 try: 599 id_serveur = int(id_serveur) 600 serv = self.parent.s_pool.get(cred_user,id_serveur) 601 except (KeyError, ValueError): 602 return 0, u("serveur inconnu dans la base zephir") 603 # on force une vérification du fichier etabs.ini avant l'envoi 604 try: 605 self.parent.s_pool.check_replication_infos(id_serveur) 606 except: 607 traceback.print_exc() 608 return 0, u('Erreur de mise à jour du fichier etabs.ini') 609 # lecture du fichier et envoi des informations 610 try: 611 data_etab = serv.get_replication_infos() 612 except: 613 return 0, u('Erreur de lecture du fichier etabs.ini') 614 return 1, base64.encodestring(data_etab)
615 616
617 - def xmlrpc_check_replication(self, cred_user, id_serveur):
618 """renvoie l'état de la configuration de réplication LDAP 619 0 : pas de réplication gérée sur ce serveur 620 1 : configurations de réplication en place 621 2 : la configuration doit être renvoyée au serveur (si suppression manuelle de fichiers) 622 """ 623 try: 624 id_serveur = int(id_serveur) 625 serv = self.parent.s_pool.get(cred_user,id_serveur) 626 except (KeyError, ValueError): 627 return 0, u("serveur inconnu dans la base zephir") 628 return serv.check_replication()
629
630 - def xmlrpc_get_replication(self, cred_user, id_serveur):
631 """renvoie la liste des configurations de réplication présentes sur un serveur 632 """ 633 try: 634 id_serveur = int(id_serveur) 635 serv = self.parent.s_pool.get(cred_user,id_serveur) 636 except (KeyError, ValueError): 637 return 0, u("serveur inconnu dans la base zephir") 638 return serv.get_replication()
639
640 - def xmlrpc_confirm_transfer(self,cred_user,id_serveur,archive):
641 """confirme la réception d'une archive par un serveur""" 642 try: 643 id_serveur = int(id_serveur) 644 serv = self.parent.s_pool.get(cred_user,id_serveur) 645 except (KeyError, ValueError): 646 return 0, u("serveur inconnu dans la base zephir") 647 # définition du répertoire du serveur 648 serveur_dir = serv.get_confdir() 649 try: 650 # suppression de l'archive 651 os.unlink(serveur_dir+os.sep+archive+'.tar') 652 # supression du fichier de checksum 653 os.unlink(serveur_dir+os.sep+archive+'.md5') 654 except: 655 return 0, u("""erreur de suppression de l'archive""") 656 else: 657 return 1, u('ok')
658
659 - def xmlrpc_get_checksum(self,cred_user,id_serveur,archive):
660 """confirme la réception d'une archive par un serveur""" 661 try: 662 id_serveur = int(id_serveur) 663 serv = self.parent.s_pool.get(cred_user,id_serveur) 664 except (KeyError, ValueError): 665 return 0, u("serveur inconnu dans la base zephir") 666 # définition du répertoire du serveur 667 serveur_dir = serv.get_confdir() 668 # lecture du fichier md5 669 try: 670 fic_md5=open(serveur_dir+os.sep+archive+'.md5') 671 md5sum = fic_md5.readlines() 672 fic_md5.close() 673 except: 674 return 0, u("""fichier %s.md5 non trouve""" % (archive)) 675 else: 676 # ok, on renvoie la chaine de contrôle 677 return 1, base64.encodestring(md5sum[0])
678
679 - def xmlrpc_install_module(self,cred_user,id_module,dico_b64):
680 """installation d'un module (récupération d'un dictionnaire)""" 681 # pour l'instant, cette procédure sert à créer ou 682 # mettre à jour le dictionnaire principal du module 683 # on récupère le libellé du module dans la base 684 query = """select id, libelle, version from modules where id=%s""" % id_module 685 return self.dbpool.runQuery(query, (int(id_module),)).addCallbacks(self._install_module,db_client_failed,callbackArgs=[dico_b64])
686
687 - def _install_module(self,data,dico_b64):
688 if data == []: 689 return 0, u("""erreur, module non trouvé""") 690 else: 691 id_module = data[0][0] 692 libelle = data[0][1] 693 version = data[0][2] 694 if version == 1: 695 #creole 1 696 dico_path = os.path.abspath(config.ROOT_DIR)+os.sep+'dictionnaires' 697 dico_b64 = {'dico-'+str(libelle):dico_b64} 698 else: 699 #creole 2 700 dico_path = os.path.abspath(config.ROOT_DIR)+os.sep+'dictionnaires'+os.sep+str(libelle) 701 if not os.path.isdir(dico_path): 702 # module supplémentaire non géré par eole 703 dico_path = os.path.join(os.path.abspath(config.PATH_MODULES),str(id_module),"dicos") 704 # traitement des dictionnaires définis 705 for dic_name, data in dico_b64.items(): 706 dico = os.path.join(dico_path, dic_name) 707 try: 708 if os.path.isfile(dico): 709 # le dictionnaire existe déjà 710 os.unlink(dico) 711 # recréation du fichier avec les données transmises 712 fic_dico = open(dico,'w') 713 fic_dico.write(base64.decodestring(data)) 714 fic_dico.close() 715 except: 716 traceback.print_exc() 717 return 0, u("erreur de mise a jour du dictionnaire du module") 718 719 return 1,u("ok")
720
721 - def xmlrpc_exec_script(self, cred_user, serveurs, script_name, params):
722 """exécution d'un script client sur un serveur/groupe 723 serveurs: id du serveur ou liste d'id 724 script_name: nom du script à exécuter 725 params:paramètres supplémentaires à donner au script 726 """ 727 if type(serveurs) != list: 728 serveurs = [serveurs] 729 erreurs = [] 730 for id_serveur in serveurs: 731 try: 732 id_serveur = int(id_serveur) 733 serv = self.parent.s_pool.get(cred_user, id_serveur) 734 except: 735 erreurs.append("Serveur %s : inexistant ou accès refusé" % str(id_serveur)) 736 continue 737 try: 738 id_uucp = str(serv.get_rne()) + '-' + str(serv.id_s) 739 cmd = "zephir_client %s %s" % (script_name, params) 740 uucp_pool.add_cmd(id_uucp,cmd.strip()) 741 except UUCPError,e: 742 erreurs.append("serveur %s (%s) : Erreur UUCP %s" % (serv.id_s, serv.rne, str(e))) 743 continue 744 if len(erreurs) == len(serveurs): 745 return 0, "Echec de l'exécution ou action interdite sur tous les serveurs" 746 return 1, erreurs
747
748 - def xmlrpc_save_files(self,cred_user,id_serveur,checksum):
749 """sauvegarde des fichiers de configuration d'un serveur""" 750 try: 751 id_serveur = int(id_serveur) 752 serv = self.parent.s_pool.get(cred_user, id_serveur) 753 except (KeyError, ValueError): 754 return 0, u("serveur inconnu dans la base zephir") 755 module = serv.id_mod 756 variante = serv.id_var 757 archive='fichiers_zephir'+str(id_serveur) 758 public_dir = '/var/spool/uucppublic' 759 temp_dir = public_dir+os.sep+str(id_serveur) 760 # création d'un répertoire temporaire pour éviter que tout le monde 761 # écrive dans le même répertoire 762 if os.path.isdir(temp_dir): 763 shutil.rmtree(temp_dir) 764 try: 765 os.mkdir(temp_dir) 766 except: 767 return 0, u("""erreur de creation du repertoire temporaire""") 768 serveur_dir = serv.get_confdir() 769 # on vérifie la validité de l'archive 770 try: 771 fic_md5 = open(public_dir+os.sep+archive+'.md5','w') 772 fic_md5.write(checksum) 773 fic_md5.close() 774 except: 775 return 0, u("""erreur d'écriture du fichier de checksum""") 776 cmd_md5 = """cd %s ; md5sum -c %s.md5 2>&1 > /dev/null""" % (public_dir,archive) 777 res=os.system(cmd_md5) 778 if res != 0: 779 return 0, u("""archive corrompue""") 780 else: 781 # l'archive est valide, on la décompresse 782 cmd_tar = """cd %s ; tar -C %s --same-owner -xhpf %s.tar >/dev/null 2>&1""" % (public_dir,str(id_serveur),archive) 783 os.system(cmd_tar) 784 # on met ensuite les fichiers en place 785 # supression des anciens fichiers ? 786 directories = ['dicos','fichiers_perso','patchs','fichiers_zephir'] 787 for rep in directories: 788 if os.path.exists(os.path.join(temp_dir, 'temp_zephir', rep)): 789 try: 790 if rep == 'dicos' and os.path.isdir(os.path.join(os.path.abspath(config.PATH_MODULES),str(module),'dicos')): 791 # creole2 : on conserve module et variante 792 shutil.rmtree(serveur_dir+os.sep+rep+'/local') 793 else: 794 shutil.rmtree(serveur_dir+os.sep+rep) 795 except: 796 # le repertoire (ou fichier) n'existe pas encore 797 pass 798 # on déplace les fichiers de l'archive 799 res = 0 800 for rep in directories: 801 if res == 0: 802 if os.path.exists(os.path.join(temp_dir, 'temp_zephir', rep)): 803 if os.path.isdir(os.path.join(os.path.abspath(config.PATH_MODULES),str(module),'dicos')) and rep == 'dicos': 804 # cas d'eole2 : répertoire de dictionnaires locaux 805 res = os.system("mv -f %s %s" % (temp_dir+'/temp_zephir/'+rep+'/local', os.path.join(serveur_dir,rep))) 806 else: 807 res = os.system("mv -f %s %s" % (temp_dir+'/temp_zephir/'+rep,serveur_dir)) 808 if res == 0: 809 res = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+os.sep+rep+' '+serveur_dir+os.sep+rep+os.sep+'variante') 810 811 if res != 0: 812 return 0, u("""erreur de mise en place des fichiers""") 813 814 if os.path.exists(os.path.join(temp_dir, 'temp_zephir', 'zephir.eol')): 815 # mise en place de zephir.eol 816 res = os.system("mv -f %s %s" % (temp_dir+'/temp_zephir/zephir.eol',serveur_dir)) 817 if res != 0: 818 return 0, u("""erreur de mise en place de zephir.eol""") 819 else: 820 # mise à jour de l'état du serveur 821 serv.maj_params({'config_ok':1}) 822 # prise en compte de la configuration dans le cache mémoire 823 if serv.dico is not None: 824 if config.CREOLE_CACHE: 825 serv.dico.mode = None 826 serv.load_conf('modif_config') 827 else: 828 serv.last_mode = None 829 serv.get_config('modif_config') 830 831 # vérification des md5 de la configuration 832 new_method = serv.check_min_version(self.parent.maj_checker, 'zephir-client', '2.3-eole54~1') 833 serv.check_md5conf(new_method) 834 # vidage du répertoire public 835 try: 836 # on supprime les fichiers temporaires 837 os.unlink(public_dir+os.sep+archive+'.tar') 838 os.unlink(public_dir+os.sep+archive+'.md5') 839 shutil.rmtree(temp_dir) 840 except: 841 return 0, u("""erreur de supression des fichiers temporaires""") 842 return 1, u('ok')
843 844
845 - def xmlrpc_install_variante(self,cred_user,id_serveur,checksum,login,passwd_md5):
846 """installation d'une variante pour un module""" 847 try: 848 id_serveur = int(id_serveur) 849 serv = self.parent.s_pool.get(cred_user, id_serveur) 850 except (KeyError, ValueError): 851 return 0, u("serveur inconnu dans la base zephir") 852 module = serv.id_mod 853 variante = serv.id_var 854 query = """select id,module,owner,passmd5 from variantes where id = %s and module = %s""" 855 params = (int(variante), int(module)) 856 return self.dbpool.runQuery(query, params).addCallbacks(self._install_variante2,db_client_failed,callbackArgs=[cred_user,checksum,login,passwd_md5,serv.get_rne(),id_serveur])
857 858
859 - def _install_variante2(self,data,cred_user,checksum,login,passwd_md5,rne,id_serveur):
860 """vérification de l'archive et stockage des fichiers""" 861 if data == []: 862 return 0, u("""variante non retrouvée dans la base""") 863 variante = data[0][0] 864 module = data[0][1] 865 owner_var = data[0][2] 866 passwd_var= data[0][3] 867 archive='variante'+str(id_serveur) 868 public_dir = '/var/spool/uucppublic' 869 temp_dir = public_dir+os.sep+str(id_serveur) 870 variante_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(module)+os.sep+'variantes'+os.sep+str(variante) 871 # si le mot de passe de la variante n'existe pas (première installation), on le stocke dans la base 872 # si on est propriétaire de la variante : ok 873 if cred_user != owner_var: 874 # si pas de mot de passe : ok 875 if passwd_var not in [None,'']: 876 # sinon on vérifie le mot de passe 877 if passwd_md5 != passwd_var: 878 return 0, u("""erreur, le mot de passe est invalide""") 879 880 # création d'un répertoire temporaire pour éviter que tout le monde 881 # écrive dans le même répertoire 882 if os.path.isdir(temp_dir): 883 shutil.rmtree(temp_dir) 884 try: 885 os.mkdir(temp_dir) 886 except: 887 return 0, u("""erreur de création du repertoire temporaire""") 888 # on vérifie la validité de l'archive 889 try: 890 fic_md5 = open(public_dir+os.sep+archive+'.md5','w') 891 fic_md5.write(checksum) 892 fic_md5.close() 893 except: 894 return 0, u("""erreur d'écriture du fichier de checksum""") 895 cmd_md5 = """cd %s ; md5sum -c %s.md5 2>&1 > /dev/null""" % (public_dir,archive) 896 res=os.system(cmd_md5) 897 if res != 0: 898 return 0, u("""archive corrompue""") 899 else: 900 # l'archive est valide, on la décompresse 901 cmd_tar = """cd %s ; tar -C %s --same-owner -xhpf %s.tar > /dev/null""" % (public_dir,str(id_serveur),archive) 902 os.system(cmd_tar) 903 # on met ensuite les fichiers en place 904 # supression des anciens patchs et dictionnaires locaux 905 try: 906 shutil.rmtree(variante_dir+os.sep+'dicos') 907 shutil.rmtree(variante_dir+os.sep+'patchs') 908 shutil.rmtree(variante_dir+os.sep+'fichiers_perso') 909 shutil.rmtree(variante_dir+os.sep+'fichiers_zephir') 910 except: 911 return 0, u("""erreur de supression de l'ancienne variante""") 912 # on déplace les fichiers de l'archive 913 res = os.system("mv %s %s" % (temp_dir+os.sep+'patch/variante',variante_dir+os.sep+'patchs')) 914 if res == 0: 915 res = os.system("mv %s %s" % (temp_dir+os.sep+'dicos/variante',variante_dir+os.sep+'dicos')) 916 if res == 0: 917 res = os.system("mv %s %s" % (temp_dir+os.sep+'fichiers_perso',variante_dir+os.sep+'fichiers_perso')) 918 if res == 0: 919 res = os.system("mv %s %s" % (temp_dir+os.sep+'fichiers_zephir',variante_dir+os.sep+'fichiers_zephir')) 920 if res != 0: 921 return 0, u("""erreur de mise en place de la variante""") 922 # vidage du répertoire public 923 try: 924 # on supprime les fichiers temporaires 925 os.unlink(public_dir+os.sep+archive+'.tar') 926 os.unlink(public_dir+os.sep+archive+'.md5') 927 shutil.rmtree(temp_dir) 928 except: 929 return 0, u("""erreur de supression des fichiers temporaires""") 930 931 if passwd_var in [None,'']: 932 # stockage des informations d'authentification 933 query = """update variantes set owner=%s, passmd5=%s where id = %s and module = %s""" 934 params = (login, passwd_md5, int(variante), int(module)) 935 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,'ok'],lambda x : [0,'erreur de stockage du mot de passe']) 936 else: 937 return 1,u('ok')
938
939 - def xmlrpc_log_serveur(self,cred_user,id_serveur,date,type_action,etat,msg):
940 """ met à jour la table d'état du serveur pour une action précise 941 (ex: MAJ ou CONFIG) afin de refléter l'état de cohérence actuelle du serveur 942 """ 943 params = {'last_log':str(date)} 944 if type_action in ['MAJ','CONFIGURE','RECONFIGURE','SAUVEGARDE','REBOOT','SERVICE_RESTART','UPGRADE','PERSO']: 945 # on met à jour le champs params du serveur pour refléter un éventuel changement d'état 946 if int(etat) == -1: 947 params['%s_ok' % type_action.lower()] = [2, str(date), msg] 948 elif int(etat) > 0: 949 params['%s_ok' % type_action.lower()] = [0, str(date), msg] 950 elif int(etat) == 0: 951 if type_action == "MAJ": 952 # cas spécial, maj lancée : on force query_maj à 0 (plus de paquets non à jour) 953 # params['query_maj'] = [0, str(date)] 954 pass 955 elif type_action == "CONFIGURE": 956 # cas de la fin d'envoi de configuration 957 # on estime que les données de configuration sont synchronisées (md5) 958 # si ce n'est pas le cas, la non concordance sera détectée au prochain envoi de stats 959 md5file = os.path.join(os.path.abspath(config.PATH_ZEPHIR),'data','config%s.md5' % id_serveur) 960 if os.path.isfile(md5file): 961 self.parent.s_pool.edit_serveur(id_serveur,{'md5s':1}) 962 params['md5s'] = [1,""] 963 params['%s_ok' % type_action.lower()] = [1, str(date), msg] 964 elif type_action == 'LOCK': 965 if int(etat) == 1: 966 params['lock_ok'] = [2, str(date), msg] 967 else: 968 params['lock_ok'] = [1,''] 969 try: 970 id_serveur = int(id_serveur) 971 serv = self.parent.s_pool[id_serveur] 972 if serv.version == 'creole1': 973 if params.has_key('query_maj'): 974 params['query_maj'] = [-2,""] 975 except (KeyError, ValueError): 976 return 0, u("serveur inconnu dans la base zephir") 977 else: 978 # on met à jour la date de dernier contact dans la base 979 self.parent.s_pool.update_contact(id_serveur) 980 981 # on regarde si l'action en question a déjà un état 982 query = """select id,etat,date,type from last_log_serveur where id_serveur=%s and type=%s""" 983 sql_params = (int(id_serveur), type_action) 984 return self.dbpool.runQuery(query, sql_params).addCallbacks(self._log_serveur,db_client_failed,callbackArgs=[id_serveur,type_action,date,int(etat),msg, params, serv])
985
986 - def _log_serveur(self,data,id_serveur,type_action,date,etat,msg,params,serv):
987 # si l'action existe déjà on la met à jour, sinon on l'insère 988 if data != []: 989 # on insère que si la date du nouveau log est > à l'ancien (cas d'anciens logs non remontés) 990 last_date = data[0][2] 991 try: 992 new_date = datetime.strptime(str(date), "%c") 993 except: 994 try: 995 # problème de conversion de date (pb de locale ?) 996 # on convertit le jour/mois en français 997 new_date = str(date).split() 998 new_date[0] = config.days[new_date[0]] 999 new_date[1] = config.months[new_date[1]] 1000 new_date = " ".join(new_date) 1001 new_date = datetime.strptime(str(new_date),"%a %b %d %H:%M:%S %Y") 1002 except: 1003 log.msg("Serveur %s - erreur de lecture de la date pour le log suivant : %s, %s, %s (%s)" % \ 1004 (str(id_serveur), type_action, str(etat), msg, date)) 1005 log.msg("utilisation de la date courante pour ce log") 1006 new_date = datetime.utcnow() 1007 if new_date >= last_date: 1008 query = """update last_log_serveur set id_serveur=%s,date=%s,type=%s,message=%s,etat=%s where id=%s""" 1009 sql_params = (int(id_serveur), date, type_action, msg, int(etat), int(data[0][0])) 1010 # on met à jour le champs params et le cache mémoire 1011 #if params.has_key('query_maj'): 1012 # self.parent.s_pool.edit_serveur(id_serveur,{'maj':params['query_maj'][0]}) 1013 serv.maj_params(params) 1014 else: 1015 # on a reçu un ancien log (reprise d'anciens logs ayant échoué) -> pas de maj de last_log 1016 return self._log_serveur2(None,id_serveur,type_action,date,etat,msg) 1017 else: 1018 query = """insert into last_log_serveur (id_serveur,date,type,message,etat) values (%s,%s,%s,%s,%s)""" 1019 sql_params = (int(id_serveur), date, type_action, msg, int(etat)) 1020 # on met à jour le champs params et le cache mémoire 1021 #if params.has_key('query_maj'): 1022 # self.parent.s_pool.edit_serveur(id_serveur,{'maj':params['query_maj'][0]}) 1023 serv.maj_params(params) 1024 return self.dbpool.runOperation(query, sql_params).addCallbacks(self._log_serveur2,db_client_failed,callbackArgs=[id_serveur,type_action,date,etat,msg])
1025
1026 - def _log_serveur2(self,data,id_serveur,type_action,date,etat,msg):
1027 query = """insert into log_serveur (id_serveur,date,type,message,etat) values (%s,%s,%s,%s,%s)""" 1028 sql_params = (int(id_serveur), date, type_action, msg, etat) 1029 # on effectue la mise à jour de la base 1030 return self.dbpool.runOperation(query, sql_params).addCallbacks(lambda x : [1,'ok'],db_client_failed)
1031
1032 - def xmlrpc_release_lock_groupe(self,cred_user,liste):
1033 """prépare la suppression des verrous sur un groupe""" 1034 erreurs=[] 1035 for serveur in liste: 1036 retour = self.xmlrpc_release_lock(cred_user, serveur['id']) 1037 if retour[0] == 0: 1038 erreurs.append(str(serveur['id'])+' : '+retour[1]) 1039 if erreurs != []: 1040 return 0, u(erreurs) 1041 else: 1042 return 1, u('ok')
1043
1044 - def xmlrpc_release_lock(self,cred_user,id_serveur):
1045 """demande la libération des verrous sur un serveur""" 1046 try: 1047 id_serveur = int(id_serveur) 1048 serv = self.parent.s_pool.get(cred_user,id_serveur) 1049 except (KeyError, ValueError): 1050 return 0, u("serveur inconnu dans la base zephir") 1051 else: 1052 serv.maj_params({'del_locks':True}) 1053 return 1, 'ok'
1054
1055 - def xmlrpc_unlock(self,cred_user,id_serveur,unlocked=False):
1056 """indique si les locks doivent être ignorés 1057 @params unlocked: si True, on enlève l'attibut del_lock de params""" 1058 try: 1059 id_serveur = int(id_serveur) 1060 serv = self.parent.s_pool.get(cred_user,id_serveur) 1061 except (KeyError, ValueError): 1062 return 0, u("serveur inconnu dans la base zephir") 1063 params = serv.get_params() 1064 if params.has_key('del_locks'): 1065 if params['del_locks'] == True: 1066 if unlocked: 1067 # les verrous ont été supprimés, on revient en état normal 1068 serv.maj_params({'del_locks':False}) 1069 # les verrous doivent être bypassés 1070 return 1, True 1071 return 1, False
1072
1073 - def _sendmail(self,adresses,subject,msg):
1074 """envoi d'un message d'alerte à une liste d'adresses mail 1075 """ 1076 bad_addr={} 1077 mail = email.MIMEText.MIMEText(msg) 1078 mail['Subject'] = Header("[Zephir] %s" % subject,"utf-8") 1079 mail['From'] = Header(config.MAIL_ACCOUNT, "utf-8") 1080 mail.set_charset('UTF-8') 1081 mail_client=smtplib.SMTP() 1082 orig_timeout = smtplib.socket.getdefaulttimeout() 1083 try: 1084 smtplib.socket.setdefaulttimeout(3) 1085 if config.MAIL_TLS.startswith('port '): 1086 mail_client.connect(config.MAIL_ADRESSE,int(config.MAIL_TLS.replace('port ',''))) 1087 else: 1088 mail_client.connect(config.MAIL_ADRESSE) 1089 smtplib.socket.setdefaulttimeout(orig_timeout) 1090 except: 1091 smtplib.socket.setdefaulttimeout(orig_timeout) 1092 return 0, u('erreur de connexion au serveur smtp') 1093 else: 1094 try: 1095 mail_client.ehlo_or_helo_if_needed() 1096 if config.MAIL_TLS.startswith('port '): 1097 try: 1098 mail_client.starttls() 1099 except smtplib.SMTPException, e: 1100 return 0, u("Erreur d'envoi du mail d'alerte : le serveur %s ne gère pas les connexions cryptées (TLS)" % config.MAIL_ADRESSE) 1101 bad_addr = mail_client.sendmail(config.MAIL_ACCOUNT,adresses,mail.as_string()) 1102 except: 1103 return 0, u("erreur d'envoi du mail d'alerte") 1104 return 1, bad_addr
1105
1106 - def xmlrpc_maj_site(self,cred_user,ip_publique,id_serveur,checksum,new_agents=0):
1107 if config.USE_THREADS: 1108 return threads.deferToThread(self._maj_site, cred_user,ip_publique, \ 1109 id_serveur,checksum,new_agents) 1110 else: 1111 return self._maj_site(cred_user, ip_publique, id_serveur, checksum, new_agents)
1112
1113 - def _maj_site(self,cred_user,ip_publique,id_serveur,checksum,new_agents=0):
1114 """vérifie l'archive envoyée par le serveur et met le site et les données xml en place 1115 """ 1116 log.msg ("connexion du serveur %s" % str(id_serveur)) 1117 # on regarde dans les logs si un lock est indiqué 1118 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD) 1119 query="""select type,etat from last_log_serveur where id_serveur=%s and type='LOCK' order by date desc, id desc""" 1120 cursor=cx.cursor() 1121 cursor.execute(query, (int(id_serveur),)) 1122 data=cursor.fetchall() 1123 cursor.close() 1124 cx.close() 1125 etat=0 1126 if data != []: 1127 etat=int(data[0][1]) 1128 if etat == 1: 1129 # si il y avait un lock sur uucp, on l'annule 1130 self.xmlrpc_log_serveur(cred_user,id_serveur,str(time.ctime()),'LOCK','0',"""Reprise de l'activité uucp""") 1131 # on met à jour la date de dernier contact dans la base 1132 self.parent.s_pool.update_contact(id_serveur) 1133 # vérification du md5 de l'archive 1134 public_dir = '/var/spool/uucppublic' 1135 archive = 'site%s' % id_serveur 1136 try: 1137 fic_md5 = open(public_dir+os.sep+archive+'.md5','w') 1138 fic_md5.writelines(checksum) 1139 fic_md5.close() 1140 except: 1141 return 0, u("""erreur d'écriture du fichier de checksum""") 1142 cmd_md5 = """cd %s ; md5sum -c %s.md5 2>&1 > /dev/null""" % (public_dir, archive) 1143 res=os.system(cmd_md5) 1144 if res != 0: 1145 return 0, u("""archive corrompue""") 1146 else: 1147 compressed='' 1148 # l'archive est valide, on la décompresse 1149 if int(new_agents) == 1: 1150 # l'archive est zippée avec les nouveaux agents 1151 compressed = 'z' 1152 rep_dest = os.path.abspath(config.PATH_ZEPHIR) 1153 # on supprime l'ancien répertoire 1154 try: 1155 shutil.rmtree(rep_dest+os.sep+"data"+os.sep+str(id_serveur)) 1156 except: 1157 pass 1158 else: 1159 rep_dest = os.path.abspath(config.PATH_ZEPHIR)+os.sep+"sites"+os.sep+str(id_serveur) 1160 # on supprime l'ancien répertoire 1161 if os.path.exists(rep_dest): 1162 shutil.rmtree(rep_dest) 1163 os.makedirs(rep_dest) 1164 1165 cmd_tar = """cd %s ; /bin/tar -C %s -x%sf %s.tar 2> /dev/null""" % (public_dir, rep_dest, compressed, archive) 1166 res=os.system(cmd_tar) 1167 if res != 0: 1168 return 0, u("erreur de mise en place du site sur zephir") 1169 serv = self.parent.s_pool[int(id_serveur)] 1170 if self.parent.maj_checker: 1171 serv.check_maj_status(self.parent.maj_checker) 1172 new_method = serv.check_min_version(self.parent.maj_checker, 'zephir-client', '2.3-eole54~1') 1173 # vérification du md5 de la configuration 1174 serv.check_md5conf(new_method) 1175 serv.update_ip_pub(ip_publique) 1176 if int(new_agents) == 1 and serv.version == 'creole1': 1177 # si serveur eole 1, on convertit le xml en utf-8 1178 f_site = file(os.path.join(rep_dest,'data',str(id_serveur),'site.cfg')) 1179 data = f_site.read() 1180 f_site.close() 1181 try: 1182 data = unicode(data,'ISO-8859-1').encode(config.charset) 1183 except: 1184 pass 1185 else: 1186 f_site = file(os.path.join(rep_dest,'data',str(id_serveur),'site.cfg'),'w') 1187 f_site.write(data) 1188 f_site.close() 1189 for xml_file in glob.glob(os.path.join(rep_dest,'data',str(id_serveur),'*/agent.xml')): 1190 try: 1191 xml = file(xml_file).read() 1192 # conversion du contenu 1193 for ori, dst in config.xml_table.items(): 1194 xml = xml.replace(ori,dst) 1195 file(xml_file,'w').write(xml) 1196 except: 1197 log.msg("erreur lors de la conversion de %s en %s" % (xml_file, config.charset)) 1198 # on met à jour la liste d'agents (en cas de nouvel agent) 1199 # et on regarde si un des agents a remonté une erreur 1200 list_errors = [] 1201 try: 1202 if self.agent_manager.has_key(str(id_serveur)): 1203 # nouvelle API des agents 1204 # on force un update du cache pour ce serveur (prise en compte de nouveaux agents sans redémarrer l'application) 1205 self.agent_manager[str(id_serveur)].update_structure() 1206 stats = self.agent_manager[str(id_serveur)].get_measure() 1207 result_ag = self.agent_manager[str(id_serveur)].global_status() 1208 if result_ag == 0: 1209 # détail des agents en erreur 1210 liste_errors = [] 1211 for ag_name, detail_ag in self.agent_manager[str(id_serveur)].agents_status().items(): 1212 if detail_ag[1] == 0 and ag_name != 'tcpservices': 1213 list_errors.append(detail_ag[0]) 1214 else: 1215 # anciens agents 1216 # mise à jour des données depuis les xml remontés 1217 AgentCollecteur(id_serveur) 1218 result_ag = ServeurStatus(id_serveur).get_status() 1219 except: 1220 traceback.print_exc() 1221 result_ag = 1 1222 1223 # on vérifie la cohérence du serveur au niveau des logs zephir 1224 try: 1225 result_zeph = self.parent.getSubHandler('serveurs').xmlrpc_get_status(cred_user,id_serveur) 1226 except: 1227 return 0, u("erreur de récupération de l'état zephir du serveur %s" % id_serveur) 1228 1229 d = defer.Deferred() 1230 d.addCallback(self._alerte,result_zeph[1],result_ag,list_errors) 1231 d.callback(id_serveur) 1232 1233 return 1,u("ok")
1234 1235
1236 - def _alerte(self,id_serveur,etat_zeph,etat_ag,list_errors):
1237 """vérification de l'état du serveur et envoi mail si nécessaire 1238 """ 1239 # on récupére la liste des utilisateurs à contacter 1240 query="select serveurs.id,serveurs.rne,installateur,serveurs.libelle, \ 1241 modules.libelle,etablissements.libelle,serveurs.etat \ 1242 from serveurs,etablissements,modules \ 1243 where serveurs.id=%s and etablissements.rne=serveurs.rne and modules.id=module_actuel" 1244 self.dbpool.runQuery(query, (int(id_serveur),)).addCallbacks(self._alerte2,db_client_failed,callbackArgs=[etat_zeph,etat_ag,list_errors])
1245
1246 - def _alerte2(self,data,etat_zeph,etat_ag,list_errors):
1247 # si erreur zephir ou agent --> mail 1248 if data == []: 1249 # pas de données récupérées (serveur inexistant ?) 1250 pass 1251 else: 1252 id_serveur = data[0][0] 1253 rne = data[0][1] 1254 libelle = data[0][3] 1255 module = data[0][4] 1256 libel_etab = data[0][5] 1257 etat_precedent = data[0][6] 1258 if etat_precedent != None: 1259 try: 1260 etat_precedent = int(etat_precedent) 1261 except Exception, e: 1262 etat_precedent = 1 1263 erreur = 0 1264 msg = """le serveur %s (%s - %s)\n établissement : %s (%s)""" % (libelle, id_serveur, module, rne, libel_etab) 1265 # vérification de l'état du serveur 1266 for cle in etat_zeph.keys(): 1267 etat = etat_zeph[cle] 1268 if type(etat) == list: 1269 if len(etat) == 3: 1270 if etat[0] == 0: 1271 if erreur == 0: 1272 msg += """\n(se reporter à la page d'état du serveur dans l'application web)""" 1273 erreur = 1 1274 msg +="""\n\nlog du %s : %s""" % (etat[1].encode(config.charset),etat[2].encode(config.charset)) 1275 if (cle == 'lock_ok') and (etat[0] != 1): 1276 msg += """\n\n Fonction Zephir verrouillées, connectez vous sur le serveur pour vérifier son état 1277 (commande '/usr/share/zephir/scripts/zephir_client del_lock' pour déverrouiller)""" 1278 1279 # on stocke l'etat global des agents dans le champs params du serveur 1280 serv = self.parent.s_pool[id_serveur] 1281 serv.maj_params({'agents':etat_ag}) 1282 if etat_ag == 0: 1283 erreur = 2 1284 # erreur remontée dans le site de surveillance 1285 msg += """\n\nerreur remontée par le serveur (cf. https://%s:%s/agents/%s)""" % (config.ADRESSE_ZEPHIR,config.PORT_HTTP,id_serveur) 1286 if list_errors != []: 1287 msg += """\n\n* %s""" % "\n* ".join(list_errors) 1288 1289 # envoi de message si erreur non envoyée précédemment 1290 # on regarde le dernier état enregistré pour ce serveur 1291 if erreur != 0: 1292 if etat_precedent not in [0,4]: 1293 if etat_precedent == 3: 1294 serv.set_status(4) 1295 else: 1296 serv.set_status(0) 1297 if serv.no_alert == False: 1298 # début d'alerte 1299 if etat_precedent == 2: 1300 # on vient de reprendre contact et il y a un problème 1301 subject = "problème détecté à la reprise de contact: serveur %s (%s)" % (libelle,rne) 1302 else: 1303 subject = "problème détecté : serveur %s (%s)" % (libelle,rne) 1304 msg = "\nproblème détecté sur " + msg 1305 self._send_alerte("problème détecté : serveur ",{int(id_serveur):msg}) 1306 else: 1307 # pas d'erreur détectée, si l'état était à 2, on ne le change pas 1308 # (l'état sera remis à 1 par la fonction de vérification du timeout) 1309 if etat_precedent in [0,4]: 1310 if etat_precedent == 4: 1311 serv.set_status(3) 1312 else: 1313 serv.set_status(1) 1314 if serv.no_alert == False: 1315 # fin d'alerte 1316 subject = "fin d'alerte : serveur %s (%s)" % (libelle,rne) 1317 msg = "\n fin d'alerte pour " + msg 1318 self._send_alerte("fin d'alerte : ",{int(id_serveur):msg}) 1319 # si on n'avait pas d'info : etat ok 1320 if etat_precedent == None: 1321 serv.set_status(1)
1322
1323 - def _send_alerte(self,subject,msgs):
1324 """recherche les mails et sms des personnes surveillant un serveur particulier 1325 """ 1326 if msgs != {}: 1327 query = """select id,serveurs from groupes_serveurs""" 1328 self.dbpool.runQuery(query).addCallbacks(self._send_alerte2,db_client_failed,callbackArgs=[subject,msgs])
1329
1330 - def _send_alerte2(self,data,subject,msg):
1331 # on récupère les groupes 1332 # et on regarde quels groupes contiennent ce serveur 1333 groupes=[] 1334 for id_serveur in msg.keys(): 1335 for groupe in data: 1336 if id_serveur in eval(groupe[1]): 1337 if groupe[0] not in groupes: 1338 groupes.append(groupe[0]) 1339 query = """select groupes,mail,sms,mail_actif,sms_actif from users \ 1340 where groupes != '' and (mail_actif=1 or sms_actif=1)""" 1341 self.dbpool.runQuery(query).addCallbacks(self._send_alerte3,db_client_failed,callbackArgs=[groupes,subject,msg])
1342
1343 - def _send_alerte3(self,data,groupes,subject,msg):
1344 """regarde quels utilisateurs surveillent les groupes 1345 en question et envoie un mail ou sms si besoin 1346 """ 1347 # utilisateurs avec les bons groupes 1348 destinataires = [] 1349 for user in data: 1350 try: 1351 groupes_user=eval(user[0]) 1352 except: 1353 groupes_user=[] 1354 for groupe in groupes_user: 1355 # un des groupes contient ce serveur 1356 if groupe in groupes: 1357 # on regarde si il faut envoyer des mails ou sms 1358 if user[3]==1: 1359 # on vérifie la syntaxe de l'adresse mail 1360 for adresse in user[1].split(','): 1361 r=re.match("""^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9]+)*$""",adresse) 1362 if r is not None: 1363 # adresse valide : on envoie le mail 1364 if adresse not in destinataires: 1365 destinataires.append(adresse) 1366 # envoi effectif des messages à tous les utilisateurs concernés 1367 if destinataires != []: 1368 self._sendmail(destinataires,subject + str(msg.keys()),"\n".join(msg.values()))
1369
1370 - def xmlrpc_scan_timeouts(self,*args):
1371 """vérifie toutes les x minutes si des serveurs ont dépassé leur timeout. 1372 vérification toutes les 5 miuntes par défaut""" 1373 # requete de récupération des données 1374 try: 1375 # premier démarrage de la boucle de vérification des contacts 1376 if self.start_time is not None: 1377 # self.parent.scheduler.start() 1378 # on démarre également la vérification des paquets disponibles 1379 self.parent.maj_checker = AptChecker() 1380 query = "update serveurs set last_contact=%s where last_contact is not null and etat <> 2" 1381 self.dbpool.runOperation(query, (self.start_time,)).addCallbacks(lambda x : [1, "OK"],db_client_failed) 1382 reactor.callLater(5, self._scan_timeouts) 1383 except: 1384 traceback.print_exc() 1385 return 0, "erreur de démarrage de la boucle de surveillance" 1386 return 1,""
1387
1388 - def _scan_timeouts(self):
1389 reactor.callLater(self.scan_delay, self._scan_timeouts) 1390 if config.LOG_ACTIONS: 1391 log.msg('Recherche des pertes de contact') 1392 query = """select serveurs.id,timeout,last_contact,serveurs.libelle, \ 1393 serveurs.rne,etablissements.libelle,modules.libelle,serveurs.etat \ 1394 from serveurs,etablissements,modules where timeout > 0 and last_contact is not null and \ 1395 serveurs.rne=etablissements.rne and module_actuel=modules.id""" 1396 self.dbpool.runQuery(query).addCallbacks(self._scan_timeouts2,db_client_failed)
1397
1398 - def _scan_timeouts2(self, data):
1399 """vérifie si le dernier contact est moins ancien que le timeout du serveur. 1400 """ 1401 # lancement du préchargement des configurations en tâche de fond au premier lancement 1402 if self.start_time is not None and config.CREOLE_CACHE: 1403 self.start_time = None 1404 reactor.callInThread(self.update_creole, [serv[0] for serv in data]) 1405 # vérification des serveurs en timeout 1406 cmds=uucp_pool._scan_pool() 1407 d_list = [] 1408 for serveur in data: 1409 # on lance la boucle de vérification sans attendre le résultat 1410 if config.USE_THREADS: 1411 def_check = threads.deferToThread(self.check_timeout, serveur) 1412 else: 1413 def_check = defer.maybeDeferred(self.check_timeout, serveur) 1414 d_list.append(def_check) 1415 d = defer.DeferredList(d_list, consumeErrors=True) 1416 d.addCallback(self._send_alertes)
1417
1418 - def _send_alertes(self, results):
1419 erreurs={} 1420 reprises={} 1421 bloquages={} 1422 debloquages={} 1423 # collecte des résultats pour chaque serveur 1424 for success, data in results: 1425 if success: 1426 erreurs.update(data[0]) 1427 reprises.update(data[1]) 1428 bloquages.update(data[2]) 1429 debloquages.update(data[3]) 1430 else: 1431 log.msg("! Erreur lors de la vérification du timeout d'un serveur : %s" \ 1432 % str(data.getErrorMessage())) 1433 self._send_alerte("commandes non lancées : ",bloquages) 1434 self._send_alerte("commandes débloquées : ",debloquages) 1435 self._send_alerte("perte de contact : ",erreurs) 1436 self._send_alerte("reprise du contact : ",reprises)
1437
1438 - def check_timeout(self, serveur):
1439 """vérifie si un serveur a dépassé le délai de connexion autorisé 1440 """ 1441 erreurs={} 1442 reprises={} 1443 bloquages={} 1444 debloquages={} 1445 # calcul du temps écoulé depuis le dernier contact (en secondes) 1446 serv = self.parent.s_pool[int(serveur[0])] 1447 params = {'timeout':[-2, ""]} 1448 last = float(serveur[2]) 1449 delta = float(time.time()) - last 1450 try: 1451 etat_actuel = int(serveur[7]) 1452 except: 1453 etat_actuel = 1 1454 # on regarde si on a dépassé le timeout 1455 try: 1456 timeout = int(serveur[1]) 1457 except: 1458 pass 1459 else: 1460 params['timeout'] = [1, time.ctime(last)] 1461 # on laisse un délai de 2x le délai de connexion + 4 minutes avant de lever une alerte 1462 # (on autorise de rater une connexion) 1463 max_delay = int(timeout) * 2 + 240 1464 if ( delta > max_delay ) and timeout != 0: 1465 params['timeout'][0]=0 1466 if etat_actuel != 2: 1467 # on prévient les utilisateurs concernés si ce n'est pas déjà fait 1468 reactor.callFromThread(log.msg, "timeout du serveur %s" % serveur[0]) 1469 serv.set_status(2) 1470 # construction du message d'erreur 1471 if serv.no_alert == False: 1472 subject = """perte du contact : serveur(s) %s (%s)""" % (serveur[3],serveur[4]) 1473 msg="""Dernier contact avec le serveur n°%s - %s (%s) de l'établissement %s (%s) : %s""" % (serveur[0],serveur[3],serveur[6],serveur[4],serveur[5],time.ctime(last)) 1474 # ajout de l'alerte 1475 erreurs[serveur[0]]=msg 1476 else: 1477 if etat_actuel == 2: 1478 # on était en timeout auparavant 1479 serv.set_status(1) 1480 if serv.no_alert == False and timeout != 0: 1481 subject = """reprise du contact : serveur(s) %s (%s)""" % (serveur[3],serveur[4]) 1482 msg = """reprise du contact avec le serveur n°%s - %s (%s) de l'établissement %s (%s) : %s""" % \ 1483 (serveur[0],serveur[3],serveur[6],serveur[4],serveur[5],time.ctime(last)) 1484 reprises[serveur[0]]=msg 1485 1486 # vérification de la bonne exécution des commandes 1487 id_uucp = serveur[4]+"-"+str(serveur[0]) 1488 old_cmds = uucp_pool.check_timeout(max_delay, id_uucp) 1489 if old_cmds != {} and timeout != 0: 1490 if etat_actuel not in [3,4]: 1491 # mail pour le bloquage des commandes en attente 1492 if serv.no_alert == False: 1493 msg = """commandes bloquées en attente pour le serveur n°%s - %s (%s) de l'établissement %s (%s) 1494 Vous pouvez afficher les logs de transfert UUCP sur ce serveur à l'aide de la commande uulog""" 1495 bloquages[serveur[0]] = msg % (serveur[0],serveur[3],serveur[6],serveur[4],serveur[5]) 1496 if etat_actuel == 0: 1497 # bloquage + erreur agents 1498 serv.set_status(4) 1499 else: 1500 # bloquage 1501 serv.set_status(3) 1502 elif etat_actuel in [3,4]: 1503 # les commandes sont débloquées 1504 if serv.no_alert == False and timeout != 0: 1505 msg = """débloquage des commandes (reprise d'activité uucp) pour le serveur n°%s - %s (%s) de l'établissement %s (%s)""" 1506 debloquages[serveur[0]] = msg % (serveur[0],serveur[3],serveur[6],serveur[4],serveur[5]) 1507 if etat_actuel == 4: 1508 # erreur agents 1509 serv.set_status(0) 1510 else: 1511 # aucune erreur 1512 serv.set_status(1) 1513 1514 # mise à jour du champ params du serveur 1515 serv.maj_params(params) 1516 return erreurs, reprises, bloquages, debloquages
1517
1518 - def update_creole(self, serveurs):
1519 # initialisation du premier serveur dans la liste 1520 log.msg("Début de mise en cache des configurations des serveurs") 1521 max_serv = len(serveurs) 1522 for num_serv, serveur in enumerate(serveurs): 1523 if not reactor.running: 1524 # On vérifie d'abord si le réacteur principal est toujours lancé 1525 # (l'arrêt idu réacteur n'arrête pas le thread) 1526 break 1527 # lancement du chargement dans un Deffered (on n'attend pas le résultat) 1528 def_upd = defer.Deferred() 1529 def_upd.addCallback(self._update_creole, max_serv, num_serv) 1530 def_upd.callback(serveur) 1531 log.msg("Fin de mise en cache des configurations")
1532
1533 - def _update_creole(self, serveur, nb_serv, current):
1534 id_serv = int(serveur) 1535 try: 1536 serv = self.parent.s_pool[id_serv] 1537 # si les dictonnaires du module du serveur est géré par dictpool, 1538 # on vérifie que tous les liens sont bien créés 1539 if self.parent.dictpool.check_module(serv.id_mod): 1540 self.parent.dictpool.check_dirs(serv) 1541 if serv.dico is None: 1542 serv.get_config('modif_config') 1543 if divmod(current, 50)[1] == 0 and current != 0: 1544 # affichage d'un message tous les 50 serveur et en fin de chargement 1545 log.msg("Mise en cache des configurations : %d/%d effectué" % (current, nb_serv)) 1546 except Exception, e: 1547 log.msg("Erreur de lecture de la configuration du serveur %s (%s)" % (str(id_serv), str(e)))
1548
1549 - def xmlrpc_get_actions(self,cred_user,id_serveur):
1550 """retourne la liste des actions uucp en attente""" 1551 # on vérifie l'existence du serveur dans la base 1552 try: 1553 id_serveur = int(id_serveur) 1554 serv = self.parent.s_pool.get(cred_user, id_serveur) 1555 except (KeyError, ValueError): 1556 return 0, u("serveur inconnu dans la base zephir") 1557 else: 1558 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur) 1559 # construction de la commande 1560 try: 1561 cmds=uucp_pool.list_cmd(id_uucp)[id_uucp] 1562 except: 1563 cmds={} 1564 try: 1565 files=uucp_pool.list_files(id_uucp)[id_uucp] 1566 except: 1567 files={} 1568 return 1,u([cmds,files])
1569
1570 - def xmlrpc_check_queue(self,cred_user,id_serveur):
1571 """indique à un serveur si il doit ou non effectuer des actions 1572 """ 1573 # on vérifie l'existence du serveur dans la base 1574 try: 1575 id_serveur = int(id_serveur) 1576 serv = self.parent.s_pool.get(cred_user, id_serveur) 1577 except (KeyError, ValueError): 1578 return 0, u("serveur inconnu dans la base zephir") 1579 else: 1580 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur) 1581 # on commence par mettre à jour le pool uucp 1582 cmds=uucp_pool._scan_pool() 1583 if len(uucp_pool.pool[id_uucp]) > 0: 1584 return 1, True 1585 else: 1586 return 1, False
1587
1588 - def xmlrpc_purge_actions(self,cred_user,serveurs,id_tache=None):
1589 """annule toutes les actions en attente sur un/plusieurs serveur(s)""" 1590 # on vérifie l'existence du serveur dans la base 1591 try: 1592 for id_serveur in serveurs: 1593 id_serveur = int(id_serveur) 1594 assert self.parent.s_pool.has_key(id_serveur) 1595 except (KeyError, ValueError): 1596 return 0, u("serveur inconnu dans la base zephir") 1597 else: 1598 for id_serveur in serveurs: 1599 rne = self.parent.s_pool.get(cred_user,int(id_serveur)).get_rne() 1600 id_uucp = str(rne) + '-' + str(id_serveur) 1601 # on regarde si un transfert est lié à cette action (configure) 1602 if id_tache is None: 1603 try: 1604 uucp_pool.flush([id_uucp]) 1605 except UUCPError, e: 1606 return 0, u("erreur de purge des commandes : %" % str(e)) 1607 else: 1608 try: 1609 uucp_pool.remove_cmd(id_uucp,int(id_tache)) 1610 except UUCPError, e: 1611 return 0, u("Erreur de supression de la commande uucp : %" %str(e)) 1612 except KeyError: 1613 pass 1614 1615 return 1,"OK"
1616