基于pysnmp封装v1、v2c、v3版本。支持getCmd、nextCmd方式请求。

1、库版本

  • python 3.6
  • pysnmp 4.4

2、简单的get请求

测试环境,基于本机电脑 snmp v1版本进行调试的。

g = getCmd(SnmpEngine(),  # 创建SNMP引擎
           CommunityData('xxxxxx'),  # 团体属性
           UdpTransportTarget((ip, 161), timeout=1, retries=0),  # 认证
           ContextData(),  # 创建SNMP上下文信息
           ObjectType(ObjectIdentity(oid))  # 创建MIB节点对象
     )

3、遇到的问题

可能会遇到:TypeError: () takes 3 positional arguments but 4 were given。这个报错
详情请见 https://github.com/pyasn1/pyasn1/issues/28

3、完整代码

from pysnmp.hlapi import *
from pysnmp.error import PySnmpError


class NetSNMP(object):
    """
    基于pySnmp的封装,支持v1、v2c、v3版本连接
    ----------
    version(int)
        *必填
        版本号(1、2、3)
    ip(str)
        *必填
        ip地址(0.0.0.0)
    mibName(str)
        *选填,默认None
        要访问的 MIB 模块的名称(SNMPv2-MIB)
    objectName(str)
        *选填,默认None
        要访问的对象的名称(sysName)
    oid(str)
        *选填,默认None
        oid(1.3.6.1.2.1.1.1)
    timeout(int)
        *选填,默认1
        超时时间(s)
    retries(int)
        *选填,默认0
        重试次数(1)
    mib_list(dict)
        [{"key":"IF-MIB","value":"ifDescr"}]
        *选填,多个mib列表
    oid_list
        ["oid","oid"...]
        *选填,多个oid列表
    ----------
    查询优先级:oid、mib、oidList、mibList
    """

    def __init__(self, version=1, ip=None, mibName=None, objectName=None, oid=None, data=None, timeout=1, retries=0,
                 mib_list=None, oid_list=None):
        self.version = version
        self.ip = ip
        self.mibName = mibName
        self.objectName = objectName
        self.data = data
        self.oid = oid
        self.timeout = timeout
        self.retries = retries
        self.mib_list = mib_list
        self.oid_list = oid_list

        self.Community = None

    # 公共参数
    def com(self):
        # 初始化引擎
        engine = SnmpEngine()
        # 配置目标主机
        target = UdpTransportTarget((self.data["ip"], self.data["port"]), timeout=self.timeout, retries=self.retries)
        # 实例化上下文对象
        context = ContextData()
        return engine, target, context

    # get方式getCmd
    def get(self):
        res = self.com()
        engine = res[0]
        target = res[1]
        context = res[2]
        lookupMib = False
        if self.oid:
            obj = ObjectType(ObjectIdentity(self.oid))
        else:
            lookupMib = True
            obj = ObjectType(ObjectIdentity(self.mibName, self.objectName, 0))
        errList = []
        for i in range(self.retries + 1):
            g = getCmd(engine, self.Community, target, context, obj, lookupMib=lookupMib)
            try:
                errorIndication, errorStatus, errorIndex, varBinds = next(g)
                if errorIndication or errorStatus:
                    # 处理 SNMP 异常
                    raise PySnmpError(errorIndication)
                else:
                    # 打印输出
                    for i in varBinds:
                        data = {
                            "code": 200,
                            "result": str(i[1])
                        }
                        return data
            except PySnmpError as e:
                if i < self.retries:
                    # 处理超时异常,进行重试
                    err = f"连接超时, 重试次数 ({i + 1}/{self.retries})..."
                    errList.append(err)
                else:
                    err = f"连接异常,重试次数: {self.retries} 异常信息: {e}"
                    errList.append(err)
        data = {
            "code": 500,
            "result": errList
        }
        return data

    # get多个oid/mib方式getCmd
    def getList(self):
        res = self.com()
        engine = res[0]
        target = res[1]
        context = res[2]
        obj = []
        lookupMib = False
        if self.oid_list is not None:
            for o in self.oid_list:
                obj.append(ObjectType(ObjectIdentity(o)))
        elif self.mib_list:
            lookupMib = True
            for o in self.mib_list:
                obj.append(ObjectType(ObjectIdentity(o["key"], o["value"], 0)))
        errList = []
        resList = []
        for i in range(self.retries + 1):
            g = getCmd(engine, self.Community, target, context, *obj, lookupMib=lookupMib)
            try:
                errorIndication, errorStatus, errorIndex, varBinds = next(g)

                if errorIndication or errorStatus:
                    # 处理 SNMP 异常
                    raise PySnmpError(errorIndication)
                else:
                    # 打印输出
                    for key, value in enumerate(varBinds):
                        name = str(value[0])
                        if self.mib_list:
                            name = self.mib_list[key]["value"]
                        arr = {
                            "name": name,
                            "res": value[1].prettyPrint(),
                        }
                        resList.append(arr)
                    data = {
                        "code": 200,
                        "result": resList
                    }
                    return data
            except PySnmpError as e:
                if i < self.retries:
                    # 处理超时异常,进行重试
                    err = f"连接超时, 重试次数 ({i + 1}/{self.retries})..."
                    errList.append(err)
                else:
                    err = f"连接异常,重试次数: {self.retries} 异常信息: {e}"
                    errList.append(err)
        data = {
            "code": 500,
            "result": errList
        }
        return data

    # walk方式nextCmd
    def walk(self):
        res = self.com()
        engine = res[0]
        target = res[1]
        context = res[2]
        lookupMib = False
        if self.oid:
            obj = ObjectType(ObjectIdentity(self.oid))
        else:
            lookupMib = True
            obj = ObjectType(ObjectIdentity(self.mibName, self.objectName))

        errList = []
        for i in range(self.retries + 1):
            g = nextCmd(engine, self.Community, target, context, obj, lexicographicMode=False, lookupMib=lookupMib)
            try:
                errorIndication, errorStatus, errorIndex, varBinds = next(g)
                if errorIndication or errorStatus:
                    # 处理 SNMP 异常
                    raise PySnmpError(errorIndication)
                else:
                    s = []
                    for a, b, c, d in g:
                        if d[0][1]:
                            res = d[0][1]
                            s.append(str(res))
                        else:
                            s.append(str(d[0][1]))

                    data = {
                        "code": 200,
                        "result": s
                    }
                    return data
            except PySnmpError as e:
                if i < self.retries:
                    # 处理超时异常,进行重试
                    err = f"连接超时, 重试次数 ({i + 1}/{self.retries})..."
                    errList.append(err)
                else:
                    err = f"连接异常,重试次数: {self.retries} 异常信息: {e}"
                    errList.append(err)
        data = {
            "code": 500,
            "result": errList
        }
        return data

    # walk多oid方式nextCmd
    def walkList(self):
        res = self.com()
        engine = res[0]
        target = res[1]
        context = res[2]
        obj = []
        lookupMib = False

        if self.oid_list is not None:
            for o in self.oid_list:
                obj.append(ObjectType(ObjectIdentity(o)))
        elif self.mib_list:
            lookupMib = False
            for o in self.mib_list:
                obj.append(ObjectType(ObjectIdentity(o["key"], o["value"])))
        errList = []

        for i in range(self.retries + 1):
            g = nextCmd(engine, self.Community, target, context, *obj, lexicographicMode=False, lookupMib=lookupMib)
            try:
                errorIndication, errorStatus, errorIndex, varBinds = next(g)
                varBinds = []
                if errorIndication or errorStatus:
                    # 处理 SNMP 异常
                    raise PySnmpError(errorIndication)
                else:
                    for _, _, _, v in g:
                        varBinds.extend(v)
                    result = {}
                    for varBind in varBinds:
                        oid = str(varBind[0])
                        value = varBind[1].prettyPrint()
                        mib = '.'.join(oid.split('.')[:-1])
                        if mib not in result:
                            result[mib] = []
                        result[mib].append({oid: value})
                    s = []
                    if self.mib_list:
                        for key, value in enumerate(result):
                            arr = {}
                            arr["name"] = self.mib_list[key]["value"]
                            arr["res"] = result[value]
                            s.append(arr)
                    else:
                        s = result
                    data = {
                        "code": 200,
                        "result": s
                    }
                    return data
            except PySnmpError as e:
                print(e)
                if i < self.retries:
                    # 处理超时异常,进行重试
                    err = f"连接超时, 重试次数 ({i + 1}/{self.retries})..."
                    errList.append(err)
                else:
                    err = f"连接异常,重试次数: {self.retries} 异常信息: {e}"
                    errList.append(err)
        data = {
            "code": 500,
            "result": errList
        }
        return data
    # V1
    def snmpV1(self, type):
        """
        snmp v1版本
        ----------
        type(str)
            类型 (get、walk)
        ----------
        """
        self.Community = CommunityData(self.data["pwd"], mpModel=0)
        if type == 'get':
            res = self.get()
        elif type == 'getList':
            res = self.getList()
        elif type == 'walkList':
            res = self.walkList()
        else:
            res = self.walk()
        return res

    # V2
    def snmpV2(self, type):
        """
        snmp v2c版本
        ----------
        type(str)
            类型 (get、walk)
        ----------
        """
        self.Community = CommunityData(self.data["pwd"], mpModel=1)
        if type == 'get':
            res = self.get()
        elif type == 'getList':
            res = self.getList()
        elif type == 'walkList':
            res = self.walkList()
        else:
            res = self.walk()
        return res

    # V3
    def snmpV3(self, type):
        """
        snmp v3版本,支持md5、sha认证加密
        ----------
        type(str)
            类型 (get、walk)
        ----------
        """
        authProtocol = self.data["authProtocol"]
        privProtocol = self.data["privProtocol"]
        user = self.data["user"]
        authKey = self.data["authKey"]
        privKey = self.data["privKey"]
        # md5加密
        if authProtocol == 'md5':
            if privProtocol == 'des':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACMD5AuthProtocol,
                    privProtocol=usmDESPrivProtocol,
                )
            elif privProtocol == '3des':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACMD5AuthProtocol,
                    privProtocol=usm3DESEDEPrivProtocol,
                )
            elif privProtocol == 'aes128':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACMD5AuthProtocol,
                    privProtocol=usmAesCfb128Protocol,
                )
            elif privProtocol == 'aes192':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACMD5AuthProtocol,
                    privProtocol=usmAesCfb192Protocol,
                )
            elif privProtocol == 'des':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACMD5AuthProtocol,
                    privProtocol=usmAesCfb256Protocol,
                )
            else:
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=None,
                    authProtocol=usmHMACMD5AuthProtocol,
                    privProtocol=usmNoPrivProtocol,
                )
        # sha加密
        if authProtocol == 'sha':
            if privProtocol == 'des':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACSHAAuthProtocol,
                    privProtocol=usmDESPrivProtocol,
                )
            elif privProtocol == '3des':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACSHAAuthProtocol,
                    privProtocol=usm3DESEDEPrivProtocol,
                )
            elif privProtocol == 'aes128':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACSHAAuthProtocol,
                    privProtocol=usmAesCfb128Protocol,
                )
            elif privProtocol == 'aes192':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACSHAAuthProtocol,
                    privProtocol=usmAesCfb192Protocol,
                )
            elif privProtocol == 'des':
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=privKey,
                    authProtocol=usmHMACSHAAuthProtocol,
                    privProtocol=usmAesCfb256Protocol,
                )
            else:
                self.Community = UsmUserData(
                    userName=user,
                    authKey=authKey,
                    privKey=None,
                    authProtocol=usmHMACSHAAuthProtocol,
                    privProtocol=usmNoPrivProtocol,
                )

        # no auth no priv
        if authProtocol is None and privProtocol is None:
            self.Community = UsmUserData(
                userName=user,
                authKey=None,
                privKey=None,
                authProtocol=usmNoAuthProtocol,
                privProtocol=usmNoPrivProtocol,
            )
        if type == 'get':
            res = self.get()
        elif type == 'getList':
            res = self.getList()
        elif type == 'walkList':
            res = self.walkList()
        else:
            res = self.walk()
        return res

    # snmp的get
    def getSnmp(self):
        """
        version:版本(1,2,3)
        mibName: mib库
        mib: MIB对象
        ip:IP地址
        port:端口号
        """
        if self.version == 1:
            return self.snmpV1('get')
        elif self.version == 2:
            return self.snmpV2('get')
        elif self.version == 3:
            return self.snmpV3('get')
        else:
            return False

    # snmp的WALK
    def walkSnmp(self):
        """
        version:版本(1,2,3)
        oid: oid
        ip:IP地址
        port:端口号
        """
        if self.version == 1:
            return self.snmpV1('walk')
        elif self.version == 2:
            return self.snmpV2('walk')
        elif self.version == 3:
            return self.snmpV3('walk')
        else:
            return False

    # snmp的getList
    def getListSnmp(self):
        """
        version:版本(1,2,3)
        oid: oid
        ip:IP地址
        port:端口号
        """

        if self.version == 1:
            return self.snmpV1('getList')
        elif self.version == 2:
            return self.snmpV2('getList')
        elif self.version == 3:
            return self.snmpV3('getList')
        else:
            return False

    # snmp的walkList
    def walkListSnmp(self):
        """
        version:版本(1,2,3)
        oid: oid
        ip:IP地址
        port:端口号
        """

        if self.version == 1:
            return self.snmpV1('walkList')
        elif self.version == 2:
            return self.snmpV2('walkList')
        elif self.version == 3:
            return self.snmpV3('walkList')
        else:
            return False


if __name__ == '__main__':
    ip = "你的ip"
    data = {
        "ip": ip,
        "port": 161,
        "pwd": "public",
    }
    walk_oid_list = [
        "1.3.6.1.2.1.2.2.1.8",
        "1.3.6.1.2.1.2.2.1.3",
    ]
    walk_mib_list = [
        {"key": "IF-MIB", "value": "ifOperStatus"},
        {"key": "IF-MIB", "value": "ifType"}
    ]
    get_mib_list = [
        {"key": "SNMPv2-MIB", "value": "sysDescr"},
        {"key": "SNMPv2-MIB", "value": "sysName"}
    ]
    get_oid_list = [
        "1.3.6.1.2.1.1.1.0",
        "1.3.6.1.2.1.1.5.0"
    ]
    """
    walk示例
    """
    # walk示例
    walkSnmp = NetSNMP(version=1, ip=ip, data=data, mibName="IF-MIB", objectName="ifOperStatus")
    res_walk = walkSnmp.walkSnmp()
    # {'code': 200, 'result': ['up', 'notPresent', 'down', 'down', 'up', 'notPresent', 'down', 'notPresent', 'notPresent', 'up', 'down', 'up']}
    # walk多mib示例
    walkListSnmp_mib = NetSNMP(version=1, ip=ip, data=data, mib_list=walk_mib_list)
    res_walk_list_mib = walkListSnmp_mib.walkListSnmp()
    # {'code': 200, 'result': [{'name': 'ifOperStatus', 'res': [{'1.3.6.1.2.1.2.2.1.8.2': '1'},...]}]}
    # walk多oid示例
    walkListSnmp_oid = NetSNMP(version=1, ip=ip, data=data, oid_list=walk_oid_list)
    res_walk_list_oid = walkListSnmp_oid.walkListSnmp()
    # {'code': 200, 'result': {'1.3.6.1.2.1.2.2.1.8': [{'1.3.6.1.2.1.2.2.1.8.2': '1'}, {'1.3.6.1.2.1.2.2.1.8.3': '6'},...]}}
    """
    get示例
    """
    # get示例
    getSnmp = NetSNMP(version=1, ip=ip, data=data, mibName="SNMPv2-MIB", objectName="sysDescr")
    res_get = getSnmp.getSnmp()
    # {'code': 200, 'result': 'Hardware: AMD64 Family 25 Model 80 Stepping 0 AT/AT COMPATIBLE - Software: Windows Version 6.3 (Build 22000 Multiprocessor Free)'}
    # get多mib示例
    getListSnmp_mib = NetSNMP(version=1, ip=ip, data=data, mib_list=get_mib_list)
    res_get_list_mib = getListSnmp_mib.getListSnmp()
    # {'code': 200, 'result': [{'name': 'sysDescr', 'res': 'Hardware: AMD64 Family 25 Model 80 Stepping 0 AT/AT COMPATIBLE - Software: Windows Version 6.3 (Build 22000 Multiprocessor Free)'}, {'name': 'sysName', 'res': 'ChenXu'}]}
    # get多oid示例
    getListSnmp_oid = NetSNMP(version=1, ip=ip, data=data, oid_list=get_oid_list)
    res_get_list_oid = getListSnmp_oid.getListSnmp()
    # {'code': 200, 'result': [{'name': '1.3.6.1.2.1.1.1.0', 'res': 'Hardware: AMD64 Family 25 Model 80 Stepping 0 AT/AT COMPATIBLE - Software: Windows Version 6.3 (Build 22000 Multiprocessor Free)'}, {'name': '1.3.6.1.2.1.1.5.0', 'res': 'ChenXu'}]}
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
封装 Axios 实例并封装 GET 请求,你可以按照以下步骤进行操作: 1. 首先,安装并引入 Axios 库。 ```bash npm install axios ``` ```javascript import axios from 'axios'; ``` 2. 创建 Axios 实例,并进行一些全局配置。 ```javascript const instance = axios.create({ baseURL: 'https://api.example.com', // 设置请求的基础URL timeout: 5000, // 设置请求超时时间 headers: { 'Content-Type': 'application/json' // 设置请求头 } }); ``` 在上述代码中,我们使用 `axios.create()` 方法创建了一个 Axios 实例,并指定了一些全局配置,如基础URL、超时时间和请求头。 3. 封装 GET 请求方法。 ```javascript function get(url, params) { return instance.get(url, { params }); } ``` 在上述代码中,我们封装了一个名为 `get` 的方法,该方法接受两个参数:`url` 表示请求的URL,`params` 表示请求的查询参数。我们使用 Axios 实例的 `get()` 方法发送 GET 请求,并将传入的 `params` 对象作为查询参数传递给 Axios。 4. 使用封装的 GET 请求。 ```javascript get('/api/example', { param1: 'value1', param2: 'value2' }) .then(response => { // 处理响应数据 }) .catch(error => { // 处理请求错误 }); ``` 在上述代码中,我们使用封装的 `get()` 方法发送 GET 请求,并传递了一个包含查询参数的对象作为第二个参数。通过 `then()` 方法处理成功的响应,通过 `catch()` 方法处理请求错误。 通过以上步骤,你成功封装了 Axios 实例并封装了 GET 请求方法。你可以在其他地方使用封装的方法来发送 GET 请求,并根据需要进行相应的处理。 希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值