Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
 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
Beispiel #5
0
    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
Beispiel #6
0
    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)