2017-03-11 8 views
0

asyncio.subprocessモジュールを介して外部スクリプトを呼び出すのがジョブの一部である場合、簡単なSNMPレスポンダを書く必要があります。今、私はpysnmpで実験が、実施例から、わずかに変更されたコードは動作しません。次のです:PySNMP Instrumentation Controller with asyncio

import asyncio                                  

from pysnmp.entity import engine, config                           
from pysnmp.entity.rfc3413 import cmdrsp, context                         
from pysnmp.carrier.asyncio.dgram import udp                          
from pysnmp.smi import instrum                              
from pysnmp.proto.api import v2c                             

snmpEngine = engine.SnmpEngine()                             

config.addTransport(                                
    snmpEngine,                                  
    udp.domainName,                                 
    udp.UdpTransport().openServerMode(('0.0.0.0', 161))                        
)                                     

# config.addV1System(snmpEngine, 'my-area', 'public')                        
config.addV1System(snmpEngine, 'public', 'public', contextName='my-context')                  
config.addV1System(snmpEngine, 'private', 'private', contextName='my-context')                  

# Allow full MIB access for each user at VACM                          
config.addVacmUser(snmpEngine, 2, "public", 'noAuthNoPriv', (1, 3, 6, 1, 2, 1), (1, 3, 6, 1, 2, 1))             
config.addVacmUser(snmpEngine, 2, "private", 'noAuthNoPriv', (1, 3, 6, 1, 2, 1), (1, 3, 6, 1, 2, 1))            

# Create an SNMP context                               
snmpContext = context.SnmpContext(snmpEngine)                          

# Very basic Management Instrumentation Controller without                       
# any Managed Objects attached. It supports only GET's and                       
# always echos request var-binds in response.                          
class EchoMibInstrumController(instrum.AbstractMibInstrumController):                    
    @asyncio.coroutine                                
    def readVars(self, varBinds, acInfo=(None, None)):                        
     yield from asyncio.sleep(1)                             
     return [(ov[0], v2c.OctetString('You queried OID %s' % ov[0])) for ov in varBinds]               

# Create a custom Management Instrumentation Controller and register at                    
# SNMP Context under ContextName 'my-context'                          
snmpContext.registerContextName(                             
    v2c.OctetString('my-context'), # Context Name                         
    EchoMibInstrumController() # Management Instrumentation                      
)                                     

# Register GET&SET Applications at the SNMP engine for a custom SNMP context                  
cmdrsp.GetCommandResponder(snmpEngine, snmpContext)                         
cmdrsp.SetCommandResponder(snmpEngine, snmpContext)                         

loop = asyncio.get_event_loop()                              
loop.run_forever() 

コマンドsnmpget -v 2c -c public 127.0.0.1 .1.3.6.1.2.1.1.1.0スクリプトは、次のトレースバックで失敗し、次でクエリを作成しようとします。

Exception in callback AbstractTransportDispatcher._cbFun(<pysnmp.carri...x7f4c7540d518>, ('127.0.0.1', 44209), b'0)\x02\x01\...1\x00\x05\x00') 
handle: <Handle AbstractTransportDispatcher._cbFun(<pysnmp.carri...x7f4c7540d518>, ('127.0.0.1', 44209), b'0)\x02\x01\...1\x00\x05\x00')>  
Traceback (most recent call last):                            
    File "/usr/lib/python3.4/asyncio/events.py", line 120, in _run                    
    self._callback(*self._args)                             
    File "/opt/profiset2/lib/python3.4/site-packages/pysnmp/carrier/base.py", line 70, in _cbFun             
    self, transportDomain, transportAddress, incomingMessage                     
    File "/opt/profiset2/lib/python3.4/site-packages/pysnmp/entity/engine.py", line 154, in __receiveMessageCbFun         
    self, transportDomain, transportAddress, wholeMsg                       
    File "/opt/profiset2/lib/python3.4/site-packages/pysnmp/proto/rfc3412.py", line 421, in receiveMessage          
    PDU, maxSizeResponseScopedPDU, stateReference)                        
    File "/opt/profiset2/lib/python3.4/site-packages/pysnmp/entity/rfc3413/cmdrsp.py", line 140, in processPdu         
    (self.__verifyAccess, snmpEngine))                           
    File "/opt/profiset2/lib/python3.4/site-packages/pysnmp/entity/rfc3413/cmdrsp.py", line 247, in handleMgmtOperation       
    mgmtFun(v2c.apiPDU.getVarBinds(PDU), (acFun, acCtx)))                      
    File "/opt/profiset2/lib/python3.4/site-packages/pysnmp/entity/rfc3413/cmdrsp.py", line 46, in sendVarBinds         
    v2c.apiPDU.setVarBinds(PDU, varBinds)                          
    File "/opt/profiset2/lib/python3.4/site-packages/pysnmp/proto/api/v1.py", line 135, in setVarBinds           
    varBindList.getComponentByPosition(idx), varBind                       
    File "/opt/profiset2/lib/python3.4/site-packages/pysnmp/proto/api/v1.py", line 38, in setOIDVal            
    oid, val = oidVal[0], oidVal[1]                            
TypeError: 'Future' object does not support indexing 

は私が愚かな何かをやっているとすることができ、私はSNMPについて多くを知らないことを認め、その後、正しい方向に私を指示してください。

答えて

0

CommandResponder < - > MIBコントローラの対話がcurrently synchronousであるために起こります。つまり、yield from MIBコントローラは使用できません。その場合はreturnしか使用できません。また、coroutineにすることはできません。これらの2つを削除すると、コードが正常に動作する可能性があります。

mgmtFun(私は上記のリンクされたコードで)Futureが完了すると、コード(例えばsendVarBinds)の残りの部分を発射Futureを返すことができることのようにpysnmpコードをリファクタリングすることは間違いなく実現可能です。これにより、MIBコントローラを非同期にすることができます。

これは必要なものですか?次に、pysnmpに対するPRまたはFRを考慮する。