diff options
Diffstat (limited to 'pysnmp/smi/view.py')
-rw-r--r-- | pysnmp/smi/view.py | 255 |
1 files changed, 163 insertions, 92 deletions
diff --git a/pysnmp/smi/view.py b/pysnmp/smi/view.py index e9fd405e..46ce5991 100644 --- a/pysnmp/smi/view.py +++ b/pysnmp/smi/view.py @@ -6,13 +6,6 @@ # import sys -from pysnmp import debug -from pysnmp.smi import error -from pysnmp.smi.indices import OidOrderedDict -from pysnmp.smi.indices import OrderedDict - -__all__ = ['MibViewController'] - if sys.version_info[0] <= 2: import types @@ -22,52 +15,69 @@ else: classTypes = (type,) instanceTypes = (object,) +from pysnmp import debug +from pysnmp.smi import error +from pysnmp.smi.indices import OidOrderedDict +from pysnmp.smi.indices import OrderedDict + +__all__ = ['MibViewController'] + class MibViewController(object): def __init__(self, mibBuilder): self.mibBuilder = mibBuilder self.lastBuildId = -1 - self.__mibSymbolsIdx = OrderedDict() + self._mibSymbolsIdx = OrderedDict() # Indexing part + def _sortFun(self, name): + # This is potentially ambiguous mapping. Sort modules in + # ascending age for resolution + mb = self.mibBuilder + + if mb.moduleID in mb.mibSymbols[name]: + mib = mb.mibSymbols[name][mb.moduleID] + revs = mib.getRevisions() + if revs: + return revs[0] + + return '1970-01-01 00:00' + def indexMib(self): if self.lastBuildId == self.mibBuilder.lastBuildId: return - debug.logger & debug.FLAG_MIB and debug.logger('indexMib: re-indexing MIB view') + debug.logger & debug.FLAG_MIB and debug.logger( + 'indexMib: re-indexing MIB view') MibScalarInstance, = self.mibBuilder.importSymbols( - 'SNMPv2-SMI', 'MibScalarInstance' - ) + 'SNMPv2-SMI', 'MibScalarInstance') # # Create indices # # Module name -> module-scope indices - self.__mibSymbolsIdx.clear() + self._mibSymbolsIdx.clear() - # Oid <-> label indices + globMibMod = { + 'oidToLabelIdx': OidOrderedDict(), + 'labelToOidIdx': {}, + 'varToNameIdx': {}, + 'typeToModIdx': OrderedDict(), + 'oidToModIdx': {} + } - # This is potentially ambiguous mapping. Sort modules in - # ascending age for resolution - def __sortFun(x, b=self.mibBuilder): - if b.moduleID in b.mibSymbols[x]: - m = b.mibSymbols[x][b.moduleID] - r = m.getRevisions() - if r: - return r[0] + self._mibSymbolsIdx[''] = globMibMod - return "1970-01-01 00:00" + # Oid <-> label indices - modNames = list(self.mibBuilder.mibSymbols.keys()) - modNames.sort(key=__sortFun) + modNames = sorted(self.mibBuilder.mibSymbols, key=self._sortFun) # Index modules names - for modName in [''] + modNames: - # Modules index - self.__mibSymbolsIdx[modName] = mibMod = { + for modName in modNames: + mibMod = { 'oidToLabelIdx': OidOrderedDict(), 'labelToOidIdx': {}, 'varToNameIdx': {}, @@ -75,76 +85,93 @@ class MibViewController(object): 'oidToModIdx': {} } - if not modName: - globMibMod = mibMod - continue + self._mibSymbolsIdx[modName] = mibMod # Types & MIB vars indices for n, v in self.mibBuilder.mibSymbols[modName].items(): if n == self.mibBuilder.moduleID: # do not index this continue # special symbol + if isinstance(v, classTypes): if n in mibMod['typeToModIdx']: raise error.SmiError( - 'Duplicate SMI type %s::%s, has %s' % (modName, n, mibMod['typeToModIdx'][n]) - ) + 'Duplicate SMI type %s::%s, has ' + '%s' % (modName, n, mibMod['typeToModIdx'][n])) + globMibMod['typeToModIdx'][n] = modName mibMod['typeToModIdx'][n] = modName + elif isinstance(v, instanceTypes): if isinstance(v, MibScalarInstance): continue + if n in mibMod['varToNameIdx']: raise error.SmiError( - 'Duplicate MIB variable %s::%s has %s' % (modName, n, mibMod['varToNameIdx'][n]) - ) + 'Duplicate MIB variable %s::%s has ' + '%s' % (modName, n, mibMod['varToNameIdx'][n])) + globMibMod['varToNameIdx'][n] = v.name mibMod['varToNameIdx'][n] = v.name - # Potentionally ambiguous mapping ahead + + # Potentially ambiguous mapping ahead globMibMod['oidToModIdx'][v.name] = modName mibMod['oidToModIdx'][v.name] = modName globMibMod['oidToLabelIdx'][v.name] = (n,) mibMod['oidToLabelIdx'][v.name] = (n,) + else: raise error.SmiError( - 'Unexpected object %s::%s' % (modName, n) - ) + 'Unexpected object %s::%s' % (modName, n)) # Build oid->long-label index - oidToLabelIdx = self.__mibSymbolsIdx['']['oidToLabelIdx'] - labelToOidIdx = self.__mibSymbolsIdx['']['labelToOidIdx'] + oidToLabelIdx = self._mibSymbolsIdx['']['oidToLabelIdx'] + labelToOidIdx = self._mibSymbolsIdx['']['labelToOidIdx'] + prevOid = () baseLabel = () - for key in oidToLabelIdx.keys(): + + for key in oidToLabelIdx: keydiff = len(key) - len(prevOid) + if keydiff > 0: if prevOid: if keydiff == 1: baseLabel = oidToLabelIdx[prevOid] + else: baseLabel += key[-keydiff:-1] else: baseLabel = () + elif keydiff < 0: baseLabel = () keyLen = len(key) + i = keyLen - 1 + while i: k = key[:i] + if k in oidToLabelIdx: baseLabel = oidToLabelIdx[k] + if i != keyLen - 1: baseLabel += key[i:-1] + break + i -= 1 + # Build oid->long-label index oidToLabelIdx[key] = baseLabel + oidToLabelIdx[key] + # Build label->oid index labelToOidIdx[oidToLabelIdx[key]] = key prevOid = key # Build module-scope oid->long-label index - for mibMod in self.__mibSymbolsIdx.values(): - for oid in mibMod['oidToLabelIdx'].keys(): + for mibMod in self._mibSymbolsIdx.values(): + for oid in mibMod['oidToLabelIdx']: mibMod['oidToLabelIdx'][oid] = oidToLabelIdx[oid] mibMod['labelToOidIdx'][oidToLabelIdx[oid]] = oid @@ -154,9 +181,11 @@ class MibViewController(object): def getOrderedModuleName(self, index): self.indexMib() - modNames = self.__mibSymbolsIdx.keys() + + modNames = self._mibSymbolsIdx if modNames: return modNames[index] + raise error.SmiError('No modules loaded at %s' % self) def getFirstModuleName(self): @@ -167,69 +196,89 @@ class MibViewController(object): def getNextModuleName(self, modName): self.indexMib() + try: - return self.__mibSymbolsIdx.nextKey(modName) + return self._mibSymbolsIdx.nextKey(modName) + except KeyError: raise error.SmiError( - 'No module next to %s at %s' % (modName, self) - ) + 'No module next to %s at %s' % (modName, self)) # MIB tree node management - def __getOidLabel(self, nodeName, oidToLabelIdx, labelToOidIdx): + def _getOidLabel(self, nodeName, oidToLabelIdx, labelToOidIdx): """getOidLabel(nodeName) -> (oid, label, suffix)""" if not nodeName: return nodeName, nodeName, () + if nodeName in labelToOidIdx: return labelToOidIdx[nodeName], nodeName, () + if nodeName in oidToLabelIdx: return nodeName, oidToLabelIdx[nodeName], () + if len(nodeName) < 2: return nodeName, nodeName, () - oid, label, suffix = self.__getOidLabel( - nodeName[:-1], oidToLabelIdx, labelToOidIdx - ) + + oid, label, suffix = self._getOidLabel( + nodeName[:-1], oidToLabelIdx, labelToOidIdx) + suffix = suffix + nodeName[-1:] + resLabel = label + tuple([str(x) for x in suffix]) if resLabel in labelToOidIdx: return labelToOidIdx[resLabel], resLabel, () + resOid = oid + suffix if resOid in oidToLabelIdx: return resOid, oidToLabelIdx[resOid], () + return oid, label, suffix def getNodeNameByOid(self, nodeName, modName=''): self.indexMib() - if modName in self.__mibSymbolsIdx: - mibMod = self.__mibSymbolsIdx[modName] + + if modName in self._mibSymbolsIdx: + mibMod = self._mibSymbolsIdx[modName] + else: raise error.SmiError('No module %s at %s' % (modName, self)) - oid, label, suffix = self.__getOidLabel( - nodeName, mibMod['oidToLabelIdx'], mibMod['labelToOidIdx'] - ) + + oid, label, suffix = self._getOidLabel( + nodeName, mibMod['oidToLabelIdx'], mibMod['labelToOidIdx']) + if oid == label: raise error.NoSuchObjectError( - str='Can\'t resolve node name %s::%s at %s' % - (modName, nodeName, self) - ) + str='Cannot resolve node name %s::%s at ' + '%s' % (modName, nodeName, self)) + debug.logger & debug.FLAG_MIB and debug.logger( - 'getNodeNameByOid: resolved %s:%s -> %s.%s' % (modName, nodeName, label, suffix)) + 'getNodeNameByOid: resolved %s:%s -> ' + '%s.%s' % (modName, nodeName, label, suffix)) + return oid, label, suffix def getNodeNameByDesc(self, nodeName, modName=''): self.indexMib() - if modName in self.__mibSymbolsIdx: - mibMod = self.__mibSymbolsIdx[modName] + + if modName in self._mibSymbolsIdx: + mibMod = self._mibSymbolsIdx[modName] + else: raise error.SmiError('No module %s at %s' % (modName, self)) + if nodeName in mibMod['varToNameIdx']: oid = mibMod['varToNameIdx'][nodeName] + else: raise error.NoSuchObjectError( - str='No such symbol %s::%s at %s' % (modName, nodeName, self) - ) + str='No such symbol %s::%s at ' + '%s' % (modName, nodeName, self)) + debug.logger & debug.FLAG_MIB and debug.logger( - 'getNodeNameByDesc: resolved %s:%s -> %s' % (modName, nodeName, oid)) + 'getNodeNameByDesc: resolved %s:%s -> ' + '%s' % (modName, nodeName, oid)) + return self.getNodeNameByOid(oid, modName) def getNodeName(self, nodeName, modName=''): @@ -238,28 +287,36 @@ class MibViewController(object): try: # First try nodeName as an OID/label return self.getNodeNameByOid(nodeName, modName) + except error.NoSuchObjectError: # ...on failure, try as MIB symbol oid, label, suffix = self.getNodeNameByDesc(nodeName[0], modName) + # ...with trailing suffix return self.getNodeNameByOid(oid + suffix + nodeName[1:], modName) def getOrderedNodeName(self, index, modName=''): self.indexMib() - if modName in self.__mibSymbolsIdx: - mibMod = self.__mibSymbolsIdx[modName] + + if modName in self._mibSymbolsIdx: + mibMod = self._mibSymbolsIdx[modName] + else: raise error.SmiError('No module %s at %s' % (modName, self)) + if not mibMod['oidToLabelIdx']: raise error.NoSuchObjectError( - str='No variables at MIB module %s at %s' % (modName, self) - ) + str='No variables at MIB module %s at ' + '%s' % (modName, self)) + try: oid, label = mibMod['oidToLabelIdx'].items()[index] + except KeyError: raise error.NoSuchObjectError( - str='No symbol at position %s in MIB module %s at %s' % (index, modName, self) - ) + str='No symbol at position %s in MIB module %s at ' + '%s' % (index, modName, self)) + return oid, label, () def getFirstNodeName(self, modName=''): @@ -272,55 +329,67 @@ class MibViewController(object): oid, label, suffix = self.getNodeName(nodeName, modName) try: return self.getNodeName( - self.__mibSymbolsIdx[modName]['oidToLabelIdx'].nextKey(oid) + suffix, modName - ) + self._mibSymbolsIdx[modName]['oidToLabelIdx'].nextKey(oid) + suffix, + modName) + except KeyError: raise error.NoSuchObjectError( - str='No name next to %s::%s at %s' % (modName, nodeName, self) - ) + str='No name next to %s::%s at ' + '%s' % (modName, nodeName, self)) def getParentNodeName(self, nodeName, modName=''): oid, label, suffix = self.getNodeName(nodeName, modName) + if len(oid) < 2: raise error.NoSuchObjectError( - str='No parent name for %s::%s at %s' % - (modName, nodeName, self) - ) + str='No parent name for %s::%s at ' + '%s' % (modName, nodeName, self)) + return oid[:-1], label[:-1], oid[-1:] + suffix def getNodeLocation(self, nodeName, modName=''): oid, label, suffix = self.getNodeName(nodeName, modName) - return self.__mibSymbolsIdx['']['oidToModIdx'][oid], label[-1], suffix + return (self._mibSymbolsIdx['']['oidToModIdx'][oid], label[-1], + suffix) # MIB type management def getTypeName(self, typeName, modName=''): self.indexMib() - if modName in self.__mibSymbolsIdx: - mibMod = self.__mibSymbolsIdx[modName] + + if modName in self._mibSymbolsIdx: + mibMod = self._mibSymbolsIdx[modName] + else: raise error.SmiError( - 'No module %s at %s' % (modName, self) - ) + 'No module %s at %s' % (modName, self)) + if typeName in mibMod['typeToModIdx']: m = mibMod['typeToModIdx'][typeName] + else: raise error.NoSuchObjectError( - str='No such type %s::%s at %s' % (modName, typeName, self) - ) + str='No such type %s::%s at ' + '%s' % (modName, typeName, self)) + return m, typeName def getOrderedTypeName(self, index, modName=''): self.indexMib() - if modName in self.__mibSymbolsIdx: - mibMod = self.__mibSymbolsIdx[modName] + + if modName in self._mibSymbolsIdx: + mibMod = self._mibSymbolsIdx[modName] + else: raise error.SmiError('No module %s at %s' % (modName, self)) + if not mibMod['typeToModIdx']: raise error.NoSuchObjectError( - str='No types at MIB module %s at %s' % (modName, self) - ) - t = mibMod['typeToModIdx'].keys()[index] + str='No types at MIB module %s at ' + '%s' % (modName, self)) + + t = list(mibMod['typeToModIdx'])[index] + return mibMod['typeToModIdx'][t], t def getFirstTypeName(self, modName=''): @@ -331,9 +400,11 @@ class MibViewController(object): def getNextType(self, typeName, modName=''): m, t = self.getTypeName(typeName, modName) + try: - return self.__mibSymbolsIdx[m]['typeToModIdx'].nextKey(t) + return self._mibSymbolsIdx[m]['typeToModIdx'].nextKey(t) + except KeyError: raise error.NoSuchObjectError( - str='No type next to %s::%s at %s' % (modName, typeName, self) - ) + str='No type next to %s::%s at ' + '%s' % (modName, typeName, self)) |