背景介绍
由于历史原因公司遗留了很多老旧设备,这些设备有很多的是 H3C 的 58 系列,这些老设备有的不支持 Netconf
,所以在做 SDN
的时候只能判断多种情况来适配这些老旧设备。
华为新设备和 H3C 的 68 系列都用 Netconf
下发配置,如果是 H3C 的 58 系列或者其他老旧设备则用分为两种情况:读设备配置用 SNMP
,写设备配置用 SSH
。
# 匹配设备和型号对应的适配器
if agent_name == 'h3c':if model_name in ['S5800-60C-PWR', 'S5820X-26S', 'S5820-32F']: # V5if model == 'read':device_params['ssh_password'] = device_snmpreturn SNMPDevice(**device_params)elif model == 'write':return SSHDevice(**device_params)else:raise ValueError('不支持该操作!')elif model_name in ['S6800-2C', 'S6800-4C', 'S10506X', 'S10506', 'S6800-54QF']: # V7device_params['ssh_port'] = 830return NetconfDevice(**device_params)else:raise ValueError('不支持该设备!')
else:raise ValueError('不支持该厂商!')
出现问题
但是最近 58 系列设备的读功能(SNMP)出现了问题。
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-from easysnmp import snmp_walkdef main(oid):cursor = snmp_walk(oids=oid,hostname='xxx.xxx.xxx.xxx',community='xxx',version=2,use_sprint_value=True)print(cursor)if __name__ == '__main__':snmp_oid = 'IF-MIB::ifDescr'main(snmp_oid)
解决思路和解决方案
第一回合
报错的意思是找不到对应对象的 oid
,但是本地 MIB库
是没问题的。
MacBook:~ zhangyi$ snmpwalk -v 2c -c xxx xxx.xxx.xxx.xxx IF-MIB::ifDescr
IF-MIB::ifDescr.1 = STRING: GigabitEthernet1/0/1
IF-MIB::ifDescr.2 = STRING: GigabitEthernet1/0/2
IF-MIB::ifDescr.3 = STRING: GigabitEthernet1/0/3
IF-MIB::ifDescr.4 = STRING: GigabitEthernet1/0/4
IF-MIB::ifDescr.5 = STRING: GigabitEthernet1/0/5
IF-MIB::ifDescr.6 = STRING: GigabitEthernet1/0/6
IF-MIB::ifDescr.7 = STRING: GigabitEthernet1/0/7
IF-MIB::ifDescr.8 = STRING: GigabitEthernet1/0/8
IF-MIB::ifDescr.9 = STRING: GigabitEthernet1/0/9
IF-MIB::ifDescr.10 = STRING: GigabitEthernet1/0/10
......
所以大概是因为 IF-MIB::ifDescr
这个字符串用不了了,当我把它换成具体的 oid
号时是不报错了,但是返回的 oid_index
也没有了值。
if __name__ == '__main__':snmp_oid = '1.3.6.1.2.1.2.2.1.2'main(snmp_oid)
所以这个问题不是 IF-MIB::ifDescr
导致的。
第二回合
接下来就是从 easysnmp
这个 Python
包中找问题了,easysnmp
底层是调用的是 net-snmp
这个系统级包,所以先查询下 net-snmp
在本机上的版本。
snmpget --version
NET-SNMP version: 5.6.2.1
当我打开官网看到 net-snmp
最新版本是 5.9.1
的时候就怀疑是不是旧版本导致的问题,所以决定先升级试试。
我本机系统是 Mac OS X
,所以使用 brew
安装很方便。
brew install net-snmp
但是当我装好最新本版以后发现系统版本还是原来的 5.6.2.1
。
原因是我本机有多个版本,解决方法有两种:一种是删除旧版本,另一种是将新版本加到环境变量中。旧版本建议别删除万一系统中哪个应用用到呢,所以我们选择添加环境变量。
打开 ~/.bashrc
文件:
vi ~/.bashrc
添加到环境变量:
export PATH=/usr/local/Cellar/net-snmp/5.9.3/bin/:$PATH
重新打开终端这时就改成新版本了:
snmpget -V
NET-SNMP version: 5.9.3
但是结果很失望,还是不行!
第三回合
既然不是底层 net-snmp
的问题难道是 easysnmp
这个包的问题吗?
重新版本后发现确实比之前的版本高一点。
pip list | grep easysnmp
easysnmp 0.2.6
之前用的版本是 0.2.5
,现在最新的是 0.2.6
。
但按道理说应该新版本会向下兼容的,为了打消疑虑决定将版本回退到 0.2.5
。
当我把版本降到 0.2.5
之后一切都正常了!
我:@#$^&%!$# ……*&%¥&@34%#!!!
总结
最后总结下经验教训吧,虽然最后查到的问题只是个版本的问题,但是为了解决这个问题前前后后浪费了大半天的时间也是郁闷。
这也说明在软件开发过程中,任何细节都不能放过,那些我们认为理所当然的事(版本应该向下兼容)也有可能出“黑天鹅”事件。所以在以后的开发中第三方包也应该在考虑范围之内,当时开发的包是什么版本就强制指定,即使在后续需要升级也要在版本改动后进行大量测试!