def mib2pysnmp2(mib_file, output_dir): """ The 'build-pysnmp-mib' script we previously used is no longer available Latest pysmi has the ability to generate a .py file from .mib automatically :param mib_file: path to the .mib file we want to compile :param output_dir: path to the output directory :return: True if we successfully compile the .mib to a .py """ logger.debug('Compiling mib file: %s', mib_file) # create a mib compiler with output dir mibCompiler = MibCompiler(SmiV2Parser(), PySnmpCodeGen(), PyFileWriter(output_dir)) # add default sources and mib_file's location mibCompiler.addSources(FileReader('/usr/share/mibs/ietf')) mibCompiler.addSources(FileReader('/usr/share/mibs/iana')) mibCompiler.addSources( FileReader(os.path.dirname(os.path.abspath(mib_file)))) # add searchers mibCompiler.addSearchers(PyFileSearcher(output_dir)) mibCompiler.addSearchers(PyPackageSearcher('pysnmp.mibs')) mibCompiler.addSearchers(StubSearcher(*baseMibs)) # compile, there should be a MIBFILE.py generated under output_dir mibName = os.path.basename(mib_file).replace('.mib', '') results = mibCompiler.compile(mibName) if results[mibName] == 'compiled' or results[mibName] == 'untouched': return True return False
def _compile_cloudify_mib(): mibs_dir = "pysnmp_mibs" if os.path.exists('{0}/{1}.py'.format(mibs_dir, CLOUDIFY_MIB)): return mib_compiler = MibCompiler(SmiV2Parser(), PySnmpCodeGen(), PyFileWriter(mibs_dir)) cloudify_mib_dir = os.path.dirname(os.path.realpath(__file__)) mib_compiler.addSources(FileReader(cloudify_mib_dir)) mib_compiler.addSources(HttpReader('mibs.snmplabs.com', 80, '/asn1/@mib@')) mib_compiler.addSearchers(PyFileSearcher(mibs_dir)) mib_compiler.compile(CLOUDIFY_MIB)
inputMibs = ['BORROWED-MIB'] httpSources = [('mibs.snmplabs.com', 80, '/asn1/@mib@')] httpBorrowers = [('mibs.snmplabs.com', 80, '/pysnmp/notexts/@mib@')] dstDirectory = '.pysnmp-mibs' # Initialize compiler infrastructure mibCompiler = MibCompiler( parserFactory(**smiV1Relaxed)(), PySnmpCodeGen(), PyFileWriter(dstDirectory)) # search for source MIBs at Web sites mibCompiler.addSources(*[HttpReader(*x) for x in httpSources]) # never recompile MIBs with MACROs mibCompiler.addSearchers(StubSearcher(*baseMibs)) # check compiled/borrowed MIBs in our own productions mibCompiler.addSearchers(PyFileSearcher(dstDirectory)) # search for compiled MIBs at Web sites if source is not available or broken mibCompiler.addBorrowers(*[ PyFileBorrower(HttpReader(*x)).setOptions(genTexts=False) for x in httpBorrowers ]) # run non-recursive MIB compilation results = mibCompiler.compile(*inputMibs) print('Results: %s' % ', '.join(['%s:%s' % (x, results[x]) for x in results]))
def fileExists(self, mibname, mtime, rebuild=False): if rebuild: debug.logger & debug.flagSearcher and debug.logger('pretend %s is very old' % mibname) return mibname = decode(mibname) try: p = __import__(self._package, globals(), locals(), ['__init__']) if hasattr(p, '__loader__') and hasattr(p.__loader__, '_files'): self.__loader = p.__loader__ self._package = self._package.replace('.', os.sep) debug.logger & debug.flagSearcher and debug.logger( '%s is an importable egg at %s' % (self._package, os.path.split(p.__file__)[0])) elif hasattr(p, '__file__'): debug.logger & debug.flagSearcher and debug.logger( '%s is not an egg, trying it as a package directory' % self._package) return PyFileSearcher(os.path.split(p.__file__)[0]).fileExists(mibname, mtime, rebuild=rebuild) else: raise error.PySmiFileNotFoundError('%s is neither importable nor a file' % self._package, searcher=self) except ImportError: raise error.PySmiFileNotFoundError('%s is not importable, trying as a path' % self._package, searcher=self) for fmt in imp.PY_COMPILED, imp.PY_SOURCE: for pySfx, pyMode in self.suffixes[fmt]: f = os.path.join(self._package, mibname.upper()) + pySfx if f not in self.__loader._files: debug.logger & debug.flagSearcher and debug.logger('%s is not in %s' % (f, self._package)) continue if fmt == imp.PY_COMPILED: pyData = self.__loader.get_data(f) if pyData[:4] == imp.get_magic(): pyData = pyData[4:] pyTime = struct.unpack('<L', pyData[:4])[0] debug.logger & debug.flagSearcher and debug.logger( 'found %s, mtime %s' % (f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(pyTime)))) if pyTime >= mtime: raise error.PySmiFileNotModifiedError() else: raise error.PySmiFileNotFoundError('older file %s exists' % mibname, searcher=self) else: debug.logger & debug.flagSearcher and debug.logger('bad magic in %s' % f) continue else: pyTime = self._parseDosTime( self.__loader._files[f][6], self.__loader._files[f][5] ) debug.logger & debug.flagSearcher and debug.logger( 'found %s, mtime %s' % (f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(pyTime)))) if pyTime >= mtime: raise error.PySmiFileNotModifiedError() else: raise error.PySmiFileNotFoundError('older file %s exists' % mibname, searcher=self) raise error.PySmiFileNotFoundError('no file %s found' % mibname, searcher=self)
def storeMib(config, mib, mibdir=None, fetchRemote=False): """ A function to compile, store new mibs Mostly got the code from https://raw.githubusercontent.com/etingof/pysmi/master/scripts/mibdump.py """ cacheDir = '/tmp/' log.debug("Collecting MIB resources") mibSearchers = defaultMibPackages log.debug("Searches") mibStubs = [x for x in baseMibs if x not in fakeMibs] log.debug("Stubs") mibSources = ["file://{}".format(x) for x in config["mibs"]["locations"]] log.debug("MIB sources from config") if mibdir != None: mibSources.append("file://{}".format(mibdir)) log.debug("MIB source from param") # if "mib" is a path, add it to the sources. if os.path.sep in mib: mibSources.append(os.path.abspath(os.path.dirname(mib))) log.debug("MIB source from '{}'".format(mib)) if fetchRemote: mibSources.append('http://mibs.snmplabs.com/asn1/@mib@') log.debug("Added remote mib source.") log.info("Using MIB sources: [{}]".format(", ".join(mibSources))) log.info("Using dest: {}".format(config['mibs']['compiled'])) log.info("Initialize compiler") try: mibCompiler = MibCompiler( parserFactory(**smiV1Relaxed)(tempdir=cacheDir), PySnmpCodeGen(), PyFileWriter(config['mibs']['compiled']).setOptions( pyCompile=True, pyOptimizationLevel=0)) print(mibSources) except Exception as e: log.error("Exception! {}".format(e)) log.debug("Adding sources to compiler") try: mibCompiler.addSources( *getReadersFromUrls(*mibSources, **dict(fuzzyMatching=True))) mibCompiler.addSearchers(PyFileSearcher(config['mibs']['compiled'])) for mibSearcher in mibSearchers: mibCompiler.addSearchers(PyPackageSearcher(mibSearcher)) mibCompiler.addSearchers(StubSearcher(*mibStubs)) log.debug("Starting compilation of {}".format(mib)) processed = mibCompiler.compile( *[mib], **dict(noDeps=False, rebuild=False, dryRun=False, genTexts=False, ignoreErrors=False)) mibCompiler.buildIndex(processed, dryRun=False, ignoreErrors=False) except smiError.PySmiError as e: log.error("Compilation failed: {}".format(e)) raise exceptions.MibCompileError(e) errors = [(x, processed[x].error) for x in sorted(processed) if processed[x] == 'failed'] compiled = [(x, processed[x].alias) for x in sorted(processed) if processed[x] == 'compiled'] missing = [x for x in sorted(processed) if processed[x] == 'missing'] for mib in compiled: log.info("Compiled {} ({})".format(mib[0], mib[1])) if len(errors) > 0 or len(missing) > 0: for error in errors: log.error("Could not process {} MIB: {}".format( error[0], error[1])) for mis in missing: log.error("Could not find {}".format(mis)) raise exceptions.MibCompileFailed(errors) log.info("Done without errors") print(processed)