Python 封裝SNMP調用接口

lyshark 2022-07-23 20:28:12 阅读数:224

pythonsnmp接口

PySNMP 是一個純粹用Python實現的SNMP,用PySNMP的最抽象的API為One-line Applications,其中有兩類API:同步的和非同步的,都在模塊pysnmp.entity.rfc3413.oneliner.cmdgen 中實現,如下是Get方式與Walk方式的基本實現.

首先需要在系統中安裝SNMP客戶端,對於Linux平臺來說只需要執行如下配置過程即可.

[[email protected] ~]# yum install -y net-snmp
[[email protected] ~]# cat /etc/snmp/snmpd.conf |grep -vE "^#|^$"
com2sec notConfigUser default public
group notConfigGroup v1 notConfigUser
group notConfigGroup v2c notConfigUser
view systemview included .1
view systemview included .1
access notConfigGroup "" any noauth exact systemview none none
[[email protected] ~]# systemctl restart snmpd
[[email protected] ~]# systemctl enable snmpd

如果是Windows系統則需要在客戶機服務列錶,開啟SNMP支持,並設置好一個團體名稱,如下圖。

當我們配置好客戶端後,服務端就客戶獲取數據了,我們以一個OID序號為例,我們查詢特定序號對應的名稱,然後將其記錄下來,例如下面這樣。

C:\Users\admin> snmpwalk -v 2c -c public 192.168.1.101 .1.3.6.1.2.1.25.2.2
HOST-RESOURCES-MIB::hrMemorySize.0 = INTEGER: 2096632 KBytes

首先我們不使用PySNMP模塊直接開線程調用看看,該代碼如下所示.

import os,re,time
# 通過SNMP收集主機CPU利用率: 通過SNMP協議,收集目標主機的CPU利用率(百分比),並返回JSON字符串.
def Get_CPU_Info(addr):
try:
Head = ["HostName","CoreLoad","CpuUser","CpuSystem","CpuIdle"]
CPU = []
ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.1.5")
CPU.append(ret.read().split(":")[3].strip())
ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.25.3.3.1.2")
CPU.append(ret.read().split(":")[3].strip())
for i in [9,10,11]:
ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " 1.3.6.1.4.1.2021.11.{}.0".format(i))
ret = ret.read()
Info = ret.split(":")[3].strip()
CPU.append(Info)
return dict(zip(Head,CPU))
except Exception:
return 0
# 通過SNMP獲取系統CPU負載信息: 分別獲取到系統的1,5,15分鐘的負載信息,並返回JSON格式.
def Get_Load_Info(addr):
try:
Head = ["HostName","Load1","Load5","Load15"]
SysLoad = []
ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.1.5")
SysLoad.append(ret.read().split(":")[3].strip())
ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.4.1.2021.10.1.3")
load = list(re.sub(".*STRING: ", "", ret.read()).split("\n"))
SysLoad.append(load[0])
SysLoad.append(load[1])
SysLoad.append(load[2])
return dict(zip(Head,SysLoad))
except Exception:
return 0
# 通過SNMP獲取系統內存占用: 內存利用率,獲取到之後,將其轉化為字典格式保存。
def Get_Mem_Info(addr):
try:
Head = ["HostName","memTotalSwap","memAvailSwap","memTotalReal","memTotalFree"]
SysMem = []
ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.1.5")
SysMem.append(ret.read().split(":")[3].strip())
ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.4.1.2021.4")
mem = ret.read().split("\n")
for i in [2,3,4,6]:
SysMem.append(re.sub(".*INTEGER: ","",mem[i]).split(" ")[0])
return dict(zip(Head,SysMem))
except Exception:
return 0
# 通過SNMP獲取系統磁盤數據: 這個案例並不完整,我只寫了一點,後面有個問題一直沒有解决.
def Get_Disk_Info(addr):
try:
dic = {}
list = []
ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " HOST-RESOURCES-MIB::hrStorageDescr")
DiskName = ret.read().split("\n")
ret =os.popen("snmpwalk -v 2c -c nmap " + addr + " HOST-RESOURCES-MIB::hrStorageUsed")
DiskUsed = ret.read().split("\n")
ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " HOST-RESOURCES-MIB::hrStorageSize")
DiskSize = ret.read().split("\n")
for i in range(1,len(DiskName) - 7):
dic["Name"]= DiskName[i + 5].split(":")[3]
dic["Used"]= DiskUsed[i + 5].split(":")[3]
dic["Size"]= DiskSize[i + 5].split(":")[3]
list.append(dic)
return list
except Exception:
return 0
if __name__ == '__main__':
for i in range(100):
dic = Get_CPU_Info("192.168.1.20")
print(dic)
time.sleep(1)

我們使用pysnmp模塊來做,安裝pysnmp很簡單,執行命令pip install pysnmp 即可,安裝後使用以下代碼執行即可獲取到目標數據,獲取方式分為兩種一種為Get另一種為Walk.

from pysnmp.hlapi import *
import os,sys
class NetSNMP():
def __init__(self,address,region):
self.region = region
self.address = address
# 獲取指定數據的方法
def GetNumber(self,oid,sub_oid,sub_id):
iterator = getCmd(SnmpEngine(),
CommunityData(self.region),
UdpTransportTarget((self.address, 161)),
ContextData(),
ObjectType(ObjectIdentity(oid, sub_oid, sub_id)))
errorIndication, errorStatus, errorIndex, varBinds = next(iterator)
if errorIndication:
return False
else:
if errorStatus:
return False
else:
for varBind in varBinds:
return [x.prettyPrint() for x in varBind]
# 使用Walk拉取數據
def WalkNumber(self, oid):
res = []
for (errorIndication, errorStatus, errorIndex, varBinds) in nextCmd(SnmpEngine(),
CommunityData(self.region),UdpTransportTarget((self.address, 161)),ContextData(),
ObjectType(ObjectIdentity(oid)).addMibSource(
'./site-packages/pysnmp/smi/mibs','pysnmp_mibs'),lexicographicMode=False):
if errorIndication:
print(errorIndication, file=sys.stderr)
break
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'),
file=sys.stderr)
break
else:
for varBind in varBinds:
res.append(str(varBind))
return res
if __name__ == "__main__":
# 初始化
ptr = NetSNMP("192.168.81.130","public")
# 使用GET方式獲取OID數據
ret = ptr.GetNumber("HOST-RESOURCES-MIB","hrMemorySize",0)
print("類型: {} --> 返回結果: {} --> 解析: {}".format(type(ret),ret,ret[1]))
# 使用Walk方式獲取OID數據
ret = ptr.WalkNumber(".1.3.6.1.2.1.2.2.1.6")
for each in ret:
mac = each.split("=")[1]
if len(mac) > 1:
print("網卡接口: {}".format(mac))
版权声明:本文为[lyshark]所创,转载请带上原文链接,感谢。 https://gsmany.com/2022/204/202207231957165909.html