#!/opt/imh-python/bin/python3.9
# This file is part of pysmi software.
# Copyright (c) 2015-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
# SNMP SMI/MIB data management tool
from pysmi.reader import getReadersFromUrls
from pysmi.searcher import AnyFileSearcher, PyFileSearcher, PyPackageSearcher, StubSearcher
from pysmi.borrower import AnyFileBorrower, PyFileBorrower
from pysmi.writer import PyFileWriter, FileWriter, CallbackWriter
from pysmi.parser import SmiV1CompatParser
from pysmi.codegen import PySnmpCodeGen, JsonCodeGen, NullCodeGen
from pysmi.compiler import MibCompiler
doFuzzyMatchingFlag = True
[--mib-searcher=<PATH|PACKAGE>]
[--destination-format=<FORMAT>]
[--destination-directory=<DIRECTORY>]
[--cache-directory=<DIRECTORY>]
[--python-optimization-level]
<MIB-NAME> [MIB-NAME [...]]]
URI - file, zip, http, https, ftp, sftp schemes are supported.
Use @mib@ placeholder token in URI to refer directly to
the required MIB module when source does not support
directory listing (e.g. HTTP).
FORMAT - pysnmp, json, null""" % (
'|'.join([x for x in sorted(debug.flagMap)])
opts, inputMibs = getopt.getopt(
['help', 'version', 'quiet', 'debug=',
'mib-source=', 'mib-searcher=', 'mib-stub=', 'mib-borrower=',
'destination-format=', 'destination-directory=', 'cache-directory=',
'no-dependencies', 'no-python-compile', 'python-optimization-level=',
'ignore-errors', 'build-index', 'rebuild', 'dry-run', 'no-mib-writes',
'generate-mib-texts', 'disable-fuzzy-source', 'keep-texts-layout']
except getopt.GetoptError:
sys.stderr.write('ERROR: %s\r\n%s\r\n' % (sys.exc_info()[1], helpMessage))
if opt[0] == '-h' or opt[0] == '--help':
SNMP SMI/MIB files conversion tool
http://snmplabs.com/pysmi
if opt[0] == '-v' or opt[0] == '--version':
from pysmi import __version__
SNMP SMI/MIB library version %s, written by Ilya Etingof <etingof@gmail.com>
Software documentation and support at http://snmplabs.com/pysmi
""" % (__version__, sys.version, helpMessage))
debug.setLogger(debug.Debug(*opt[1].split(',')))
if opt[0] == '--mib-source':
mibSources.append(opt[1])
if opt[0] == '--mib-searcher':
mibSearchers.append(opt[1])
if opt[0] == '--mib-stub':
if opt[0] == '--mib-borrower':
mibBorrowers.append((opt[1], genMibTextsFlag))
if opt[0] == '--destination-format':
if opt[0] == '--destination-directory':
if opt[0] == '--cache-directory':
if opt[0] == '--no-dependencies':
if opt[0] == '--no-python-compile':
if opt[0] == '--python-optimization-level':
pyOptimizationLevel = int(opt[1])
sys.stderr.write('ERROR: known Python optimization levels: -1, 0, 1, 2\r\n%s\r\n' % helpMessage)
if opt[0] == '--ignore-errors':
if opt[0] == '--build-index':
if opt[0] == '--rebuild':
if opt[0] == '--dry-run':
if opt[0] == '--no-mib-writes':
if opt[0] == '--generate-mib-texts':
if opt[0] == '--disable-fuzzy-source':
doFuzzyMatchingFlag = False
if opt[0] == '--keep-texts-layout':
mibSources = ['file:///usr/share/snmp/mibs',
'http://mibs.snmplabs.com/asn1/@mib@']
set([os.path.abspath(os.path.dirname(x))
inputMibs = [os.path.basename(os.path.splitext(x)[0]) for x in inputMibs]
sys.stderr.write('ERROR: MIB modules names not specified\r\n%s\r\n' % helpMessage)
if dstFormat == 'pysnmp':
mibSearchers = PySnmpCodeGen.defaultMibPackages
mibStubs = [x for x in PySnmpCodeGen.baseMibs if x not in PySnmpCodeGen.fakeMibs]
mibBorrowers = [('http://mibs.snmplabs.com/pysnmp/notexts/@mib@', False),
('http://mibs.snmplabs.com/pysnmp/fulltexts/@mib@', True)]
dstDirectory = os.path.expanduser("~")
if sys.platform[:3] == 'win':
dstDirectory = os.path.join(dstDirectory, 'PySNMP Configuration', 'mibs')
dstDirectory = os.path.join(dstDirectory, '.pysnmp', 'mibs')
# Compiler infrastructure
borrowers = [PyFileBorrower(x[1], genTexts=mibBorrowers[x[0]][1])
for x in enumerate(getReadersFromUrls(*[m[0] for m in mibBorrowers], **dict(lowcaseMatching=False)))]
searchers = [PyFileSearcher(dstDirectory)]
for mibSearcher in mibSearchers:
searchers.append(PyPackageSearcher(mibSearcher))
searchers.append(StubSearcher(*mibStubs))
codeGenerator = PySnmpCodeGen()
fileWriter = PyFileWriter(dstDirectory).setOptions(pyCompile=pyCompileFlag,
pyOptimizationLevel=pyOptimizationLevel)
elif dstFormat == 'json':
mibStubs = JsonCodeGen.baseMibs
mibBorrowers = [('http://mibs.snmplabs.com/json/notexts/@mib@', False),
('http://mibs.snmplabs.com/json/fulltexts/@mib@', True)]
dstDirectory = os.path.join('.')
# Compiler infrastructure
borrowers = [AnyFileBorrower(x[1], genTexts=mibBorrowers[x[0]][1]).setOptions(exts=['.json'])
for x in enumerate(getReadersFromUrls(*[m[0] for m in mibBorrowers], **dict(lowcaseMatching=False)))]
searchers = [AnyFileSearcher(dstDirectory).setOptions(exts=['.json']), StubSearcher(*mibStubs)]
codeGenerator = JsonCodeGen()
fileWriter = FileWriter(dstDirectory).setOptions(suffix='.json')
elif dstFormat == 'null':
mibStubs = NullCodeGen.baseMibs
mibBorrowers = [('http://mibs.snmplabs.com/null/notexts/@mib@', False),
('http://mibs.snmplabs.com/null/fulltexts/@mib@', True)]
# Compiler infrastructure
codeGenerator = NullCodeGen()
searchers = [StubSearcher(*mibStubs)]
borrowers = [AnyFileBorrower(x[1], genTexts=mibBorrowers[x[0]][1])
for x in enumerate(getReadersFromUrls(*[m[0] for m in mibBorrowers], **dict(lowcaseMatching=False)))]
fileWriter = CallbackWriter(lambda *x: None)
sys.stderr.write('ERROR: unknown destination format: %s\r\n%s\r\n' % (dstFormat, helpMessage))
sys.stderr.write("""Source MIB repositories: %s
Borrow missing/failed MIBs from: %s
Existing/compiled MIB locations: %s
Compiled MIBs destination directory: %s
MIBs excluded from code generation: %s
Parser grammar cache directory: %s
Also compile all relevant MIBs: %s
Rebuild MIBs regardless of age: %s
Byte-compile Python modules: %s (optimization level %s)
Ignore compilation errors: %s
Generate OID->MIB index: %s
Generate texts in MIBs: %s
Keep original texts layout: %s
Try various file names while searching for MIB module: %s
""" % (', '.join(mibSources),
', '.join([x[0] for x in mibBorrowers if x[1] == genMibTextsFlag]),
', '.join(sorted(mibStubs)),
cacheDirectory or 'not used',
nodepsFlag and 'no' or 'yes',
rebuildFlag and 'yes' or 'no',
dryrunFlag and 'yes' or 'no',
writeMibsFlag and 'yes' or 'no',
dstFormat == 'pysnmp' and pyCompileFlag and 'yes' or 'no',
dstFormat == 'pysnmp' and pyOptimizationLevel and 'yes' or 'no',
ignoreErrorsFlag and 'yes' or 'no',
buildIndexFlag and 'yes' or 'no',
genMibTextsFlag and 'yes' or 'no',
keepTextsLayout and 'yes' or 'no',
doFuzzyMatchingFlag and 'yes' or 'no'))
# Initialize compiler infrastructure
mibCompiler = MibCompiler(
SmiV1CompatParser(tempdir=cacheDirectory),
*mibSources, **dict(fuzzyMatching=doFuzzyMatchingFlag)
mibCompiler.addSearchers(*searchers)
mibCompiler.addBorrowers(*borrowers)
processed = mibCompiler.compile(
*inputMibs, **dict(noDeps=nodepsFlag,
genTexts=genMibTextsFlag,
textFilter=keepTextsLayout and (lambda symbol, text: text) or None,
ignoreErrors=ignoreErrorsFlag)
ignoreErrors=ignoreErrorsFlag
sys.stderr.write('ERROR: %s\r\n' % sys.exc_info()[1])
sys.stderr.write('%sreated/updated MIBs: %s\r\n' % (dryrunFlag and 'Would be c' or 'C', ', '.join(
['%s%s' % (x, x != processed[x].alias and ' (%s)' % processed[x].alias or '') for x in sorted(processed) if processed[x] == 'compiled'])))
sys.stderr.write('Pre-compiled MIBs %sborrowed: %s\r\n' % (dryrunFlag and 'Would be ' or '', ', '.join(
['%s (%s)' % (x, processed[x].path) for x in sorted(processed) if processed[x] == 'borrowed'])))
'Up to date MIBs: %s\r\n' % ', '.join(['%s' % x for x in sorted(processed) if processed[x] == 'untouched']))
sys.stderr.write('Missing source MIBs: %s\r\n' % ', '.join(
['%s' % x for x in sorted(processed) if processed[x] == 'missing']))
'Ignored MIBs: %s\r\n' % ', '.join(['%s' % x for x in sorted(processed) if processed[x] == 'unprocessed']))
sys.stderr.write('Failed MIBs: %s\r\n' % ', '.join(
['%s (%s)' % (x, processed[x].error) for x in sorted(processed) if processed[x] == 'failed']))
if any(x for x in processed.values() if x == 'missing'):
exitCode = EX_MIB_MISSING
if any(x for x in processed.values() if x == 'failed'):