由于历史原因公司遗留了很多老旧设备,这些设备有很多的是 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']: # V5
if model == 'read':
device_params['ssh_password'] = device_snmp
return 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']: # V7
device_params['ssh_port'] = 830
return NetconfDevice(**device_params)
else:
raise ValueError('不支持该设备!')
else:
raise ValueError('不支持该厂商!')
但是最近 58 系列设备的读功能(SNMP)出现了问题。
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
from easysnmp import snmp_walk
def 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)
接下来就是从 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%#!!!
最后总结下经验教训吧,虽然最后查到的问题只是个版本的问题,但是为了解决这个问题前前后后浪费了大半天的时间也是郁闷。
这也说明在软件开发过程中,任何细节都不能放过,那些我们认为理所当然的事(版本应该向下兼容)也有可能出“黑天鹅”事件。所以在以后的开发中第三方包也应该在考虑范围之内,当时开发的包是什么版本就强制指定,即使在后续需要升级也要在版本改动后进行大量测试!