I'm trying to write a program that manages a complex of devices via SNMP. I use Python 3 as a programming language. Reading SNMP variables from managed devices is fine. It is impossible to execute netsnmp.snmpset in any way . Example:

>>> import netsnmp >>> x1 = '11:22:33:44:55:66' >>> ss = netsnmp.Session(Version = 2, DestHost = '172.17.132.73', Community="public") >>> tag = '.1.3.6.1.4.1.<Моя фирма>.5.1.2.1.3.10.1' >>> vb = netsnmp.Varbind(tag, '0', x1, 'STRING') >>> snmpe = netsnmp.snmpset(vb, ss) 

The following error is displayed:

 Traceback (innermost last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.5/dist-packages/netsnmp/client.py", line 246, in snmpset var_list.append(Varbind(arg)) File "/usr/local/lib/python3.5/dist-packages/netsnmp/client.py", line 64, in __init__ match = regex.match(tag) TypeError: expected string or bytes-like object 

If you look at the outcomes indicated in the presentation, you can see that the abuse goes to the tag field in the vb object. But he - just STRING !!!. So the meaning of the error message is completely incomprehensible to me. I tried to remove the starting point in the OID, I tried to add the "0" at the end myself - no effect.

What kind of mystic?

    1 answer 1

    Try this:

     snmpe = snmpset(vb, Version=2, DestHost='172.17.132.73', Community="public") 

    I had to look at the library code :

     def snmpset(*args, **kargs): sess = Session(**kargs) var_list = VarList() for arg in args: if isinstance(arg, netsnmp.client.Varbind): var_list.append(arg) else: var_list.append(Varbind(arg)) res = sess.set(var_list) return res 

    Here you can see that everything that is passed to the function as a list of parameters (args) is considered Varbind , and the named parameters (kargs) are Session parameters.

    Therefore, when running netsnmp.snmpset(vb, ss) object in ss ( Session ) did not pass the test if isinstance(arg, netsnmp.client.Varbind): and got into the Varbind constructor as a tag :

     class Varbind(object): def __init__(self, tag=None, iid=None, val=None, type=None): self.tag = STR(tag) self.iid = STR(iid) self.val = STR(val) self.type = STR(type) # parse iid out of tag if needed if iid == None and tag != None: regex = re.compile(r'^((?:\.\d+)+|(?:\w+(?:[-:]*\w+)+))\.?(.*)$') match = regex.match(tag) if match: (self.tag, self.iid) = match.group(1,2) ... 

    Well, and as was in error, regex.match works with strings and bytes.

    • I do not think that this will solve the problem ... For the following reasons: - Sergey
    • 1) I started writing this code in exactly this syntax. Then I fixed it on what I showed, just to reduce the amount of code. - Sergey
    • Did you run what I wrote you in response? - gil9red
    • one
      Because this is how *args works in function parameters. This is part of the python syntax. Take the function def foo(*args, **kwargs) , when you call it with the following parameters: foo(1, 2, 3, flag=True, name="Bar") , then in this function args=[1, 2 ,3] , and kwargs={"flag": True, "name": "Bar"} . Therefore, parameters without a name were included in the loop, and the named parameters were passed to the Session constructor. In general, these two special parameters can be called whatever you like, the main thing is the number * . * - list (or tuple, you need to look), ** - dictionary - gil9red
    • one
      In *args tuple will still lie, but it does not differ from the list in this situation. @Sergey, now it became clear? :) - gil9red