def genCode(self, ast, symbolTable, **kwargs): mibInfo, context = IntermediateCodeGen.genCode(self, ast, symbolTable, **kwargs) # TODO: reduce code duplication with the other codegens searchPath = os.path.join(os.path.dirname(__file__), 'templates') dstTemplate = kwargs.get('dstTemplate') if dstTemplate: searchPath.insert(0, os.path.dirname(os.path.abspath(dstTemplate))) env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchPath), trim_blocks=True, lstrip_blocks=True) env.filters['capfirst'] = jfilters.capfirst try: tmpl = env.get_template(dstTemplate or self.TEMPLATE_NAME) text = tmpl.render(mib=context) except jinja2.exceptions.TemplateError: err = sys.exc_info()[1] raise error.PySmiCodegenError( 'Jinja template rendering error: %s' % err) debug.logger & debug.flagCodegen and debug.logger( 'canonical MIB name %s (%s), imported MIB(s) %s, rendered from ' '%s, JSON document size %d bytes' % (mibInfo.name, mibInfo.identity, ','.join(mibInfo.imported) or '<none>', dstTemplate, len(text))) return mibInfo, text
def genCode(self, ast, symbolTable, **kwargs): self.genRules['text'] = kwargs.get('genTexts', False) self.textFilter = kwargs.get('textFilter') or ( lambda symbol, text: re.sub('\s+', ' ', text)) self.symbolTable = symbolTable self._rows.clear() self._cols.clear() self._exports.clear() self._seenSyms.clear() self._importMap.clear() self._out.clear() self._moduleIdentityOid = None self.moduleName[0], moduleOid, imports, declarations = ast out, importedModules = self.genImports(imports or {}) for declr in declarations or []: if declr: clausetype = declr[0] classmode = clausetype == 'typeDeclaration' self.handlersTable[declr[0]](self, self.prepData( declr[1:], classmode), classmode) for sym in self.symbolTable[self.moduleName[0]]['_symtable_order']: if sym not in self._out: raise error.PySmiCodegenError( 'No generated code for symbol %s' % sym) out += self._out[sym] out += self.genExports() if 'comments' in kwargs: out = ''.join(['# %s\n' % x for x in kwargs['comments']]) + '#\n' + out out = '#\n# PySNMP MIB module %s (http://snmplabs.com/pysmi)\n' % self.moduleName[ 0] + out debug.logger & debug.flagCodegen and debug.logger( 'canonical MIB name %s (%s), imported MIB(s) %s, Python code size %s bytes' % (self.moduleName[0], moduleOid, ','.join(importedModules) or '<none>', len(out))) return MibInfo(oid=moduleOid, identity=self._moduleIdentityOid, name=self.moduleName[0], revision=self._moduleRevision, oids=[], enterprise=None, compliance=[], imported=tuple([ x for x in importedModules if x not in self.fakeMibs ])), out
def genCode(self, ast, symbolTable, **kwargs): self.genRules['text'] = kwargs.get('genTexts', False) self.textFilter = kwargs.get('textFilter') or ( lambda symbol, text: re.sub('\s+', ' ', text)) self.symbolTable = symbolTable self._rows.clear() self._cols.clear() self._seenSyms.clear() self._importMap.clear() self._out.clear() self._moduleIdentityOid = None self._enterpriseOid = None self._oids = set() self._complianceOids = [] self.moduleName[0], moduleOid, imports, declarations = ast outDict, importedModules = self.genImports(imports and imports or {}) for declr in declarations or []: if declr: self.handlersTable[declr[0]](self, self.prepData(declr[1:])) for sym in self.symbolTable[self.moduleName[0]]['_symtable_order']: if sym not in self._out: raise error.PySmiCodegenError( 'No generated code for symbol %s' % sym) outDict[sym] = self._out[sym] outDict['meta'] = OrderedDict() outDict['meta']['module'] = self.moduleName[0] if 'comments' in kwargs: outDict['meta']['comments'] = kwargs['comments'] debug.logger & debug.flagCodegen and debug.logger( 'canonical MIB name %s (%s), imported MIB(s) %s' % (self.moduleName[0], moduleOid, ','.join(importedModules) or '<none>')) return MibInfo(oid=moduleOid, identity=self._moduleIdentityOid, name=self.moduleName[0], revision=self._moduleRevision, oids=self._oids, enterprise=self._enterpriseOid, compliance=self._complianceOids, imported=tuple([ x for x in importedModules if x not in self.fakeMibs ])), outDict
def genCode(self, ast, symbolTable, **kwargs): self.genRules['text'] = kwargs.get('genTexts', False) self.symbolTable = symbolTable out = '' importedModules = () self._rows.clear() self._cols.clear() self._exports.clear() self._presentedSyms.clear() self._importMap.clear() self._out.clear() self.moduleName[0], moduleOid, imports, declarations = ast out, importModules = self.genImports(imports and imports or {}) for declr in declarations and declarations or []: if declr: clausetype = declr[0] classmode = clausetype == 'typeDeclaration' self.handlersTable[declr[0]](self, self.prepData( declr[1:], classmode), classmode) for sym in self.symbolTable[self.moduleName[0]]['_symtable_order']: if sym not in self._out: raise error.PySmiCodegenError( 'No generated code for symbol %s' % sym) out += self._out[sym] out += self.genExports() if 'comments' in kwargs: out = ''.join(['# %s\n' % x for x in kwargs['comments']]) + '#\n' + out out = '#\n# NetSnmp MIB module' + out debug.logger & debug.flagCodegen and debug.logger( 'canonical MIB name %s (%s), imported MIB(s) %s, C code size %s bytes' % (self.moduleName[0], moduleOid, ','.join(importedModules) or '<none>', len(out))) return MibInfo(oid=None, NameError=self.moduleName[0], importedModules=tuple([ x for x in importedModules if x not in fakedMibs ])), out
def genCode(self, ast, symbolTable, **kwargs): mibInfo, context = IntermediateCodeGen.genCode(self, ast, symbolTable, **kwargs) # Adapt intermediate context to pysnmp template requirements # Translate SMI objects names in IMPORT imports = OrderedDict() for module, symbols in context.get('imports', {}).items(): if not isinstance(symbols, list): continue imports[module] = [] for symbol in symbols: if symbol in self.SMI_OBJECTS: imports[module].extend(self.SMI_OBJECTS[symbol]) else: imports[module].append(symbol) context['imports'] = imports # Turn string OIDs into tuples which is native to pysnmp # TODO: we should make intermediate format producing tuples def translateOids(dct): for key, value in tuple(dct.items()): if isinstance(value, dict): translateOids(value) elif key == 'oid': dct[key] = tuple(int(x) for x in value.split('.')) translateOids(context) # Translate SMI types into pysnmp class names # Sort Managed Objects by OID objects = OrderedDict() for symbol, definition in sorted(context.items(), key=lambda x: x[1].get('oid', ())): objects[symbol] = definition context = objects # Render Python code searchPath = [os.path.join(os.path.dirname(__file__), 'templates')] # TODO: add unit test on custom template dstTemplate = kwargs.get('dstTemplate') if dstTemplate: searchPath.insert(0, os.path.dirname(os.path.abspath(dstTemplate))) env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchPath), trim_blocks=True, lstrip_blocks=True) env.filters['capfirst'] = jfilters.capfirst try: tmpl = env.get_template(dstTemplate or self.TEMPLATE_NAME) text = tmpl.render(mib=context) except jinja2.exceptions.TemplateError: err = sys.exc_info()[1] raise error.PySmiCodegenError( 'Jinja template rendering error: %s' % err) debug.logger & debug.flagCodegen and debug.logger( 'canonical MIB name %s (%s), imported MIB(s) %s, rendered from ' '%s, Python code size %d bytes' % (mibInfo.name, mibInfo.identity, ','.join(mibInfo.imported) or '<none>', dstTemplate, len(text))) return mibInfo, text
def genIndex(self, processed, **kwargs): outDict = { 'meta': {}, 'identity': {}, 'enterprise': {}, 'compliance': {}, 'oids': {}, } if kwargs.get('old_index_data'): try: outDict.update(json.loads(kwargs['old_index_data'])) except Exception: raise error.PySmiCodegenError('Index load error: %s' % sys.exc_info()[1]) def order(top): if isinstance(top, dict): new_top = OrderedDict() try: # first try to sort keys as OIDs for k in sorted( top, key=lambda x: [int(y) for y in x.split('.')]): new_top[k] = order(top[k]) except ValueError: for k in sorted(top): new_top[k] = order(top[k]) return new_top elif isinstance(top, list): new_top = [] for e in sorted(set(top)): new_top.append(order(e)) return new_top return top for module, status in processed.items(): modData = outDict['identity'] identity_oid = getattr(status, 'identity', None) if identity_oid: if identity_oid not in modData: modData[identity_oid] = [] modData[identity_oid].append(module) modData = outDict['enterprise'] enterprise_oid = getattr(status, 'enterprise', None) if enterprise_oid: if enterprise_oid not in modData: modData[enterprise_oid] = [] modData[enterprise_oid].append(module) modData = outDict['compliance'] compliance_oids = getattr(status, 'compliance', ()) for compliance_oid in compliance_oids: if compliance_oid not in modData: modData[compliance_oid] = [] modData[compliance_oid].append(module) modData = outDict['oids'] objects_oids = getattr(status, 'oids', ()) for object_oid in objects_oids: if object_oid not in modData: modData[object_oid] = [] modData[object_oid].append(module) if modData: unique_prefixes = {} for oid in sorted(modData, key=lambda x: x.count('.')): for oid_prefix, modules in unique_prefixes.items(): if oid.startswith(oid_prefix) and set( modules).issuperset(modData[oid]): break else: unique_prefixes[oid] = modData[oid] outDict['oids'] = unique_prefixes if 'comments' in kwargs: outDict['meta']['comments'] = kwargs['comments'] debug.logger & debug.flagCodegen and debug.logger( 'OID->MIB index built, %s entries' % len(processed)) return json.dumps(order(outDict), indent=2)