Show
Ignore:
Timestamp:
10/11/09 08:41:33 (15 years ago)
Author:
jerome
Message:

Removed all support for pysnmp v3.x
Applied the patch from Ilya Etingof and Börje Sennung to fix #47.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/pykota/accounters/snmp.py

    r3503 r3506  
    3737    from pysnmp.entity.rfc3413.oneliner import cmdgen 
    3838except ImportError : 
    39     hasV4 = False 
    40     try : 
    41         from pysnmp.asn1.encoding.ber.error import TypeMismatchError 
    42         from pysnmp.mapping.udp.error import SnmpOverUdpError 
    43         from pysnmp.mapping.udp.role import Manager 
    44         from pysnmp.proto.api import alpha 
    45     except ImportError : 
    46         raise RuntimeError, "The pysnmp module is not available. Download it from http://pysnmp.sf.net/" 
    47 else : 
    48     hasV4 = True 
     39    raise RuntimeError, "The pysnmp v4.x module is not available. Download it from http://pysnmp.sf.net/\nPyKota doesn't support earlier releases anymore." 
    4940 
    5041from pykota import constants 
     
    257248        return self.printerInternalPageCounter 
    258249 
    259 if hasV4 : 
    260     class Handler(BaseHandler) : 
    261         """A class for pysnmp v4.x""" 
    262         def retrieveSNMPValues(self) : 
    263             """Retrieves a printer's internal page counter and status via SNMP.""" 
    264             try : 
    265                 errorIndication, errorStatus, errorIndex, varBinds = \ 
    266                  cmdgen.CommandGenerator().getCmd(cmdgen.CommunityData("pykota", self.community, 0), \ 
    267                                                   cmdgen.UdpTransportTarget((self.printerHostname, self.port)), \ 
    268                                                   tuple([int(i) for i in pageCounterOID.split('.')]), \ 
    269                                                   tuple([int(i) for i in hrPrinterStatusOID.split('.')]), \ 
    270                                                   tuple([int(i) for i in hrDeviceStatusOID.split('.')]), \ 
    271                                                   tuple([int(i) for i in hrPrinterDetectedErrorStateOID.split('.')])) 
    272             except socket.gaierror, msg : 
    273                 errorIndication = repr(msg) 
    274             except : 
    275                 errorIndication = "Unknown SNMP/Network error. Check your wires." 
    276             if errorIndication : 
    277                 self.parent.filter.printInfo("SNMP Error : %s" % errorIndication, "error") 
    278                 self.initValues() 
    279             elif errorStatus : 
    280                 self.parent.filter.printInfo("SNMP Error : %s at %s" % (errorStatus.prettyPrint(), \ 
     250class Handler(BaseHandler) : 
     251    """A class for pysnmp v4.x, PyKota doesn't support earlier releases of pysnmp anymore.'""" 
     252    def __init__(self, *args): 
     253        BaseHandler.__init__(self, *args) 
     254        self.snmpEngine = cmdgen.CommandGenerator() 
     255        self.snmpAuth = cmdgen.CommunityData("pykota", self.community, 0) 
     256        self.snmpTarget = cmdgen.UdpTransportTarget((self.printerHostname, self.port)) 
     257 
     258    def retrieveSNMPValues(self) : 
     259        """Retrieves a printer's internal page counter and status via SNMP.""" 
     260        try : 
     261            errorIndication, errorStatus, errorIndex, varBinds = \ 
     262                self.snmpEngine.getCmd(self.snmpAuth, \ 
     263                                       self.snmpTarget, \ 
     264                                       tuple([int(i) for i in pageCounterOID.split('.')]), \ 
     265                                       tuple([int(i) for i in hrPrinterStatusOID.split('.')]), \ 
     266                                       tuple([int(i) for i in hrDeviceStatusOID.split('.')]), \ 
     267                                       tuple([int(i) for i in hrPrinterDetectedErrorStateOID.split('.')])) 
     268        except socket.gaierror, msg : 
     269            errorIndication = repr(msg) 
     270        except : 
     271            errorIndication = "Unknown SNMP/Network error. Check your wires." 
     272        if errorIndication : 
     273            self.parent.filter.printInfo("SNMP Error : %s" % errorIndication, "error") 
     274            self.initValues() 
     275        elif errorStatus : 
     276            self.parent.filter.printInfo("SNMP Error : %s at %s" % (errorStatus.prettyPrint(), \ 
    281277                                                                        varBinds[int(errorIndex)-1]), \ 
    282278                                             "error") 
    283                 self.initValues() 
    284             else : 
    285                 self.printerInternalPageCounter = max(self.printerInternalPageCounter, int(varBinds[0][1].prettyPrint() or "0")) 
    286                 self.printerStatus = int(varBinds[1][1].prettyPrint() or "2") # or unknown 
    287                 self.deviceStatus = int(varBinds[2][1].prettyPrint() or "1")  # or unknown 
    288                 self.printerDetectedErrorState = self.extractErrorStates(str(varBinds[3][1])) 
    289                 self.parent.filter.logdebug("SNMP answer decoded : PageCounter : %s  PrinterStatus : '%s'  DeviceStatus : '%s'  PrinterErrorState : '%s'" \ 
    290                      % (self.printerInternalPageCounter, \ 
    291                         printerStatusValues.get(self.printerStatus), \ 
    292                         deviceStatusValues.get(self.deviceStatus), \ 
    293                         self.printerDetectedErrorState)) 
    294 else : 
    295     class Handler(BaseHandler) : 
    296         """A class for pysnmp v3.4.x""" 
    297         def retrieveSNMPValues(self) : 
    298             """Retrieves a printer's internal page counter and status via SNMP.""" 
    299             ver = alpha.protoVersions[alpha.protoVersionId1] 
    300             req = ver.Message() 
    301             req.apiAlphaSetCommunity(self.community) 
    302             req.apiAlphaSetPdu(ver.GetRequestPdu()) 
    303             req.apiAlphaGetPdu().apiAlphaSetVarBindList((pageCounterOID, ver.Null()), \ 
    304                                                         (hrPrinterStatusOID, ver.Null()), \ 
    305                                                         (hrDeviceStatusOID, ver.Null()), \ 
    306                                                         (hrPrinterDetectedErrorStateOID, ver.Null())) 
    307             tsp = Manager() 
    308             try : 
    309                 tsp.sendAndReceive(req.berEncode(), \ 
    310                                    (self.printerHostname, self.port), \ 
    311                                    (self.handleAnswer, req)) 
    312             except (SnmpOverUdpError, select.error), msg : 
    313                 self.parent.filter.printInfo(_("Network error while doing SNMP queries on printer %s : %s") % (self.printerHostname, msg), "warn") 
    314                 self.initValues() 
    315             tsp.close() 
    316  
    317         def handleAnswer(self, wholeMsg, notusedhere, req): 
    318             """Decodes and handles the SNMP answer.""" 
    319             ver = alpha.protoVersions[alpha.protoVersionId1] 
    320             rsp = ver.Message() 
    321             try : 
    322                 rsp.berDecode(wholeMsg) 
    323             except TypeMismatchError, msg : 
    324                 self.parent.filter.printInfo(_("SNMP message decoding error for printer %s : %s") % (self.printerHostname, msg), "warn") 
    325                 self.initValues() 
    326             else : 
    327                 if req.apiAlphaMatch(rsp): 
    328                     errorStatus = rsp.apiAlphaGetPdu().apiAlphaGetErrorStatus() 
    329                     if errorStatus: 
    330                         self.parent.filter.printInfo(_("Problem encountered while doing SNMP queries on printer %s : %s") % (self.printerHostname, errorStatus), "warn") 
    331                     else: 
    332                         self.values = [] 
    333                         for varBind in rsp.apiAlphaGetPdu().apiAlphaGetVarBindList(): 
    334                             self.values.append(varBind.apiAlphaGetOidVal()[1].rawAsn1Value) 
    335                         try : 
    336                             # keep maximum value seen for printer's internal page counter 
    337                             self.printerInternalPageCounter = max(self.printerInternalPageCounter, self.values[0]) 
    338                             self.printerStatus = self.values[1] 
    339                             self.deviceStatus = self.values[2] 
    340                             self.printerDetectedErrorState = self.extractErrorStates(self.values[3]) 
    341                             self.parent.filter.logdebug("SNMP answer decoded : PageCounter : %s  PrinterStatus : '%s'  DeviceStatus : '%s'  PrinterErrorState : '%s'" \ 
    342                                  % (self.printerInternalPageCounter, \ 
    343                                     printerStatusValues.get(self.printerStatus), \ 
    344                                     deviceStatusValues.get(self.deviceStatus), \ 
    345                                     self.printerDetectedErrorState)) 
    346                         except IndexError : 
    347                             self.parent.filter.logdebug("SNMP answer is incomplete : %s" % str(self.values)) 
    348                             pass 
    349                         else : 
    350                             return 1 
     279            self.initValues() 
     280        else : 
     281            self.printerInternalPageCounter = max(self.printerInternalPageCounter, int(varBinds[0][1].prettyPrint() or "0")) 
     282            self.printerStatus = int(varBinds[1][1].prettyPrint() or "2") # or unknown 
     283            self.deviceStatus = int(varBinds[2][1].prettyPrint() or "1")  # or unknown 
     284            self.printerDetectedErrorState = self.extractErrorStates(str(varBinds[3][1])) 
     285            self.parent.filter.logdebug("SNMP answer decoded : PageCounter : %s  PrinterStatus : '%s'  DeviceStatus : '%s'  PrinterErrorState : '%s'" \ 
     286                                            % (self.printerInternalPageCounter, \ 
     287                                                   printerStatusValues.get(self.printerStatus), \ 
     288                                                   deviceStatusValues.get(self.deviceStatus), \ 
     289                                                   self.printerDetectedErrorState)) 
    351290 
    352291def main(hostname) :