Python 封装SNMP调用接口

打印 上一主题 下一主题

主题 763|帖子 763|积分 2289

PySNMP 是一个纯粹用Python实现的SNMP,用PySNMP的最抽象的API为One-line Applications,其中有两类API:同步的和非同步的,都在模块pysnmp.entity.rfc3413.oneliner.cmdgen 中实现,如下是Get方式与Walk方式的基本实现.
首先需要在系统中安装SNMP客户端,对于Linux平台来说只需要执行如下配置过程即可.
  1. [root@localhost ~]# yum install -y net-snmp
  2. [root@localhost ~]# cat /etc/snmp/snmpd.conf |grep -vE "^#|^$"
  3. com2sec notConfigUser  default       public
  4. group   notConfigGroup v1           notConfigUser
  5. group   notConfigGroup v2c           notConfigUser
  6. view    systemview    included   .1
  7. view    systemview    included   .1
  8. access  notConfigGroup  ""  any  noauth  exact  systemview none none
  9. [root@localhost ~]# systemctl restart snmpd
  10. [root@localhost ~]# systemctl enable snmpd
复制代码
如果是Windows系统则需要在客户机服务列表,开启SNMP支持,并设置好一个团体名称,如下图。

当我们配置好客户端后,服务端就客户获取数据了,我们以一个OID序号为例,我们查询特定序号对应的名称,然后将其记录下来,例如下面这样。
  1. C:\Users\admin> snmpwalk -v 2c -c public 192.168.1.101 .1.3.6.1.2.1.25.2.2
  2. HOST-RESOURCES-MIB::hrMemorySize.0 = INTEGER: 2096632 KBytes
复制代码
首先我们不使用PySNMP模块直接开线程调用看看,该代码如下所示.
  1. import os,re,time
  2. # 通过SNMP收集主机CPU利用率: 通过SNMP协议,收集目标主机的CPU利用率(百分比),并返回JSON字符串.
  3. def Get_CPU_Info(addr):
  4.     try:
  5.         Head = ["HostName","CoreLoad","CpuUser","CpuSystem","CpuIdle"]
  6.         CPU = []
  7.         ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.1.5")
  8.         CPU.append(ret.read().split(":")[3].strip())
  9.         ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.25.3.3.1.2")
  10.         CPU.append(ret.read().split(":")[3].strip())
  11.         for i in [9,10,11]:
  12.             ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " 1.3.6.1.4.1.2021.11.{}.0".format(i))
  13.             ret = ret.read()
  14.             Info = ret.split(":")[3].strip()
  15.             CPU.append(Info)
  16.         return dict(zip(Head,CPU))
  17.     except Exception:
  18.         return 0
  19. # 通过SNMP获取系统CPU负载信息: 分别获取到系统的1,5,15分钟的负载信息,并返回JSON格式.
  20. def Get_Load_Info(addr):
  21.     try:
  22.         Head = ["HostName","Load1","Load5","Load15"]
  23.         SysLoad = []
  24.         ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.1.5")
  25.         SysLoad.append(ret.read().split(":")[3].strip())
  26.         ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.4.1.2021.10.1.3")
  27.         load = list(re.sub(".*STRING: ", "", ret.read()).split("\n"))
  28.         SysLoad.append(load[0])
  29.         SysLoad.append(load[1])
  30.         SysLoad.append(load[2])
  31.         return dict(zip(Head,SysLoad))
  32.     except Exception:
  33.         return 0
  34. # 通过SNMP获取系统内存占用: 内存利用率,获取到之后,将其转化为字典格式保存。
  35. def Get_Mem_Info(addr):
  36.     try:
  37.         Head = ["HostName","memTotalSwap","memAvailSwap","memTotalReal","memTotalFree"]
  38.         SysMem = []
  39.         ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.1.5")
  40.         SysMem.append(ret.read().split(":")[3].strip())
  41.         ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.4.1.2021.4")
  42.         mem = ret.read().split("\n")
  43.         for i in [2,3,4,6]:
  44.             SysMem.append(re.sub(".*INTEGER: ","",mem[i]).split(" ")[0])
  45.         return dict(zip(Head,SysMem))
  46.     except Exception:
  47.         return 0
  48. # 通过SNMP获取系统磁盘数据: 这个案例并不完整,我只写了一点,后面有个问题一直没有解决.
  49. def Get_Disk_Info(addr):
  50.     try:
  51.         dic = {}
  52.         list = []
  53.         ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " HOST-RESOURCES-MIB::hrStorageDescr")
  54.         DiskName = ret.read().split("\n")
  55.         ret =os.popen("snmpwalk -v 2c -c nmap " + addr + " HOST-RESOURCES-MIB::hrStorageUsed")
  56.         DiskUsed = ret.read().split("\n")
  57.         ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " HOST-RESOURCES-MIB::hrStorageSize")
  58.         DiskSize = ret.read().split("\n")
  59.         for i in range(1,len(DiskName) - 7):
  60.             dic["Name"]= DiskName[i + 5].split(":")[3]
  61.             dic["Used"]= DiskUsed[i + 5].split(":")[3]
  62.             dic["Size"]= DiskSize[i + 5].split(":")[3]
  63.             list.append(dic)
  64.         return list
  65.     except Exception:
  66.         return 0
  67. if __name__ == '__main__':
  68.     for i in range(100):
  69.         dic = Get_CPU_Info("192.168.1.20")
  70.         print(dic)
  71.         time.sleep(1)
复制代码
我们使用pysnmp模块来做,安装pysnmp很简单,执行命令pip install pysnmp 即可,安装后使用以下代码执行即可获取到目标数据,获取方式分为两种一种为Get另一种为Walk.
  1. from pysnmp.hlapi import *
  2. import os,sys
  3. class NetSNMP():
  4.     def __init__(self,address,region):
  5.         self.region = region
  6.         self.address = address
  7.     # 获取指定数据的方法
  8.     def GetNumber(self,oid,sub_oid,sub_id):
  9.         iterator = getCmd(SnmpEngine(),
  10.                           CommunityData(self.region),
  11.                           UdpTransportTarget((self.address, 161)),
  12.                           ContextData(),
  13.                           ObjectType(ObjectIdentity(oid, sub_oid, sub_id)))
  14.         errorIndication, errorStatus, errorIndex, varBinds = next(iterator)
  15.         if errorIndication:
  16.             return False
  17.         else:
  18.             if errorStatus:
  19.                 return False
  20.             else:
  21.                 for varBind in varBinds:
  22.                     return [x.prettyPrint() for x in varBind]
  23.     # 使用Walk拉取数据
  24.     def WalkNumber(self, oid):
  25.         res = []
  26.         for (errorIndication, errorStatus, errorIndex, varBinds) in nextCmd(SnmpEngine(),
  27.              CommunityData(self.region),UdpTransportTarget((self.address, 161)),ContextData(),
  28.              ObjectType(ObjectIdentity(oid)).addMibSource(
  29.              './site-packages/pysnmp/smi/mibs','pysnmp_mibs'),lexicographicMode=False):
  30.             if errorIndication:
  31.                 print(errorIndication, file=sys.stderr)
  32.                 break
  33.             elif errorStatus:
  34.                 print('%s at %s' % (errorStatus.prettyPrint(),
  35.                                     errorIndex and varBinds[int(errorIndex) - 1][0] or '?'),
  36.                       file=sys.stderr)
  37.                 break
  38.             else:
  39.                 for varBind in varBinds:
  40.                     res.append(str(varBind))
  41.         return res
  42. if __name__ == "__main__":
  43.     # 初始化
  44.     ptr = NetSNMP("192.168.81.130","public")
  45.     # 使用GET方式获取OID数据
  46.     ret = ptr.GetNumber("HOST-RESOURCES-MIB","hrMemorySize",0)
  47.     print("类型: {} --> 返回结果: {} --> 解析: {}".format(type(ret),ret,ret[1]))
  48.     # 使用Walk方式获取OID数据
  49.     ret = ptr.WalkNumber(".1.3.6.1.2.1.2.2.1.6")
  50.     for each in ret:
  51.         mac = each.split("=")[1]
  52.         if len(mac) > 1:
  53.             print("网卡接口: {}".format(mac))
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小小小幸运

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表