Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return the pretty name from a referenced OID #96

Open
swannie2 opened this issue May 25, 2021 · 5 comments
Open

Return the pretty name from a referenced OID #96

swannie2 opened this issue May 25, 2021 · 5 comments

Comments

@swannie2
Copy link

swannie2 commented May 25, 2021

I'm working through snimpy to see if it's right for my project and I've got it working but I've run into an issue that I can'f find a solution for. I'm querying sysObjectID and it correctly returns the OID for the system object, but I'd like for it to return the name reference from the MIB. Can this be done?

Here's my code:

#!/usr/bin/python3
from snimpy.manager import Manager as M
from snimpy.manager import load

load("CISCO-PRODUCTS-MIB")
load("SNMPv2-MIB")

m = M("192.168.10.40","staging",2)
print(m.sysObjectID)

Output from the code:

./test.py
1.3.6.1.4.1.9.1.1317

Output from the same OID via snmpget:

snmpget -v2c -c staging 192.168.10.40 sysObjectID.0
SNMPv2-MIB::sysObjectID.0 = OID: CISCO-PRODUCTS-MIB::cat3560cG8PC

Is there a way to get Snimpy to "follow" the reference to the other OID and return the proper name?

@johnworkman
Copy link

Yes, I had to do exactly this. For exactly the same issue of formatting the sysObjectID node.
Here's what I came up with:

def oidToNode(oid):
    if not oidToNode.nodes:
        for mib_loaded in snimpy.manager.loaded:
            for node in snimpy.mib.getNodes(mib_loaded):
                oidToNode.nodes[node.oid] = node
    oid2 = list(oid)
    while oid2:
        if tuple(oid2) in oidToNode.nodes:
            return oidToNode.nodes[tuple(oid2)]
        oid2.pop()
oidToNode.nodes = {}

Example:


>>> from snimpy.manager import load
>>> load("CISCO-PRODUCTS-MIB")
>>> n = oidToNode([1, 3, 6, 1, 4, 1, 9, 1, 1317])
>>> print(n)
cat3560cG8PC
>>> print(repr(n))
<Node CISCO-PRODUCTS-MIB::cat3560cG8PC from 'CISCO-PRODUCTS-MIB'>
>>> print(type(n))
<class 'snimpy.mib.Node'>
>>> n.oid
(1, 3, 6, 1, 4, 1, 9, 1, 1317)
>>>

Unfortunately, you may need to also abuse the repr function in the snimpy.mib.Node object to get the MIB name. If anyone knows a better way to do this, let us know so I can fix my scripts.

@swannie2
Copy link
Author

Thank you. I was looking at doing it in an alternate way like you suggested, but with not being a python expert (or an amateur for that matter) I felt like there was something obvious I was missing.

Off the top of my head, I think there are several other Cisco MIBs that pull counters and interface stats and reference other OIDs in similar ways. Overall I really like this library and if there was a way to say "follow the OID" on certain queries that would be extremely useful.

@johnworkman
Copy link

The only other place that I can think of where the returned data type points to another node is in ENTITY-MIB::entAliasMappingIdentifier. All of the counters should just be plain integer types.

Here's another little chunk of code that does something similar:

import re
def displayOid(oid):
    oid = [int(x) for x in str(oid).split(".")]
    n = snimpy.mib.getByOid(oid)
    m = re.match('<\S+ (.*) from .*$', repr(n))
    if m:
        mibname = m.group(1)
    else:
        mibname = ''
    pieces = 0 - (len(oid) - len(n.oid))
    if pieces != 0:
        remainder = oid[pieces:]
        remainder = [str(x) for x in remainder]
    else:
        remainder = []
    return ".".join([mibname] + remainder)

Example:

>>> from snimpy.manager import load
>>> load("CISCO-PRODUCTS-MIB")
>>> print(displayOid('1.3.6.1.4.1.9.1.1317'))
CISCO-PRODUCTS-MIB::cat3560cG8PC

$ snmpwalk --- ENTITY-MIB::entAliasMappingIdentifier
ENTITY-MIB::entAliasMappingIdentifier.1062.0 = OID: IF-MIB::ifIndex.8
ENTITY-MIB::entAliasMappingIdentifier.1063.0 = OID: IF-MIB::ifIndex.9
ENTITY-MIB::entAliasMappingIdentifier.1064.0 = OID: IF-MIB::ifIndex.10
ENTITY-MIB::entAliasMappingIdentifier.1065.0 = OID: IF-MIB::ifIndex.11
ENTITY-MIB::entAliasMappingIdentifier.1066.0 = OID: IF-MIB::ifIndex.12
ENTITY-MIB::entAliasMappingIdentifier.1067.0 = OID: IF-MIB::ifIndex.13
ENTITY-MIB::entAliasMappingIdentifier.1068.0 = OID: IF-MIB::ifIndex.14

$ snmptranslate -On IF-MIB::ifIndex.13
.1.3.6.1.2.1.2.2.1.1.13

$ python

>>> from snimpy.manager import load
>>> load("CISCO-PRODUCTS-MIB")
>>> load("IF-MIB")
>>> print(displayOid('1.3.6.1.2.1.2.2.1.1.13'))
IF-MIB::ifIndex.13

@swannie2
Copy link
Author

You're right, I was thinking of the PoE Mib which references entPhysical instead of IfMib for it's interface naming and appends it to the end of the oid. That's a different, but equally annoying, situation.

@vincentbernat
Copy link
Owner

We can implement the high level part of this using format (see https://www.python.org/dev/peps/pep-3101/#controlling-formatting-on-a-per-type-basis)

print("OID: {}, name: {:name}".format(oid, oid))

Is any of you interested in implementing this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants