diff --git a/gestion/hptools.py b/gestion/hptools.py index 3b318751..2a787fd5 100644 --- a/gestion/hptools.py +++ b/gestion/hptools.py @@ -14,7 +14,6 @@ from popen2 import popen3 from sys import stderr, path from commands import getstatusoutput from annuaires import chbre_prises, all_switchs, uplink_prises -import threading try : from secrets import config_snmp_secrete @@ -40,112 +39,59 @@ class ConversationError(Exception) : # Classes de base pour comminiquer (ssh et snmp) +import pexpect class ssh : """ Ouverture d'une connexion ssh, envoi de commandes et récupération du résultat """ - __debug = 0 - __ssh_log = '/dev/null' - __logDest = stderr - - __ssh_out = '' # Retour de la connexion ssh + def __init__(self,host) : """ Ouverture d'une connexion ssh vers le switch choisi """ self.switch = host - self.log=open(self.__ssh_log,'w') + self.__sshout = '' + self.ssh = pexpect.spawn("ssh %s" % host) + self.ssh.sendline("") + self.ssh.sendline("configure") + self.ssh.expect("%s\(config\)# " % self.switch, timeout=10) - if self.__debug : self.__logDest.write("SSH DEBUG : __init__(host=%s)\n" % host) - self.__host = host - self.__retour, self.__input, self.__err = popen3("/usr/bin/ssh -tt %s" % host) - sleep(1) - - # Création de threads de lecture de la connexion - r = threading.Thread(target=self.__read_retour,args=(threading.currentThread(),)) - r.start() - e = threading.Thread(target=self.__read_err,args=(threading.currentThread(),)) - e.start() - - # On passe l'intro, passe manager et en environnement de configuration - self.send_cmd('\nenable\nconfigure') - - def __read_retour(self,parent) : - while parent.isAlive() : - c = self.__retour.read(1) - self.__ssh_out += c - self.log.write(c) - self.log.flush() - - def __read_err(self,parent) : - err = '' - while parent.isAlive : - char = self.__err.read(1) - if char == '\n' : - # Il y a eu une erreur - if err.lower() in [ 'connection to %s closed by remote host.' % self.switch , - 'connection to %s closed.' % self.switch ] : - raise ConnectionClosed - else : - print err - err = '' - else : - err += char - def __del__(self) : """Ferme la connexion : envoi logout et attend """ - if self.__debug : self.__logDest.write("SSH DEBUG : __del__()\n") - try : - self.send_cmd('\nlogout') - except ConnectionClosed : - # C'est le but - pass + self.ssh.sendline("logout") + self.ssh.send("y") + self.ssh.send("y") + self.ssh.close() def send_cmd(self,cmd,timeout=15): """ Envoi une commande, attend le prompt et retourne la réponse """ - if self.__debug : self.__logDest.write("SSH DEBUG : __send_cmd(%s)\n" % cmd.strip() ) - - self.__ssh_out = '' # oubli de ce qu'il y a avant - self.log.flush() - # Envoi de la commande - self.__input.write(cmd+'\n') - self.__input.flush() + self.ssh.sendline(cmd) + self.__sshout = '' + + try: + # Attente de la réponse + while 1: + index = self.ssh.expect([' \[y/n\]\? ', + '%s\(config\)# ' % self.switch, + 'quit: Control-C'], + timeout=timeout) + + self.__sshout = self.__sshout + self.ssh.before + if index == 0: + # On répond oui + self.ssh.send("y") + elif index == 1: + # On est revenu au prompt + break + elif index == 2: + # On doit continuer, on envoie espace + self.ssh.send(" ") - # Premier retour - count=0 - t = '' - while 1: - sleep(1) - out = self.__ssh_out - # On a récupéré un prompt ? - while_break = 0 - for n in range(1,200) : - try : t = out[-n-7:-n] - except : continue - if t == ' [y/n]?' : - self.__input.write('y') - self.__input.flush() - sleep(1) - elif t == 'onfig)#' : - if self.__debug : self.__logDest.write("SSH DEBUG : __send_cmd -> OK\n") - while_break=1 - elif t == 'ntrol-C' : - # Faut appuyer sur une touche - if self.__debug : self.__logDest.write("SSH DEBUG : __send_cmd -> MORE\n") - self.__input.write(' ') - self.__input.flush() - sleep(1) - else : - continue - break - - if while_break : break - # Rien de bien, le switch es un peu lent, on attend - if self.__debug : self.__logDest.write("SSH DEBUG : __send_cmd -> WAIT (%s) \n" % t) - count += 1 - if count > timeout : - # Il y a un problème - raise ConnectionTimout - - return self.__ssh_out + return self.__sshout + except pexpect.TIMEOUT: + print "Timeout !" + import traceback + traceback.print_exc() + print "Contenu du buffer :" + print self.ssh.before class snmp : """ Classe de communication SNMP """