diff --git a/gestion/hptools.py b/gestion/hptools.py index 619e0851..15beebe6 100755 --- a/gestion/hptools.py +++ b/gestion/hptools.py @@ -8,6 +8,8 @@ Donne la classe switch qui permet d'effectuer les opérations élémentaires sur les switchs manageable HP 26xx. Frédéric PAUGET +TODO réécrire ce script (la moitié des fonctions ne marchent plus, + l'autre ferait bien d'utiliser netsnmp ou équivalent) """ from time import sleep from sys import stderr, path @@ -15,10 +17,12 @@ from commands import getstatusoutput from annuaires_pg import chbre_prises, all_switchs from os.path import exists from os import system +import os import sys from re import findall import re from config import vlans +import netsnmp path.append('/usr/scripts/gestion') from ldap_crans import crans_ldap @@ -123,6 +127,7 @@ class snmp : """ self.host = host self.version = version + self.community = community if version == '1' or version == '2c' : self.options = "-v %s -c '%s' %s " % ( version, community, host ) @@ -179,10 +184,12 @@ class snmp : """ return self.__exec('snmpset -O vq %s %s %s %s' % (self.options, oid, typ, val ) ) - def walk(self,base_oid) : + def walk(self,base_oid, bin_comp=False) : """ Retourne le résultat de snmpwalk le retour est un dictionnaire { oid : valeur } """ + if bin_comp: + return snmp.bin_walk(self, base_oid) lignes = self.__exec('snmpwalk -Ox %s %s' % (self.options, base_oid ) ).split('\n') result = {} for ligne in lignes: @@ -193,6 +200,37 @@ class snmp : pass return result + def bin_walk(self, base_oid): + """ Retourne le résultat de snmpwalk + le retour est un dictionnaire { oid : valeur } + TODO: prendre en compte l'auth et le snmp vn, n>1 + TODO: malheureusement, la plupart des fonctions faisant appel + à walk ne marchent pas out-of-the-box, il faut donc + d'abord les convertir avant de leur faire utiliser cette nouvelle + fonction + """ + try: + prefix, b_oid = base_oid.split('::', 1) + except ValueError: + raise NotImplementedError('Merci de préciser un MIB') + + os.environ['MIBS'] = prefix + # ^^^ Je suis triste de faire ça + + oid_obj = netsnmp.VarList(netsnmp.Varbind(b_oid)) + # oid_obj est remple des réponses du snmpwalk + netsnmp.snmpwalk(oid_obj, + Version = int(self.version), + DestHost=self.host, + Community=self.community, + ) + #UseLongNames=1, #ceci devrait marcher selon la doc + #en pratique, non (cf /usr/lib/python2.7/dist-packages/netsnmp/client.py) + + # On renvoie un résultat ressemblant à ce que fait le snmpwalk shell + return { '%s::%s.%s' % (prefix, res.tag, res.iid): res.val + for res in oid_obj } + ############################################################################################# ### Gestion des switchs proprement dite @@ -228,13 +266,13 @@ class hpswitch : if not prise : prise = self.prise if self.__debug : self.__logDest.write("HP DEBUG : show_prise_mac(prise=%s)\n" % prise) try: - data = self.walk('STATISTICS-MIB::hpSwitchPortFdbAddress.%d' % int(prise)) + data = self.walk('STATISTICS-MIB::hpSwitchPortFdbAddress.%d' % int(prise), + bin_comp=True) macs = [] for value in data.itervalues(): - mac = value.replace(' ', '').lower().replace('"', '') - if not re.match('([0-9a-f]{2}){6}', mac): - mac = mac.encode('hex').lower() - mac = "%s:%s:%s:%s:%s:%s" % (mac[0:2], mac[2:4], mac[4:6], mac[6:8], mac[8:10], mac[10:12]) + if len(value) != 6: + continue # Should not happen + mac = ':'.join('%02x' % ord(c) for c in value) macs.append(mac) return macs except ValueError: @@ -247,7 +285,8 @@ class hpswitch : mac = mac.lower() # On interroge le switch try: - data = self.walk('STATISTICS-MIB::hpSwitchPortFdbAddress') + data = self.walk('STATISTICS-MIB::hpSwitchPortFdbAddress', + bin_comp=True) except ValueError: print >> sys.stderr, "Le switch %s fait du caca..." % self.switch return None