Changeset 3506

Show
Ignore:
Timestamp:
10/11/09 08:41:33 (13 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.

Location:
pykota/trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/pkturnkey

    r3490 r3506  
    163163            from pysnmp.entity.rfc3413.oneliner import cmdgen 
    164164        except ImportError : 
    165             hasV4 = False 
    166             try : 
    167                 from pysnmp.asn1.encoding.ber.error import TypeMismatchError 
    168                 from pysnmp.mapping.udp.role import Manager 
    169                 from pysnmp.proto.api import alpha 
    170             except ImportError : 
    171                 logerr("pysnmp doesn't seem to be installed. SNMP checks will be ignored !\n") 
    172                 return False 
    173         else : 
    174             hasV4 = True 
    175  
    176         if hasV4 : 
    177             def retrieveSNMPValues(hostname, community) : 
    178                 """Retrieves a printer's internal page counter and status via SNMP.""" 
    179                 errorIndication, errorStatus, errorIndex, varBinds = \ 
    180                      cmdgen.CommandGenerator().getCmd(cmdgen.CommunityData("pykota", community, 0), \ 
    181                                                       cmdgen.UdpTransportTarget((hostname, 161)), \ 
    182                                                       tuple([int(i) for i in pageCounterOID.split('.')])) 
    183                 if errorIndication : 
    184                     raise "No SNMP !" 
    185                 elif errorStatus : 
    186                     raise "No SNMP !" 
    187                 else : 
    188                     self.SNMPOK = True 
    189         else : 
    190             def retrieveSNMPValues(hostname, community) : 
    191                 """Retrieves a printer's internal page counter and status via SNMP.""" 
    192                 ver = alpha.protoVersions[alpha.protoVersionId1] 
    193                 req = ver.Message() 
    194                 req.apiAlphaSetCommunity(community) 
    195                 req.apiAlphaSetPdu(ver.GetRequestPdu()) 
    196                 req.apiAlphaGetPdu().apiAlphaSetVarBindList((pageCounterOID, ver.Null())) 
    197                 tsp = Manager() 
    198                 try : 
    199                     tsp.sendAndReceive(req.berEncode(), \ 
    200                                        (hostname, 161), \ 
    201                                        (handleAnswer, req)) 
    202                 except : 
    203                     raise "No SNMP !" 
    204                 tsp.close() 
    205  
    206             def handleAnswer(wholemsg, notusedhere, req): 
    207                 """Decodes and handles the SNMP answer.""" 
    208                 ver = alpha.protoVersions[alpha.protoVersionId1] 
    209                 rsp = ver.Message() 
    210                 try : 
    211                     rsp.berDecode(wholemsg) 
    212                 except TypeMismatchError, msg : 
    213                     raise "No SNMP !" 
    214                 else : 
    215                     if req.apiAlphaMatch(rsp): 
    216                         errorStatus = rsp.apiAlphaGetPdu().apiAlphaGetErrorStatus() 
    217                         if errorStatus: 
    218                             raise "No SNMP !" 
    219                         else: 
    220                             self.values = [] 
    221                             for varBind in rsp.apiAlphaGetPdu().apiAlphaGetVarBindList(): 
    222                                 self.values.append(varBind.apiAlphaGetOidVal()[1].rawAsn1Value) 
    223                             try : 
    224                                 pagecounter = self.values[0] 
    225                             except : 
    226                                 raise "No SNMP !" 
    227                             else : 
    228                                 self.SNMPOK = True 
    229                                 return True 
    230  
    231         self.SNMPOK = False 
     165            logerr("pysnmp doesn't seem to be installed. PyKota needs pysnmp v4.x, otherwise SNMP checks will be ignored !\n") 
     166            return False 
    232167        try : 
    233             retrieveSNMPValues(hostname, community) 
     168            errorIndication, errorStatus, errorIndex, varBinds = \ 
     169                cmdgen.CommandGenerator().getCmd(cmdgen.CommunityData("pykota", community, 0), \ 
     170                                                     cmdgen.UdpTransportTarget((hostname, 161)), \ 
     171                                                     tuple([int(i) for i in pageCounterOID.split('.')])) 
     172            if errorIndication : 
     173                raise "No SNMP !" 
     174            elif errorStatus : 
     175                raise "No SNMP !" 
     176            else : 
     177                self.SNMPOK = True 
    234178        except : 
    235179            self.SNMPOK = False 
  • pykota/trunk/CREDITS

    r3481 r3506  
    9494    problem with MySQL connections to 'localhost:3306'. 
    9595  - Darin Perusich - Cognigen Corp. - Ported the LDAP schema to Sun DS 
     96  - Ilya Etingof and B� Sennung - Fixed performance problems in SNMP 
     97    queries. 
    9698 
    9799============================================================== 
  • pykota/trunk/docs/installation.sgml

    r3472 r3506  
    842842          <listitem> 
    843843            <para> 
    844               The <application>pysnmp</application> Python module version 3.4.2, or higher, version 4 is recommanded. 
     844              The <application>pysnmp</application> Python module version 4.x, or higher. 
    845845              You can download it from <ulink url="http://pysnmp.sourceforge.net">http://pysnmp.sourceforge.net</ulink>. 
    846846            </para> 
  • 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) : 
  • pykota/trunk/README

    r3481 r3506  
    150150    - The Python-SNMP module to query printers for their page counter. 
    151151      (http://pysnmp.sourceforge.net) 
    152       IMPORTANT : version 3.4.2 or higher, preferably v4.x is now REQUIRED. 
    153       Versions 2.x won't work. 
     152      IMPORTANT : version v4.x is now REQUIRED. 
     153      Versions 3.x or earlier are not supported anymore. 
    154154    - The Python-OSD module to use the graphical print quota reminder. 
    155155      (http://repose.cx/pyosd/)