首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异步PySNMP仪器控制器

异步PySNMP仪器控制器
EN

Stack Overflow用户
提问于 2017-03-11 16:58:10
回答 1查看 564关注 0票数 1

我需要编写简单的simple,其中一部分工作是通过asyncio.subprocess模块调用一些外部脚本。现在,我正在试验pysnmp,但是按照示例中稍作修改的代码不起作用:

代码语言:javascript
复制
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脚本将使用以下回溯失败。

代码语言:javascript
复制
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不太了解,那么,请给我指明正确的方向。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-11 18:28:16

这是因为CommandResponder <-> MIB控制器交互是当前同步。换句话说,您不能使用yield from MIB控制器,您只能从它获得return。它不可能是coroutine。一旦删除了这两件事,您的代码可能会正常工作。

用一种mgmtFun (在我前面链接的代码中)可以返回Future的方式重构pysnmp代码是绝对可行的,Future一旦完成Future就会触发其余的代码(例如sendVarBinds)。这将使您的MIB控制器异步。

这就是你需要的吗?然后考虑一下PR或FR来对抗脓抽筋症。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42738005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档