def init(**context): if context['options']: for k,v in [split(x, ':') for x in split(context['options'], ',')]: if k == 'addon': if k in moduleContext: moduleContext[k].append(v) else: moduleContext[k] = [v] else: moduleContext[k] = v if context['mode'] == 'variating': moduleContext['booted'] = time.time() elif context['mode'] == 'recording': if 'dir' not in moduleContext: raise error.SnmpsimError('SNMP snapshots directory not specified') if not os.path.exists(moduleContext['dir']): log.msg('multiplex: creating %s...' % moduleContext['dir']) os.makedirs(moduleContext['dir']) if 'iterations' in moduleContext: moduleContext['iterations'] = max(0, int(moduleContext['iterations'])-1) if 'period' in moduleContext: moduleContext['period'] = float(moduleContext['period']) else: moduleContext['period'] = 10.0 moduleContext['ready'] = True
def init(**context): if context['options']: for k, v in [split(x, ':') for x in split(context['options'], ',')]: if k == 'addon': if k in moduleContext: moduleContext[k].append(v) else: moduleContext[k] = [v] else: moduleContext[k] = v if context['mode'] == 'variating': moduleContext['booted'] = time.time() elif context['mode'] == 'recording': if 'dir' not in moduleContext: raise error.SnmpsimError('SNMP snapshots directory not specified') if not os.path.exists(moduleContext['dir']): log.msg('multiplex: creating %s...' % moduleContext['dir']) os.makedirs(moduleContext['dir']) if 'iterations' in moduleContext: moduleContext['iterations'] = max( 0, int(moduleContext['iterations']) - 1) if 'period' in moduleContext: moduleContext['period'] = float(moduleContext['period']) else: moduleContext['period'] = 10.0 moduleContext['ready'] = True
def create_snmp_record(self, oid, stop_oid=None, get_subtree=True, get_single_value=False): self._get_bulk_flag = self.snmp_parameters.get_bulk_flag if get_single_value and self._get_bulk_flag: self._get_bulk_flag = False self._output_list = list() self._oid = univ.ObjectIdentifier(oid) if stop_oid: self._stop_oid = univ.ObjectIdentifier(stop_oid) elif get_subtree: _stop_oid = "{}{}".format(oid[:-1], int(oid[-1:]) + 1) self._stop_oid = univ.ObjectIdentifier(_stop_oid) cb_ctx = { 'total': 0, 'count': 0, 'errors': 0, 'is_snmp_timeout': False, 'iteration': 0, 'reqTime': time.time(), '': True, 'retries': self.snmp_parameters.retry_count, 'lastOID': oid } if self._get_bulk_flag: self.send_bulk_var_binds(self._oid, cb_ctx) else: self.send_walk_var_binds(self._oid, cb_ctx) log.msg('Sending initial %s request for %s ....' % ( self.snmp_parameters.get_bulk_flag and 'GETBULK' or 'GETNEXT', self._oid)) # t = time.time() # exc_info = None try: self.snmp_parameters.snmp_engine.transportDispatcher.runDispatcher() except KeyboardInterrupt: raise # log.msg('Shutting down process...') except Exception: exc_info = sys.exc_info() pass if cb_ctx.get("is_snmp_timeout") and not self._output_list: raise requestTimedOut # t = time.time() - t cb_ctx['total'] += cb_ctx['count'] # log.msg('OIDs dumped: %s, elapsed: %.2f sec, rate: %.2f OIDs/sec, errors: %d' % ( # cb_ctx['total'], t, t and cb_ctx['count'] // t or 0, cb_ctx['errors'])) # if exc_info: # for line in traceback.format_exception(*exc_info): # log.msg(line.replace('\n', ';')) return self._output_list
def _cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx): oid, value = cbCtx if errorIndication or errorStatus: log.msg( 'notification: for %s=%r failed with errorIndication %s, errorStatus %s' % (oid, value, errorIndication, errorStatus))
def record(oid, tag, value, **context): if 'ready' not in moduleContext: raise error.SnmpsimError('module not initialized') if 'dbConn' in moduleContext: dbConn = moduleContext['dbConn'] else: raise error.SnmpsimError('variation module not initialized') if 'started' not in moduleContext: moduleContext['started'] = time.time() redisScript = moduleContext.get('evalsha') keySpace = '%.10d' % (moduleContext['key-spaces-id'] + moduleContext.get('iterations', 0)) if context['stopFlag']: dbConn.sort(keySpace + '-' + 'temp_oids_ordering', store=keySpace + '-' + 'oids_ordering', alpha=True) dbConn.delete(keySpace + '-' + 'temp_oids_ordering') dbConn.rpush(moduleContext['key-spaces-id'], keySpace) log.msg('redis: done with key-space %s' % keySpace) if 'iterations' in moduleContext and moduleContext['iterations']: log.msg('redis: %s iterations remaining' % moduleContext['iterations']) moduleContext['started'] = time.time() moduleContext['iterations'] -= 1 wait = max(0, moduleContext['period'] - (time.time() - moduleContext['started'])) raise error.MoreDataNotification(period=wait) else: raise error.NoDataNotification() dbOid = '.'.join(['%10s' % x for x in oid.split('.')]) if 'hexvalue' in context: textTag = context['hextag'] textValue = context['hexvalue'] else: textTag = SnmprecGrammar().getTagByType(context['origValue']) textValue = str(context['origValue']) dbConn.lpush(keySpace + '-temp_oids_ordering', keySpace + '-' + dbOid) if redisScript: dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid, textTag + '|' + textValue) else: dbConn.set(keySpace + '-' + dbOid, textTag + '|' + textValue) if not context['count']: settings = { 'key-spaces-id': moduleContext['key-spaces-id'] } if 'period' in moduleContext: settings['period'] = '%.2f' % float(moduleContext['period']) if 'addon' in moduleContext: settings.update( dict([split(x, '=') for x in moduleContext['addon']]) ) value = ','.join([ '%s=%s' % (k,v) for k,v in settings.items() ]) return str(context['startOID']), ':redis', value else: raise error.NoDataNotification()
def _cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx): oid, value = cbCtx if errorIndication or errorStatus: log.msg('notification: for %s=%r failed with errorIndication %s, errorStatus %s' % (oid, value, errorIndication, errorStatus))
def getHandles(self): if self.isOpen(): if self.__textFileTime != os.stat(self.__textFile)[8]: log.msg('Text file %s modified, closing' % self.__textFile) self.close() if not self.isOpen(): self.create() self.open() return self.__text, self.__db
def getHandles(self): if self.isOpen(): if self.__textFileTime != os.stat(self.__textFile)[8]: log.msg('Text file %s modified, closing' % self.__textFile) self.close() if not self.isOpen(): self.create() self.open() return self.__text, self.__db
def init(**context): options = {} if context['options']: options.update( dict([split(x, ':') for x in split(context['options'], ',')])) connectOpts = 'host', 'port', 'password', 'db', 'unix_socket' connectParams = dict([(k, options[k]) for k in options if k in connectOpts]) for k in 'port', 'db': if k in connectParams: connectParams[k] = int(connectParams[k]) if not connectParams: raise error.SnmpsimError('Redis connect parameters not specified') if StrictRedis is None: raise error.SnmpsimError('redis-py Python package must be installed!') moduleContext['dbConn'] = StrictRedis(**connectParams) if context['mode'] == 'recording': if 'key-spaces-id' in options: moduleContext['key-spaces-id'] = int(options['key-spaces-id']) else: moduleContext['key-spaces-id'] = random.randrange(0, 0xffffffff) log.msg('redis: using key-spaces-id %s' % moduleContext['key-spaces-id']) if 'iterations' in options: moduleContext['iterations'] = max(0, int(options['iterations']) - 1) if 'period' in options: moduleContext['period'] = float(options['period']) else: moduleContext['period'] = 60.0 redisScript = options.get('evalsha') if redisScript: log.msg('redis: using server-side script %s' % redisScript) elif context['mode'] == 'variating': moduleContext['booted'] = time.time() moduleContext['ready'] = True
def init(**context): options = {} if context['options']: options.update( dict([split(x, ':') for x in split(context['options'], ',')])) connectOpts = 'host', 'port', 'password', 'db', 'unix_socket' connectParams = dict( [(k, options[k]) for k in options if k in connectOpts]) for k in 'port', 'db': if k in connectParams: connectParams[k] = int(connectParams[k]) if not connectParams: raise error.SnmpsimError('Redis connect parameters not specified') if StrictRedis is None: raise error.SnmpsimError('redis-py Python package must be installed!') moduleContext['dbConn'] = StrictRedis(**connectParams) if context['mode'] == 'recording': if 'key-spaces-id' in options: moduleContext['key-spaces-id'] = int(options['key-spaces-id']) else: moduleContext['key-spaces-id'] = random.randrange(0, 0xffffffff) log.msg('redis: using key-spaces-id %s' % moduleContext['key-spaces-id']) if 'iterations' in options: moduleContext['iterations'] = max(0, int(options['iterations']) - 1) if 'period' in options: moduleContext['period'] = float(options['period']) else: moduleContext['period'] = 60.0 redisScript = options.get('evalsha') if redisScript: log.msg('redis: using server-side script %s' % redisScript) elif context['mode'] == 'variating': moduleContext['booted'] = time.time() moduleContext['ready'] = True
def record(oid, tag, value, **context): if 'ready' not in moduleContext: raise error.SnmpsimError('module not initialized') if 'started' not in moduleContext: moduleContext['started'] = time.time() if context['stopFlag']: if 'file' in moduleContext: moduleContext['file'].close() del moduleContext['file'] else: moduleContext['filenum'] = 0 if 'iterations' in moduleContext and moduleContext['iterations']: log.msg('multiplex: %s iterations remaining' % moduleContext['iterations']) moduleContext['started'] = time.time() moduleContext['iterations'] -= 1 moduleContext['filenum'] += 1 wait = max(0, moduleContext['period'] - (time.time() - moduleContext['started'])) raise error.MoreDataNotification(period=wait) else: raise error.NoDataNotification() if 'file' not in moduleContext: if 'filenum' not in moduleContext: moduleContext['filenum'] = 0 snmprecfile = os.path.join(moduleContext['dir'], '%.5d%ssnmprec' % (moduleContext['filenum'], os.path.extsep)) moduleContext['file'] = open(snmprecfile, 'wb') log.msg('multiplex: writing into %s file...' % snmprecfile) moduleContext['file'].write( SnmprecRecord().format(context['origOid'], context['origValue']) ) if not context['total']: settings = { 'dir': moduleContext['dir'].replace(os.path.sep, '/') } if 'period' in moduleContext: settings['period'] = '%.2f' % float(moduleContext['period']) if 'addon' in moduleContext: settings.update( dict([split(x, '=') for x in moduleContext['addon']]) ) value = ','.join([ '%s=%s' % (k,v) for k,v in settings.items() ]) return str(context['startOID']), ':multiplex', value else: raise error.NoDataNotification()
def record(oid, tag, value, **context): if 'ready' not in moduleContext: raise error.SnmpsimError('module not initialized') if 'started' not in moduleContext: moduleContext['started'] = time.time() if context['stopFlag']: if 'file' in moduleContext: moduleContext['file'].close() del moduleContext['file'] else: moduleContext['filenum'] = 0 if 'iterations' in moduleContext and moduleContext['iterations']: log.msg('multiplex: %s iterations remaining' % moduleContext['iterations']) moduleContext['started'] = time.time() moduleContext['iterations'] -= 1 moduleContext['filenum'] += 1 wait = max(0, moduleContext['period'] - (time.time() - moduleContext['started'])) raise error.MoreDataNotification(period=wait) else: raise error.NoDataNotification() if 'file' not in moduleContext: if 'filenum' not in moduleContext: moduleContext['filenum'] = 0 snmprecfile = os.path.join(moduleContext['dir'], '%.5d%ssnmprec' % (moduleContext['filenum'], os.path.extsep)) moduleContext['file'] = open(snmprecfile, 'wb') log.msg('multiplex: writing into %s file...' % snmprecfile) moduleContext['file'].write( SnmprecRecord().format(context['origOid'], context['origValue']) ) if not context['total']: settings = { 'dir': moduleContext['dir'].replace(os.path.sep, '/') } if 'period' in moduleContext: settings['period'] = '%.2f' % float(moduleContext['period']) if 'addon' in moduleContext: settings.update( dict([split(x, '=') for x in moduleContext['addon']]) ) value = ','.join(['%s=%s' % (k, v) for k, v in settings.items()]) return str(context['startOID']), ':multiplex', value else: raise error.NoDataNotification()
def variate(oid, tag, value, **context): # in --v2c-arch some of the items are not defined transportDomain = transportAddress = securityModel = securityName = \ securityLevel = contextName = '<undefined>' if 'transportDomain' in context: transportDomain = rfc1902.ObjectName( context['transportDomain']).prettyPrint() if 'transportAddress' in context: transportAddress = ':'.join( [str(x) for x in context['transportAddress']]) if 'securityModel' in context: securityModel = str(context['securityModel']) if 'securityName' in context: securityName = str(context['securityName']) if 'securityLevel' in context: securityLevel = str(context['securityLevel']) if 'contextName' in context: contextName = str(context['contextName']) args = [(x.replace('@TRANSPORTDOMAIN@', transportDomain).replace( '@TRANSPORTADDRESS@', transportAddress).replace( '@SECURITYMODEL@', securityModel).replace('@SECURITYNAME@', securityName).replace( '@SECURITYLEVEL@', securityLevel).replace('@CONTEXTNAME@', contextName).replace( '@DATAFILE@', context['dataFile']).replace('@OID@', str(oid)).replace( '@TAG@', tag).replace('@ORIGOID@', str(context['origOid'])). replace('@ORIGTAG@', str(sum( [x for x in context['origValue'].tagSet[0]]))).replace( '@ORIGVALUE@', str(context['origValue'])).replace( '@SETFLAG@', str(int(context['setFlag']))).replace( '@NEXTFLAG@', str(int(context['nextFlag']))).replace( '@SUBTREEFLAG@', str(int(context['subtreeFlag'])))) for x in split(value, ' ')] log.msg('subprocess: executing external process "%s"' % ' '.join(args)) call = (hasattr(subprocess, 'check_output') and subprocess.check_output or hasattr(subprocess, 'check_call') and subprocess.check_call or subprocess.call) if not hasattr(subprocess, 'check_output'): log.msg('subprocess: old Python, expect no output!') try: return oid, tag, call(args, shell=moduleContext['settings']['shell']) except (hasattr(subprocess, 'CalledProcessError') and subprocess.CalledProcessError or Exception): log.msg('subprocess: external program execution failed') return context['origOid'], tag, context['errorStatus']
def variate(oid, tag, value, **context): # in --v2c-arch some of the items are not defined transportDomain = transportAddress = securityModel = securityName = \ securityLevel = contextName = '<undefined>' if 'transportDomain' in context: transportDomain = rfc1902.ObjectName(context['transportDomain']).prettyPrint() if 'transportAddress' in context: transportAddress = ':'.join([str(x) for x in context['transportAddress']]) if 'securityModel' in context: securityModel = str(context['securityModel']) if 'securityName' in context: securityName = str(context['securityName']) if 'securityLevel' in context: securityLevel = str(context['securityLevel']) if 'contextName' in context: contextName = str(context['contextName']) args = [ x\ .replace('@TRANSPORTDOMAIN@', transportDomain)\ .replace('@TRANSPORTADDRESS@', transportAddress)\ .replace('@SECURITYMODEL@', securityModel)\ .replace('@SECURITYNAME@', securityName)\ .replace('@SECURITYLEVEL@', securityLevel)\ .replace('@CONTEXTNAME@', contextName)\ .replace('@DATAFILE@', context['dataFile'])\ .replace('@OID@', str(oid))\ .replace('@TAG@', tag)\ .replace('@ORIGOID@', str(context['origOid']))\ .replace('@ORIGTAG@', str(sum([ x for x in context['origValue'].tagSet[0]])))\ .replace('@ORIGVALUE@', str(context['origValue']))\ .replace('@SETFLAG@', str(int(context['setFlag'])))\ .replace('@NEXTFLAG@', str(int(context['nextFlag'])))\ .replace('@SUBTREEFLAG@', str(int(context['subtreeFlag'])))\ for x in split(value, ' ') ] log.msg('subprocess: executing external process "%s"' % ' '.join(args)) call = hasattr(subprocess, 'check_output') and subprocess.check_output or \ hasattr(subprocess, 'check_call') and subprocess.check_call or \ subprocess.call if not hasattr(subprocess, 'check_output'): log.msg('subprocess: old Python, expect no output!') try: return oid, tag, call( args, shell=moduleContext['settings']['shell'] ) except hasattr(subprocess, 'CalledProcessError') and \ subprocess.CalledProcessError or Exception: log.msg('subprocess: external program execution failed') return context['origOid'], tag, context['errorStatus']
def variate(oid, tag, value, **context): if not context['nextFlag'] and not context['exactMatch']: return context['origOid'], tag, context['errorStatus'] if 'settings' not in recordContext: recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')]) if 'hexvalue' in recordContext['settings']: recordContext['settings']['value'] = [int(recordContext['settings']['hexvalue'][x:x+2], 16) for x in range(0, len(recordContext['settings']['hexvalue']), 2)] if 'status' in recordContext['settings']: recordContext['settings']['status'] = recordContext['settings']['status'].lower() if 'op' not in recordContext['settings']: recordContext['settings']['op'] = 'any' if 'vlist' in recordContext['settings']: vlist = {} recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':') while recordContext['settings']['vlist']: o,v,e = recordContext['settings']['vlist'][:3] recordContext['settings']['vlist'] = recordContext['settings']['vlist'][3:] v = SnmprecGrammar.tagMap[tag](v) if o not in vlist: vlist[o] = {} if o == 'eq': vlist[o][v] = e elif o in ('lt', 'gt'): vlist[o] = v, e else: log.msg('error: bad vlist syntax: %s' % recordContext['settings']['vlist']) recordContext['settings']['vlist'] = vlist e = None if context['setFlag']: if 'vlist' in recordContext['settings']: if 'eq' in recordContext['settings']['vlist'] and \ context['origValue'] in recordContext['settings']['vlist']['eq']: e = recordContext['settings']['vlist']['eq'][context['origValue']] elif 'lt' in recordContext['settings']['vlist'] and \ context['origValue'] < recordContext['settings']['vlist']['lt'][0]: e = recordContext['settings']['vlist']['lt'][1] elif 'gt' in recordContext['settings']['vlist'] and \ context['origValue'] > recordContext['settings']['vlist']['gt'][0]: e = recordContext['settings']['vlist']['gt'][1] elif recordContext['settings']['op'] in ('set', 'any'): if 'status' in recordContext['settings']: e = recordContext['settings']['status'] else: if recordContext['settings']['op'] in ('get', 'any'): if 'status' in recordContext['settings']: e = recordContext['settings']['status'] if e and e in errorTypes: log.msg('error: reporting %s for %s' % (e, oid)) raise errorTypes[e]( name=oid, idx=max(0, context['varsTotal']-context['varsRemaining']-1) ) if context['setFlag']: recordContext['settings']['value'] = context['origValue'] return oid, tag, recordContext['settings'].get('value', context['errorStatus'])
def variate(oid, tag, value, **context): if 'snmpEngine' in context and context['snmpEngine']: snmpEngine = context['snmpEngine'] if snmpEngine not in moduleContext: moduleContext[snmpEngine] = {} if context['transportDomain'] not in moduleContext[snmpEngine]: # register this SNMP Engine to handle our transports' # receiver IDs (which we build by outbound and simulator # transportDomains concatenation) snmpEngine.registerTransportDispatcher( snmpEngine.transportDispatcher, UdpTransportTarget.transportDomain + \ context['transportDomain'] ) snmpEngine.registerTransportDispatcher( snmpEngine.transportDispatcher, Udp6TransportTarget.transportDomain + \ context['transportDomain'] ) moduleContext[snmpEngine][context['transportDomain']] = 1 else: raise error.SnmpsimError('variation module not given snmpEngine') if not context['nextFlag'] and not context['exactMatch']: return context['origOid'], tag, context['errorStatus'] if 'settings' not in recordContext: recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')]) for k,v in ( ('op', 'set'), ('community', 'public'), ('authkey', None), ('authproto', 'md5'), ('privkey', None), ('privproto', 'des'), ('proto', 'udp'), ('port', '162'), ('ntftype', 'trap'), ('trapoid', '1.3.6.1.6.3.1.1.5.1') ): recordContext['settings'].setdefault(k, v) if 'hexvalue' in recordContext['settings']: recordContext['settings']['value'] = [int(recordContext['settings']['hexvalue'][x:x+2], 16) for x in range(0, len(recordContext['settings']['hexvalue']), 2)] if 'vlist' in recordContext['settings']: vlist = {} recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':') while recordContext['settings']['vlist']: o,v = recordContext['settings']['vlist'][:2] recordContext['settings']['vlist'] = recordContext['settings']['vlist'][2:] v = SnmprecGrammar.tagMap[tag](v) if o not in vlist: vlist[o] = set() if o == 'eq': vlist[o].add(v) elif o in ('lt', 'gt'): vlist[o] = v else: log.msg('notification: bad vlist syntax: %s' % recordContext['settings']['vlist']) recordContext['settings']['vlist'] = vlist args = recordContext['settings'] if context['setFlag'] and 'vlist' in args: if 'eq' in args['vlist'] and \ context['origValue'] in args['vlist']['eq']: pass elif 'lt' in args['vlist'] and \ context['origValue'] < args['vlist']['lt']: pass elif 'gt' in args['vlist'] and \ context['origValue'] > args['vlist']['gt']: pass else: return oid, tag, context['origValue'] if args['op'] not in ('get', 'set', 'any', '*'): log.msg('notification: unknown SNMP request type configured: %s' % args['op']) return context['origOid'], tag, context['errorStatus'] if args['op'] == 'get' and not context['setFlag'] or \ args['op'] == 'set' and context['setFlag'] or \ args['op'] in ('any', '*'): if args['version'] in ('1', '2c'): authData = CommunityData(args['community'], mpModel=args['version'] == '2c' and 1 or 0) elif args['version'] == '3': if args['authproto'] == 'md5': authProtocol = usmHMACMD5AuthProtocol elif args['authproto'] == 'sha': authProtocol = usmHMACSHAAuthProtocol elif args['authproto'] == 'none': authProtocol = usmNoAuthProtocol else: log.msg('notification: unknown auth proto %s' % args['authproto']) return context['origOid'], tag, context['errorStatus'] if args['privproto'] == 'des': privProtocol = usmDESPrivProtocol elif args['privproto'] == 'aes': privProtocol = usmAesCfb128Protocol elif args['privproto'] == 'none': privProtocol = usmNoPrivProtocol else: log.msg('notification: unknown privacy proto %s' % args['privproto']) return context['origOid'], tag, context['errorStatus'] authData = UsmUserData(args['user'], args['authkey'], args['privkey'], authProtocol=authProtocol, privProtocol=privProtocol) else: log.msg('notification: unknown SNMP version %s' % args['version']) return context['origOid'], tag, context['errorStatus'] if 'host' not in args: log.msg('notification: target hostname not configured for OID' % (oid,)) return context['origOid'], tag, context['errorStatus'] if args['proto'] == 'udp': target = UdpTransportTarget((args['host'], int(args['port']))) elif args['proto'] == 'udp6': target = Udp6TransportTarget((args['host'], int(args['port']))) else: log.msg('notification: unknown transport %s' % args['proto']) return context['origOid'], tag, context['errorStatus'] localAddress = None if 'bindaddr' in args: localAddress = args['bindaddr'] else: if context['transportDomain'][:len(target.transportDomain)] == \ target.transportDomain: localAddress = snmpEngine.transportDispatcher.getTransport(context['transportDomain']).getLocalAddress()[0] else: log.msg('notification: incompatible network transport types used by CommandResponder vs NotificationOriginator') if 'bindaddr' in args: localAddress = args['bindaddr'] if localAddress: log.msg('notification: binding to local address %s' % localAddress) target.setLocalAddress((localAddress, 0)) # this will make target objects different based on their bind address target.transportDomain = target.transportDomain + \ context['transportDomain'] varBinds = [] if 'uptime' in args: varBinds.append( ( ObjectIdentifier('1.3.6.1.2.1.1.3.0'), TimeTicks(args['uptime']) ) ) if args['version'] == '1': if 'agentaddress' in args: varBinds.append( ( ObjectIdentifier('1.3.6.1.6.3.18.1.3.0'), IpAddress(args['agentaddress']) ) ) if 'enterprise' in args: varBinds.append( ( ObjectIdentifier('1.3.6.1.6.3.1.1.4.3.0'), ObjectIdentifier(args['enterprise']) ) ) if 'varbinds' in args: vbs = split(args['varbinds'], ':') while vbs: varBinds.append( (ObjectIdentifier(vbs[0]), typeMap[vbs[1]](vbs[2])) ) vbs = vbs[3:] sendNotification( snmpEngine, authData, target, ContextData(), args['ntftype'], NotificationType(ObjectIdentity(args['trapoid'])).addVarBinds(*varBinds), cbFun=_cbFun, cbCtx=(oid, value) ) log.msg('notification: sending Notification to %s with credentials %s' % (authData, target)) if context['setFlag'] or 'value' not in args: return oid, tag, context['origValue'] else: return oid, tag, args['value']
def cb_fun(self, snmp_engine, send_request_handle, error_indication, error_status, error_index, var_bind_table, cb_ctx): if cb_ctx['is_snmp_timeout'] and self.snmp_parameters.get_bulk_flag: self._get_bulk_flag = True cb_ctx['is_snmp_timeout'] = False if isinstance(error_indication, RequestTimedOut): cb_ctx['is_snmp_timeout'] = True self._get_bulk_flag = False if error_indication and not cb_ctx['retries']: cb_ctx['errors'] += 1 # log.msg('SNMP Engine error: %s' % error_indication) return # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception, # so we ignore noSuchName error here if error_status and error_status != 2 or error_indication: log.msg('Remote SNMP error %s' % (error_indication or error_status.prettyPrint())) if cb_ctx['retries']: try: next_oid = var_bind_table[-1][0][0] except IndexError: next_oid = cb_ctx['lastOID'] else: log.msg('Failed OID: %s' % next_oid) # fuzzy logic of walking a broken OID if len(next_oid) < 4: pass elif (self.snmp_parameters.retry_count - cb_ctx[ 'retries']) * 10 / self.snmp_parameters.retry_count > 5: next_oid = next_oid[:-2] + (next_oid[-2] + 1,) elif next_oid[-1]: next_oid = next_oid[:-1] + (next_oid[-1] + 1,) else: next_oid = next_oid[:-2] + (next_oid[-2] + 1, 0) cb_ctx['retries'] -= 1 cb_ctx['lastOID'] = next_oid log.msg('Retrying with OID %s (%s retries left)...' % (next_oid, cb_ctx['retries'])) # initiate another SNMP walk iteration if self._get_bulk_flag: self.send_bulk_var_binds(next_oid, cb_ctx) else: self.send_walk_var_binds(next_oid, cb_ctx) cb_ctx['errors'] += 1 return if self.snmp_parameters.retry_count != cb_ctx['retries']: cb_ctx['retries'] += 1 if var_bind_table and var_bind_table[-1] and var_bind_table[-1][0]: cb_ctx['lastOID'] = var_bind_table[-1][0][0] stop_flag = False time.sleep(0.2) # Walk var-binds for varBindRow in var_bind_table: for oid, value in varBindRow: # EOM _add_line = True if self._stop_oid and oid >= self._stop_oid: stop_flag = True _add_line = False if (value is None or value.tagSet in (rfc1905.NoSuchObject.tagSet, rfc1905.NoSuchInstance.tagSet, rfc1905.EndOfMibView.tagSet)): stop_flag = True # remove value enumeration if value.tagSet == rfc1902.Integer32.tagSet: value = rfc1902.Integer32(value) if value.tagSet == rfc1902.Unsigned32.tagSet: value = rfc1902.Unsigned32(value) if value.tagSet == rfc1902.Bits.tagSet: value = rfc1902.OctetString(value) # Build .snmprec record context = { 'origOid': oid, 'origValue': value, 'count': cb_ctx['count'], 'total': cb_ctx['total'], 'iteration': cb_ctx['iteration'], 'reqTime': cb_ctx['reqTime'], 'startOID': self._oid, 'stop_flag': stop_flag, } try: line = "" if _add_line: line = self.data_file_handler.format(oid, value, **context).replace("|", ", ") except error.MoreDataNotification: cb_ctx['count'] = 0 cb_ctx['iteration'] += 1 more_data_notification = sys.exc_info()[1] if 'period' in more_data_notification: log.msg( '%s OIDs dumped, waiting %.2f sec(s)...' % ( cb_ctx['total'], more_data_notification['period'])) time.sleep(more_data_notification['period']) # initiate another SNMP walk iteration if self._get_bulk_flag: self.send_bulk_var_binds(self._oid, cb_ctx) else: self.send_walk_var_binds(self._oid, cb_ctx) stop_flag = True # stop current iteration except error.NoDataNotification: pass except error.SnmpsimError: log.msg('ERROR: %s' % (sys.exc_info()[1],)) continue else: if _add_line and line and line not in self._output_list: self._output_list.append(line) cb_ctx['count'] += 1 cb_ctx['total'] += 1 if cb_ctx['count'] % 100 == 0: log.msg('OIDs dumped: %s/%s' % ( cb_ctx['iteration'], cb_ctx['count'])) # Next request time cb_ctx['reqTime'] = time.time() # Continue walking return not stop_flag
mibBuilder = builder.MibBuilder() mibViewController = view.MibViewController(mibBuilder) compiler.addMibCompiler(mibBuilder, sources=mibSources or defaultMibSources) if isinstance(startOID, rfc1902.ObjectIdentity): startOID.resolveWithMib(mibViewController) if isinstance(stopOID, rfc1902.ObjectIdentity): stopOID.resolveWithMib(mibViewController) # Load variation module if variationModuleName: for variationModulesDir in confdir.variation: log.msg('Scanning "%s" directory for variation modules...' % variationModulesDir) if not os.path.exists(variationModulesDir): log.msg('Directory "%s" does not exist' % variationModulesDir) continue mod = os.path.join(variationModulesDir, variationModuleName + '.py') if not os.path.exists(mod): log.msg('Variation module "%s" not found' % mod) continue ctx = {'path': mod, 'moduleContext': {}} try: if sys.version_info[0] > 2: exec(compile(open(mod).read(), mod, 'exec'), ctx) else:
def variate(oid, tag, value, **context): if 'settings' not in recordContext: recordContext['settings'] = dict( [split(x, '=') for x in split(value, ',')]) if 'dir' not in recordContext['settings']: log.msg('multiplex: snapshot directory not specified') return context['origOid'], tag, context['errorStatus'] recordContext['settings']['dir'] = recordContext[ 'settings']['dir'].replace('/', os.path.sep) if recordContext['settings']['dir'][0] != os.path.sep: for x in confdir.data: d = os.path.join(x, recordContext['settings']['dir']) if os.path.exists(d): break else: log.msg('multiplex: directory %s not ' 'found' % recordContext['settings']['dir']) return context['origOid'], tag, context['errorStatus'] else: d = recordContext['settings']['dir'] recordContext['dirmap'] = dict( [(int(os.path.basename(x).split(os.path.extsep)[0]), os.path.join(d, x)) for x in os.listdir(d) if x[-7:] == 'snmprec'] ) recordContext['keys'] = list(recordContext['dirmap']) recordContext['bounds'] = ( min(recordContext['keys']), max(recordContext['keys'])) if 'period' in recordContext['settings']: recordContext['settings']['period'] = float( recordContext['settings']['period']) else: recordContext['settings']['period'] = 60.0 if 'wrap' in recordContext['settings']: recordContext['settings']['wrap'] = bool( recordContext['settings']['wrap']) else: recordContext['settings']['wrap'] = False if 'control' in recordContext['settings']: recordContext['settings']['control'] = rfc1902.ObjectName( recordContext['settings']['control']) log.msg( 'multiplex: using control OID %s for subtree %s, ' 'time-based multiplexing ' 'disabled' % (recordContext['settings']['control'], oid)) recordContext['ready'] = True if 'ready' not in recordContext: return context['origOid'], tag, context['errorStatus'] if oid not in moduleContext: moduleContext[oid] = {} if context['setFlag']: if 'control' in ( recordContext['settings'] and recordContext['settings']['control'] == context['origOid']): fileno = int(context['origValue']) if fileno >= len(recordContext['keys']): log.msg('multiplex: .snmprec file number %s over limit of' ' %s' % (fileno, len(recordContext['keys']))) return context['origOid'], tag, context['errorStatus'] moduleContext[oid]['fileno'] = fileno log.msg( 'multiplex: switched to file #%s ' '(%s)' % (recordContext['keys'][fileno], recordContext['dirmap'][recordContext['keys'][fileno]])) return context['origOid'], tag, context['origValue'] else: return context['origOid'], tag, context['errorStatus'] if 'control' in recordContext['settings']: if 'fileno' not in moduleContext[oid]: moduleContext[oid]['fileno'] = 0 if (not context['nextFlag'] and recordContext['settings']['control'] == context['origOid']): val = rfc1902.Integer32(moduleContext[oid]['fileno']) return context['origOid'], tag, val else: period = recordContext['settings']['period'] uptime = time.time() - moduleContext['booted'] timeslot = uptime % (period * len(recordContext['dirmap'])) fileslot = int(timeslot / period) + recordContext['bounds'][0] fileno = bisect.bisect(recordContext['keys'], fileslot) - 1 if ('fileno' not in moduleContext[oid] or moduleContext[oid]['fileno'] < fileno or recordContext['settings']['wrap']): moduleContext[oid]['fileno'] = fileno datafile = recordContext['dirmap'][ recordContext['keys'][moduleContext[oid]['fileno']]] if ('datafile' not in moduleContext[oid] or moduleContext[oid]['datafile'] != datafile): if 'datafileobj' in moduleContext[oid]: moduleContext[oid]['datafileobj'].close() recordIndex = RecordIndex(datafile, SnmprecRecord()).create() moduleContext[oid]['datafileobj'] = recordIndex moduleContext[oid]['datafile'] = datafile log.msg( 'multiplex: switching to data file %s for ' '%s' % (datafile, context['origOid'])) text, db = moduleContext[oid]['datafileobj'].getHandles() textOid = str(rfc1902.OctetString( '.'.join(['%s' % x for x in context['origOid']]))) try: line = moduleContext[oid]['datafileobj'].lookup(textOid) except KeyError: offset = searchRecordByOid(context['origOid'], text, SnmprecRecord()) exactMatch = False else: offset, subtreeFlag, prevOffset = line.split(str2octs(',')) exactMatch = True text.seek(int(offset)) line, _, _ = getRecord(text) # matched line if context['nextFlag']: if exactMatch: line, _, _ = getRecord(text) else: if not exactMatch: return context['origOid'], tag, context['errorStatus'] if not line: return context['origOid'], tag, context['errorStatus'] try: oid, value = SnmprecRecord().evaluate(line) except error.SnmpsimError: oid, value = context['origOid'], context['errorStatus'] return oid, tag, value
def variate(oid, tag, value, **context): if 'dbConn' in moduleContext: dbConn = moduleContext['dbConn'] else: raise error.SnmpsimError('variation module not initialized') cursor = dbConn.cursor() try: cursor.execute('set session transaction isolation level %s' % moduleContext['isolationLevel']) cursor.fetchall() except: # non-MySQL/Postgres pass if value: dbTable = value.split(',').pop(0) elif 'dbTable' in moduleContext: dbTable = moduleContext['dbTable'] else: log.msg('SQL table not specified for OID %s' % (context['origOid'], )) return context['origOid'], tag, context['errorStatus'] origOid = context['origOid'] sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')]) if context['setFlag']: if 'hexvalue' in context: textTag = context['hextag'] textValue = context['hexvalue'] else: textTag = SnmprecGrammar().getTagByType(context['origValue']) textValue = str(context['origValue']) cursor.execute( 'select maxaccess,tag,value from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid)) resultset = cursor.fetchone() if resultset: maxaccess = resultset[0] if maxaccess != 'read-write': return origOid, tag, context['errorStatus'] value_written = textValue try: value_settings = {} value_settings = dict( [split(x, '=') for x in split(resultset[2], ',')]) print value_settings # if detected error mode, raise an error if 'mode' in value_settings and \ value_settings['mode'] == 'error': raise Error.WrongValueError( name=origOid, idx=max( 0, context['varsTotal'] - context['varsRemaining'] - 1)) elif 'mode' in value_settings and \ value_settings['mode'] == 'normal': value_written = "mode=" + value_settings['mode'] + \ ",value=" + textValue else: return origOid, tag, context['errorStatus'] except Error.WrongValueError: cursor.close() raise Error.WrongValueError(name=origOid, idx=max( 0, context['varsTotal'] - context['varsRemaining'] - 1)) except: pass cursor.execute( 'update %s set tag=\'%s\',value=\'%s\' where oid=\'%s\'' % (dbTable, textTag, value_written, sqlOid)) inform = moduleContext.get('inform') try: value = str(origOid) + " " + textValue written_len = os.write(inform, value) if written_len != len(value): log.msg( "--->Infrasim: Expected length %d, actual length %d\n" % (len(str(origOid)), written_len)) cursor.close() return origOid, tag, context['errorStatus'] except Exception, ex: log.msg("--->Infrasim: {0}".format(ex)) cursor.close() return origOid, tag, context['errorStatus'] else: cursor.close() raise Error.NoSuchInstanceError( name=origOid, idx=max(0, context['varsTotal'] - context['varsRemaining'] - 1)) if context['varsRemaining'] == 0: # last OID in PDU dbConn.commit() cursor.close() return origOid, textTag, context['origValue']
def variate(oid, tag, value, **context): if not context['nextFlag'] and not context['exactMatch']: return context['origOid'], tag, context['errorStatus'] if 'settings' not in recordContext: recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')]) if 'hexvalue' in recordContext['settings']: recordContext['settings']['value'] = [int(recordContext['settings']['hexvalue'][x:x + 2], 16) for x in range(0, len(recordContext['settings']['hexvalue']), 2)] if 'wait' in recordContext['settings']: recordContext['settings']['wait'] = float(recordContext['settings']['wait']) else: recordContext['settings']['wait'] = 500.0 if 'deviation' in recordContext['settings']: recordContext['settings']['deviation'] = float(recordContext['settings']['deviation']) else: recordContext['settings']['deviation'] = 0.0 if 'vlist' in recordContext['settings']: vlist = {} recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':') while recordContext['settings']['vlist']: o, v, d = recordContext['settings']['vlist'][:3] recordContext['settings']['vlist'] = recordContext['settings']['vlist'][3:] d = int(d) v = SnmprecGrammar.tagMap[tag](v) if o not in vlist: vlist[o] = {} if o == 'eq': vlist[o][v] = d elif o in ('lt', 'gt'): vlist[o] = v, d else: log.msg('delay: bad vlist syntax: %s' % recordContext['settings']['vlist']) recordContext['settings']['vlist'] = vlist if 'tlist' in recordContext['settings']: tlist = {} recordContext['settings']['tlist'] = split(recordContext['settings']['tlist'], ':') while recordContext['settings']['tlist']: o, v, d = recordContext['settings']['tlist'][:3] recordContext['settings']['tlist'] = recordContext['settings']['tlist'][3:] v = int(v) d = int(d) if o not in tlist: tlist[o] = {} if o == 'eq': tlist[o][v] = d elif o in ('lt', 'gt'): tlist[o] = v, d else: log.msg('delay: bad tlist syntax: %s' % recordContext['settings']['tlist']) recordContext['settings']['tlist'] = tlist if context['setFlag'] and 'vlist' in recordContext['settings']: if ('eq' in recordContext['settings']['vlist'] and context['origValue'] in recordContext['settings']['vlist']['eq']): delay = recordContext['settings']['vlist']['eq'][context['origValue']] elif ('lt' in recordContext['settings']['vlist'] and context['origValue'] < recordContext['settings']['vlist']['lt'][0]): delay = recordContext['settings']['vlist']['lt'][1] elif ('gt' in recordContext['settings']['vlist'] and context['origValue'] > recordContext['settings']['vlist']['gt'][0]): delay = recordContext['settings']['vlist']['gt'][1] else: delay = recordContext['settings']['wait'] elif 'tlist' in recordContext['settings']: now = int(time.time()) if ('eq' in recordContext['settings']['tlist'] and now == recordContext['settings']['tlist']['eq']): delay = recordContext['settings']['tlist']['eq'][now] elif ('lt' in recordContext['settings']['tlist'] and now < recordContext['settings']['tlist']['lt'][0]): delay = recordContext['settings']['tlist']['lt'][1] elif ('gt' in recordContext['settings']['tlist'] and now > recordContext['settings']['tlist']['gt'][0]): delay = recordContext['settings']['tlist']['gt'][1] else: delay = recordContext['settings']['wait'] else: delay = recordContext['settings']['wait'] if recordContext['settings']['deviation']: delay += random.randrange( -recordContext['settings']['deviation'], recordContext['settings']['deviation'] ) if delay < 0: delay = 0 elif delay > 99999: log.msg('delay: dropping response for %s' % oid) raise error.NoDataNotification() log.msg('delay: waiting %d milliseconds for %s' % (delay, oid)) time.sleep(delay / 1000) # ms if context['setFlag'] or 'value' not in recordContext['settings']: return oid, tag, context['origValue'] else: return oid, tag, recordContext['settings']['value']
sys.exit(-1) if privProtocols[v3PrivProto] == config.usmNoPrivProtocol: if v3PrivKey is not None: v3PrivProto = 'DES' else: if v3PrivKey is None: sys.stderr.write('ERROR: --v3-priv-key is missing\r\n%s\r\n' % helpMessage) sys.exit(-1) else: v3ContextEngineId = None v3ContextName = '' log.setLogger('snmprec', 'stderr') if getBulkFlag and not snmpVersion: log.msg('WARNING: will be using GETNEXT with SNMPv1!') getBulkFlag = False # Attempt to reopen std output stream in binary mode if outputFile is sys.stderr: if sys.version_info[0] > 2: outputFile = outputFile.buffer elif sys.platform == "win32": import msvcrt msvcrt.setmode(outputFile.fileno(), os.O_BINARY) # Load variation module if variationModuleName: for variationModulesDir in confdir.variation: log.msg('Scanning "%s" directory for variation modules...' % variationModulesDir)
def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus, errorIndex, varBindTable, cbCtx): if errorIndication and not cbCtx['retries']: cbCtx['errors'] += 1 log.msg('SNMP Engine error: %s' % errorIndication) return # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception, # so we ignore noSuchName error here if errorStatus and errorStatus != 2 or errorIndication: log.msg('Remote SNMP error %s' % (errorIndication or errorStatus.prettyPrint())) if cbCtx['retries']: try: nextOID = varBindTable[-1][0][0] except IndexError: nextOID = cbCtx['lastOID'] else: log.msg('Failed OID: %s' % nextOID) # fuzzy logic of walking a broken OID if len(nextOID) < 4: pass elif (continueOnErrors-cbCtx['retries'])*10/continueOnErrors > 5: nextOID = nextOID[:-2] + (nextOID[-2]+1,) elif nextOID[-1]: nextOID = nextOID[:-1] + (nextOID[-1]+1,) else: nextOID = nextOID[:-2] + (nextOID[-2]+1, 0) cbCtx['retries'] -= 1 cbCtx['lastOID'] = nextOID log.msg('Retrying with OID %s (%s retries left)...' % (nextOID, cbCtx['retries'])) # initiate another SNMP walk iteration if getBulkFlag: cmdGen.sendVarBinds( snmpEngine, 'tgt', v3ContextEngineId, v3Context, 0, getBulkRepetitions, [ (nextOID, None) ], cbFun, cbCtx ) else: cmdGen.sendVarBinds( snmpEngine, 'tgt', v3ContextEngineId, v3Context, [ (nextOID, None) ], cbFun, cbCtx ) cbCtx['errors'] += 1 return if continueOnErrors != cbCtx['retries']: cbCtx['retries'] += 1 if varBindTable and varBindTable[-1] and varBindTable[-1][0]: cbCtx['lastOID'] = varBindTable[-1][0][0] stopFlag = False # Walk var-binds for varBindRow in varBindTable: for oid, val in varBindRow: # EOM if stopOID and oid >= stopOID: stopFlag = True # stop on out of range condition elif val is None or \ val.tagSet in (rfc1905.NoSuchObject.tagSet, rfc1905.NoSuchInstance.tagSet, rfc1905.EndOfMibView.tagSet): stopFlag = True # Build .snmprec record context = { 'origOid': oid, 'origValue': val, 'count': cbCtx['count'], 'total': cbCtx['total'], 'iteration': cbCtx['iteration'], 'reqTime': cbCtx['reqTime'], 'startOID': startOID, 'stopOID': stopOID, 'stopFlag': stopFlag, 'variationModule': variationModule } try: line = dataFileHandler.format(oid, val, **context) except error.MoreDataNotification: cbCtx['count'] = 0 cbCtx['iteration'] += 1 moreDataNotification = sys.exc_info()[1] if 'period' in moreDataNotification: log.msg('%s OIDs dumped, waiting %.2f sec(s)...' % (cbCtx['total'], moreDataNotification['period'])) time.sleep(moreDataNotification['period']) # initiate another SNMP walk iteration if getBulkFlag: cmdGen.sendVarBinds( snmpEngine, 'tgt', v3ContextEngineId, v3Context, 0, getBulkRepetitions, [ (startOID, None) ], cbFun, cbCtx ) else: cmdGen.sendVarBinds( snmpEngine, 'tgt', v3ContextEngineId, v3Context, [ (startOID, None) ], cbFun, cbCtx ) stopFlag = True # stop current iteration except error.NoDataNotification: pass except error.SnmpsimError: log.msg('ERROR: %s' % (sys.exc_info()[1],)) continue else: outputFile.write(line) cbCtx['count'] += 1 cbCtx['total'] += 1 if cbCtx['count'] % 100 == 0: log.msg('OIDs dumped: %s/%s' % (cbCtx['iteration'], cbCtx['count'])) # Next request time cbCtx['reqTime'] = time.time() # Continue walking return not stopFlag
def variate(oid, tag, value, **context): if not context['nextFlag'] and not context['exactMatch']: return context['origOid'], tag, context['errorStatus'] if 'settings' not in recordContext: recordContext['settings'] = dict( [split(x, '=') for x in split(value, ',')]) if 'hexvalue' in recordContext['settings']: recordContext['settings']['value'] = [ int(recordContext['settings']['hexvalue'][x:x + 2], 16) for x in range( 0, len(recordContext['settings']['hexvalue']), 2) ] if 'status' in recordContext['settings']: recordContext['settings']['status'] = recordContext['settings'][ 'status'].lower() if 'op' not in recordContext['settings']: recordContext['settings']['op'] = 'any' if 'vlist' in recordContext['settings']: vlist = {} recordContext['settings']['vlist'] = split( recordContext['settings']['vlist'], ':') while recordContext['settings']['vlist']: o, v, e = recordContext['settings']['vlist'][:3] recordContext['settings']['vlist'] = recordContext['settings'][ 'vlist'][3:] typeTag, _ = SnmprecRecord.unpackTag(tag) v = SnmprecGrammar.tagMap[typeTag](v) if o not in vlist: vlist[o] = {} if o == 'eq': vlist[o][v] = e elif o in ('lt', 'gt'): vlist[o] = v, e else: log.msg('error: bad vlist syntax: %s' % recordContext['settings']['vlist']) recordContext['settings']['vlist'] = vlist e = None if context['setFlag']: if 'vlist' in recordContext['settings']: if ('eq' in recordContext['settings']['vlist'] and context['origValue'] in recordContext['settings']['vlist']['eq']): e = recordContext['settings']['vlist']['eq'][ context['origValue']] elif ('lt' in recordContext['settings']['vlist'] and context['origValue'] < recordContext['settings']['vlist']['lt'][0]): e = recordContext['settings']['vlist']['lt'][1] elif ('gt' in recordContext['settings']['vlist'] and context['origValue'] > recordContext['settings']['vlist']['gt'][0]): e = recordContext['settings']['vlist']['gt'][1] elif recordContext['settings']['op'] in ('set', 'any'): if 'status' in recordContext['settings']: e = recordContext['settings']['status'] else: if recordContext['settings']['op'] in ('get', 'any'): if 'status' in recordContext['settings']: e = recordContext['settings']['status'] if e and e in errorTypes: log.msg('error: reporting %s for %s' % (e, oid)) raise errorTypes[e]( name=oid, idx=max(0, context['varsTotal'] - context['varsRemaining'] - 1)) if context['setFlag']: recordContext['settings']['value'] = context['origValue'] return oid, tag, recordContext['settings'].get('value', context['errorStatus'])
def variate(oid, tag, value, **context): if 'dbConn' in moduleContext: dbConn = moduleContext['dbConn'] else: raise error.SnmpsimError('variation module not initialized') cursor = dbConn.cursor() try: cursor.execute( 'set session transaction isolation level %s' % isolationLevels[moduleContext['isolationLevel']] ) cursor.fetchall() except: # non-MySQL/Postgres pass if value: dbTable = value.split(',').pop(0) elif 'dbTable' in moduleContext: dbTable = moduleContext['dbTable'] else: log.msg('SQL table not specified for OID %s' % (context['origOid'],)) return context['origOid'], tag, context['errorStatus'] origOid = context['origOid'] sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')]) if context['setFlag']: if 'hexvalue' in context: textTag = context['hextag'] textValue = context['hexvalue'] else: textTag = SnmprecGrammar().getTagByType(context['origValue']) textValue = str(context['origValue']) cursor.execute( 'select maxaccess,tag from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid) ) resultset = cursor.fetchone() if resultset: maxaccess = resultset[0] if maxaccess != 'read-write': return origOid, tag, context['errorStatus'] cursor.execute( 'update %s set tag=\'%s\',value=\'%s\' where oid=\'%s\'' % (dbTable, textTag, textValue, sqlOid) ) else: cursor.execute( 'insert into %s values (\'%s\', \'%s\', \'%s\', \'read-write\')' % (dbTable, sqlOid, textTag, textValue) ) if context['varsRemaining'] == 0: # last OID in PDU dbConn.commit() cursor.close() return origOid, textTag, context['origValue'] else: if context['nextFlag']: cursor.execute('select oid from %s where oid>\'%s\' order by oid limit 1' % (dbTable, sqlOid)) resultset = cursor.fetchone() if resultset: origOid = origOid.clone( '.'.join([x.strip() for x in str(resultset[0]).split('.')]) ) sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')]) else: cursor.close() return origOid, tag, context['errorStatus'] cursor.execute('select tag, value from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid)) resultset = cursor.fetchone() cursor.close() if resultset: return origOid, str(resultset[0]), str(resultset[1]) else: return origOid, tag, context['errorStatus']
def record(oid, tag, value, **context): if 'started' not in moduleContext: moduleContext['started'] = time.time() if 'iterations' not in moduleContext: moduleContext['iterations'] = min( 1, moduleContext['settings'].get('iterations', 0)) # single-run recording if 'iterations' not in moduleContext[ 'settings'] or not moduleContext['settings']['iterations']: if context['origValue'].tagSet not in (rfc1902.Counter32.tagSet, rfc1902.Counter64.tagSet, rfc1902.TimeTicks.tagSet, rfc1902.Gauge32.tagSet, rfc1902.Integer.tagSet): if 'hextag' in context: tag = context['hextag'] if 'hexvalue' in context: value = context['hexvalue'] return oid, tag, value if 'taglist' not in moduleContext['settings'] or \ tag not in moduleContext['settings']['taglist']: return oid, tag, value value = 'initial=%s' % value if context['origValue'].tagSet == rfc1902.TimeTicks.tagSet: value += ',rate=100' elif context['origValue'].tagSet == rfc1902.Integer.tagSet: value += ',rate=0' return oid, tag + ':numeric', value # multiple-iteration recording if oid not in moduleContext: settings = {'initial': value} if context['origValue'].tagSet == rfc1902.TimeTicks.tagSet: settings['rate'] = 100 elif context['origValue'].tagSet == rfc1902.Integer.tagSet: settings['rate'] = 0 # may be constants if 'addon' in moduleContext['settings']: settings.update( dict([ split(x, '=') for x in moduleContext['settings']['addon'] ])) moduleContext[oid] = {} moduleContext[oid]['settings'] = settings if moduleContext['iterations']: if context['stopFlag']: # switching to final iteration log.msg('numeric: %s iterations remaining' % moduleContext['settings']['iterations']) moduleContext['iterations'] -= 1 moduleContext['started'] = time.time() wait = max( 0, float(moduleContext['settings']['period']) - (time.time() - moduleContext['started'])) raise error.MoreDataNotification(period=wait) else: # storing values on first iteration moduleContext[oid]['time'] = time.time() moduleContext[oid]['value'] = context['origValue'] if 'hexvalue' in moduleContext[oid]: moduleContext[oid]['hexvalue'] = context['hexvalue'] if 'hextag' in moduleContext[oid]: moduleContext[oid]['hextag'] = context['hextag'] raise error.NoDataNotification() else: if context['stopFlag']: raise error.NoDataNotification() if 'value' in moduleContext[oid]: if context['origValue'].tagSet not in (rfc1902.Counter32.tagSet, rfc1902.Counter64.tagSet, rfc1902.TimeTicks.tagSet, rfc1902.Gauge32.tagSet, rfc1902.Integer.tagSet): if 'hextag' in moduleContext[oid]: tag = moduleContext[oid]['hextag'] if 'hexvalue' in moduleContext[oid]: value = moduleContext[oid]['hexvalue'] return oid, tag, value if tag not in moduleContext['settings']['taglist']: return oid, tag, moduleContext[oid]['value'] moduleContext[oid]['settings']['rate'] = (int( context['origValue']) - int(moduleContext[oid]['value'])) / ( time.time() - moduleContext[oid]['time']) tag += ':numeric' value = ','.join([ '%s=%s' % (k, v) for k, v in moduleContext[oid]['settings'].items() ]) return oid, tag, value else: raise error.NoDataNotification()
def variate(oid, tag, value, **context): if 'dbConn' in moduleContext: dbConn = moduleContext['dbConn'] else: raise error.SnmpsimError('variation module not initialized') cursor = dbConn.cursor() try: cursor.execute( 'set session transaction isolation level %s' % moduleContext['isolationLevel'] ) cursor.fetchall() except: # non-MySQL/Postgres pass if value: dbTable = value.split(',').pop(0) elif 'dbTable' in moduleContext: dbTable = moduleContext['dbTable'] else: log.msg('SQL table not specified for OID %s' % (context['origOid'],)) return context['origOid'], tag, context['errorStatus'] origOid = context['origOid'] sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')]) if context['setFlag']: if 'hexvalue' in context: textTag = context['hextag'] textValue = context['hexvalue'] else: textTag = SnmprecGrammar().getTagByType(context['origValue']) textValue = str(context['origValue']) cursor.execute( 'select maxaccess,tag,value from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid) ) resultset = cursor.fetchone() if resultset: maxaccess = resultset[0] if maxaccess != 'read-write': return origOid, tag, context['errorStatus'] value_written = textValue try: value_settings = {} value_settings = dict([split(x, '=') for x in split(resultset[2], ',')]) print value_settings # if detected error mode, raise an error if 'mode' in value_settings and \ value_settings['mode'] == 'error': raise Error.WrongValueError(name=origOid, idx=max(0, context['varsTotal'] - context['varsRemaining'] - 1)) elif 'mode' in value_settings and \ value_settings['mode'] == 'normal': value_written = "mode=" + value_settings['mode'] + \ ",value=" + textValue else: return origOid, tag, context['errorStatus'] except Error.WrongValueError: cursor.close() raise Error.WrongValueError(name=origOid, idx=max(0, context['varsTotal'] - context['varsRemaining'] - 1)) except: pass cursor.execute( 'update %s set tag=\'%s\',value=\'%s\' where oid=\'%s\'' % (dbTable, textTag, value_written, sqlOid) ) inform = moduleContext.get('inform') try: value = str(origOid) + " " + textValue written_len = os.write(inform, value) if written_len != len(value): log.msg("--->Infrasim: Expected length %d, actual length %d\n" % (len(str(origOid)), written_len)) cursor.close() return origOid, tag, context['errorStatus'] except Exception, ex: log.msg("--->Infrasim: {0}".format(ex)) cursor.close() return origOid, tag, context['errorStatus'] else: cursor.close() raise Error.NoSuchInstanceError(name=origOid, idx=max(0, context['varsTotal'] - context['varsRemaining'] - 1)) if context['varsRemaining'] == 0: # last OID in PDU dbConn.commit() cursor.close() return origOid, textTag, context['origValue']
def variate(oid, tag, value, **context): if 'snmpEngine' in context and context['snmpEngine']: snmpEngine = context['snmpEngine'] if snmpEngine not in moduleContext: moduleContext[snmpEngine] = {} if context['transportDomain'] not in moduleContext[snmpEngine]: # register this SNMP Engine to handle our transports' # receiver IDs (which we build by outbound and simulator # transportDomains concatenation) snmpEngine.registerTransportDispatcher( snmpEngine.transportDispatcher, UdpTransportTarget.transportDomain + \ context['transportDomain'] ) snmpEngine.registerTransportDispatcher( snmpEngine.transportDispatcher, Udp6TransportTarget.transportDomain + \ context['transportDomain'] ) moduleContext[snmpEngine][context['transportDomain']] = 1 else: raise error.SnmpsimError('variation module not given snmpEngine') if not context['nextFlag'] and not context['exactMatch']: return context['origOid'], tag, context['errorStatus'] if 'settings' not in recordContext: recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')]) for k, v in (('op', 'set'), ('community', 'public'), ('authkey', None), ('authproto', 'md5'), ('privkey', None), ('privproto', 'des'), ('proto', 'udp'), ('port', '162'), ('ntftype', 'trap'), ('trapoid', '1.3.6.1.6.3.1.1.5.1')): recordContext['settings'].setdefault(k, v) if 'hexvalue' in recordContext['settings']: recordContext['settings']['value'] = [int(recordContext['settings']['hexvalue'][x:x + 2], 16) for x in range(0, len(recordContext['settings']['hexvalue']), 2)] if 'vlist' in recordContext['settings']: vlist = {} recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':') while recordContext['settings']['vlist']: o, v = recordContext['settings']['vlist'][:2] recordContext['settings']['vlist'] = recordContext['settings']['vlist'][2:] v = SnmprecGrammar.tagMap[tag](v) if o not in vlist: vlist[o] = set() if o == 'eq': vlist[o].add(v) elif o in ('lt', 'gt'): vlist[o] = v else: log.msg('notification: bad vlist syntax: %s' % recordContext['settings']['vlist']) recordContext['settings']['vlist'] = vlist args = recordContext['settings'] if context['setFlag'] and 'vlist' in args: if 'eq' in args['vlist'] and \ context['origValue'] in args['vlist']['eq']: pass elif 'lt' in args['vlist'] and \ context['origValue'] < args['vlist']['lt']: pass elif 'gt' in args['vlist'] and \ context['origValue'] > args['vlist']['gt']: pass else: return oid, tag, context['origValue'] if args['op'] not in ('get', 'set', 'any', '*'): log.msg('notification: unknown SNMP request type configured: %s' % args['op']) return context['origOid'], tag, context['errorStatus'] if args['op'] == 'get' and not context['setFlag'] or \ args['op'] == 'set' and context['setFlag'] or \ args['op'] in ('any', '*'): if args['version'] in ('1', '2c'): authData = CommunityData(args['community'], mpModel=args['version'] == '2c' and 1 or 0) elif args['version'] == '3': if args['authproto'] == 'md5': authProtocol = usmHMACMD5AuthProtocol elif args['authproto'] == 'sha': authProtocol = usmHMACSHAAuthProtocol elif args['authproto'] == 'none': authProtocol = usmNoAuthProtocol else: log.msg('notification: unknown auth proto %s' % args['authproto']) return context['origOid'], tag, context['errorStatus'] if args['privproto'] == 'des': privProtocol = usmDESPrivProtocol elif args['privproto'] == 'aes': privProtocol = usmAesCfb128Protocol elif args['privproto'] == 'none': privProtocol = usmNoPrivProtocol else: log.msg('notification: unknown privacy proto %s' % args['privproto']) return context['origOid'], tag, context['errorStatus'] authData = UsmUserData(args['user'], args['authkey'], args['privkey'], authProtocol=authProtocol, privProtocol=privProtocol) else: log.msg('notification: unknown SNMP version %s' % args['version']) return context['origOid'], tag, context['errorStatus'] if 'host' not in args: log.msg('notification: target hostname not configured for OID %s' % (oid,)) return context['origOid'], tag, context['errorStatus'] if args['proto'] == 'udp': target = UdpTransportTarget((args['host'], int(args['port']))) elif args['proto'] == 'udp6': target = Udp6TransportTarget((args['host'], int(args['port']))) else: log.msg('notification: unknown transport %s' % args['proto']) return context['origOid'], tag, context['errorStatus'] localAddress = None if 'bindaddr' in args: localAddress = args['bindaddr'] else: if context['transportDomain'][:len(target.transportDomain)] == \ target.transportDomain: localAddress = \ snmpEngine.transportDispatcher.getTransport(context['transportDomain']).getLocalAddress()[0] else: log.msg( 'notification: incompatible network transport types used by CommandResponder vs NotificationOriginator') if 'bindaddr' in args: localAddress = args['bindaddr'] if localAddress: log.msg('notification: binding to local address %s' % localAddress) target.setLocalAddress((localAddress, 0)) # this will make target objects different based on their bind address target.transportDomain = target.transportDomain + \ context['transportDomain'] varBinds = [] if 'uptime' in args: varBinds.append( (ObjectIdentifier('1.3.6.1.2.1.1.3.0'), TimeTicks(args['uptime'])) ) if args['version'] == '1': if 'agentaddress' in args: varBinds.append( (ObjectIdentifier('1.3.6.1.6.3.18.1.3.0'), IpAddress(args['agentaddress'])) ) if 'enterprise' in args: varBinds.append( (ObjectIdentifier('1.3.6.1.6.3.1.1.4.3.0'), ObjectIdentifier(args['enterprise'])) ) if 'varbinds' in args: vbs = split(args['varbinds'], ':') while vbs: varBinds.append( (ObjectIdentifier(vbs[0]), typeMap[vbs[1]](vbs[2])) ) vbs = vbs[3:] sendNotification( snmpEngine, authData, target, ContextData(), args['ntftype'], NotificationType(ObjectIdentity(args['trapoid'])).addVarBinds(*varBinds), cbFun=_cbFun, cbCtx=(oid, value) ) log.msg('notification: sending Notification to %s with credentials %s' % (authData, target)) if context['setFlag'] or 'value' not in args: return oid, tag, context['origValue'] else: return oid, tag, args['value']
def record(oid, tag, value, **context): if 'started' not in moduleContext: moduleContext['started'] = time.time() if 'iterations' not in moduleContext: moduleContext['iterations'] = min( 1, moduleContext['settings'].get('iterations', 0)) # single-run recording iterations = moduleContext['settings'].get('iterations') if not iterations: if context['origValue'].tagSet not in INTEGER_TYPES: if 'hextag' in context: tag = context['hextag'] if 'hexvalue' in context: value = context['hexvalue'] return oid, tag, value if ('taglist' not in moduleContext['settings'] or tag not in moduleContext['settings']['taglist']): return oid, tag, value value = 'initial=%s' % value if context['origValue'].tagSet == rfc1902.TimeTicks.tagSet: value += ',rate=100' elif context['origValue'].tagSet == rfc1902.Integer.tagSet: value += ',rate=0' return oid, tag + ':numeric', value # multiple-iteration recording if oid not in moduleContext: settings = { 'initial': value } if context['origValue'].tagSet == rfc1902.TimeTicks.tagSet: settings['rate'] = 100 elif context['origValue'].tagSet == rfc1902.Integer.tagSet: settings['rate'] = 0 # may be constants if 'addon' in moduleContext['settings']: settings.update( dict([split(x, '=') for x in moduleContext['settings']['addon']])) moduleContext[oid] = {} moduleContext[oid]['settings'] = settings if moduleContext['iterations']: if context['stopFlag']: # switching to final iteration log.msg('numeric: %s iterations ' 'remaining' % moduleContext['iterations']) moduleContext['iterations'] -= 1 moduleContext['started'] = time.time() running = time.time() - moduleContext['started'] wait = max(0, float(moduleContext['settings']['period']) - running) raise error.MoreDataNotification(period=wait) else: # storing values on first iteration moduleContext[oid]['time'] = time.time() moduleContext[oid]['value'] = context['origValue'] if 'hexvalue' in moduleContext[oid]: moduleContext[oid]['hexvalue'] = context['hexvalue'] if 'hextag' in moduleContext[oid]: moduleContext[oid]['hextag'] = context['hextag'] raise error.NoDataNotification() else: if context['stopFlag']: raise error.NoDataNotification() if 'value' in moduleContext[oid]: if context['origValue'].tagSet not in INTEGER_TYPES: if 'hextag' in moduleContext[oid]: tag = moduleContext[oid]['hextag'] if 'hexvalue' in moduleContext[oid]: value = moduleContext[oid]['hexvalue'] return oid, tag, value if tag not in moduleContext['settings']['taglist']: return oid, tag, moduleContext[oid]['value'] diff = int(context['origValue']) - int(moduleContext[oid]['value']) runtime = time.time() - moduleContext[oid]['time'] moduleContext[oid]['settings']['rate'] = diff / runtime tag += ':numeric' value = ','.join( ['%s=%s' % (k, v) for k, v in moduleContext[oid]['settings'].items()]) return oid, tag, value else: raise error.NoDataNotification()
def variate(oid, tag, value, **context): if not context['nextFlag'] and not context['exactMatch']: return context['origOid'], tag, context['errorStatus'] if 'settings' not in recordContext: recordContext['settings'] = dict( [split(x, '=') for x in split(value, ',')]) if 'vlist' in recordContext['settings']: vlist = {} recordContext['settings']['vlist'] = split( recordContext['settings']['vlist'], ':') while recordContext['settings']['vlist']: o, v, e = recordContext['settings']['vlist'][:3] vl = recordContext['settings']['vlist'][3:] recordContext['settings']['vlist'] = vl typeTag, _ = SnmprecRecord.unpackTag(tag) v = SnmprecGrammar.TAG_MAP[typeTag](v) if o not in vlist: vlist[o] = {} if o == 'eq': vlist[o][v] = e elif o in ('lt', 'gt'): vlist[o] = v, e else: log.msg('writecache: bad vlist syntax: ' '%s' % recordContext['settings']['vlist']) recordContext['settings']['vlist'] = vlist if 'status' in recordContext['settings']: st = recordContext['settings']['status'].lower() recordContext['settings']['status'] = st if oid not in moduleContext: moduleContext[oid] = {} typeTag, _ = SnmprecRecord.unpackTag(tag) moduleContext[oid]['type'] = SnmprecGrammar.TAG_MAP[typeTag]() textOid = str(oid) if context['setFlag']: if 'vlist' in recordContext['settings']: if ('eq' in recordContext['settings']['vlist'] and context['origValue'] in recordContext['settings']['vlist']['eq']): e = recordContext['settings']['vlist']['eq'][ context['origValue']] elif ('lt' in recordContext['settings']['vlist'] and context['origValue'] < recordContext['settings']['vlist']['lt'][0]): e = recordContext['settings']['vlist']['lt'][1] elif ('gt' in recordContext['settings']['vlist'] and context['origValue'] > recordContext['settings']['vlist']['gt'][0]): e = recordContext['settings']['vlist']['gt'][1] else: e = None if e in ERROR_TYPES: idx = max(0, context['varsTotal'] - context['varsRemaining'] - 1) raise ERROR_TYPES[e](name=oid, idx=idx) if moduleContext[oid]['type'].isSameTypeWith(context['origValue']): moduleContext['cache'][textOid] = context['origValue'] else: return context['origOid'], tag, context['errorStatus'] if 'status' in recordContext['settings']: if ('op' not in recordContext['settings'] or recordContext['settings']['op'] == 'any' or recordContext['settings']['op'] == 'set' and context['setFlag'] or recordContext['settings']['op'] == 'get' and not context['setFlag']): e = recordContext['settings']['status'] if e in ERROR_TYPES: idx = max(0, context['varsTotal'] - context['varsRemaining'] - 1) raise ERROR_TYPES[e](name=oid, idx=idx) if textOid in moduleContext['cache']: return oid, tag, moduleContext['cache'][textOid] elif 'hexvalue' in recordContext['settings']: return oid, tag, moduleContext[oid]['type'].clone( hexValue=recordContext['settings']['hexvalue']) elif 'value' in recordContext['settings']: return oid, tag, moduleContext[oid]['type'].clone( recordContext['settings']['value']) else: return oid, tag, context['errorStatus']
mibViewController = view.MibViewController(mibBuilder) compiler.addMibCompiler( mibBuilder, sources=mibSources or defaultMibSources ) if isinstance(startOID, rfc1902.ObjectIdentity): startOID.resolveWithMib(mibViewController) if isinstance(stopOID, rfc1902.ObjectIdentity): stopOID.resolveWithMib(mibViewController) # Load variation module if variationModuleName: for variationModulesDir in confdir.variation: log.msg('Scanning "%s" directory for variation modules...' % variationModulesDir) if not os.path.exists(variationModulesDir): log.msg('Directory "%s" does not exist' % variationModulesDir) continue mod = os.path.join(variationModulesDir, variationModuleName + '.py') if not os.path.exists(mod): log.msg('Variation module "%s" not found' % mod) continue ctx = { 'path': mod, 'moduleContext': {} } try: if sys.version_info[0] > 2: exec(compile(open(mod).read(), mod, 'exec'), ctx) else:
def variate(oid, tag, value, **context): if 'dbConn' in moduleContext: dbConn = moduleContext['dbConn'] else: raise error.SnmpsimError('variation module not initialized') cursor = dbConn.cursor() try: cursor.execute( 'set session transaction isolation level %s' % moduleContext['isolationLevel'] ) cursor.fetchall() except: # non-MySQL/Postgres pass if value: dbTable = value.split(',').pop(0) elif 'dbTable' in moduleContext: dbTable = moduleContext['dbTable'] else: log.msg('SQL table not specified for OID %s' % (context['origOid'],)) return context['origOid'], tag, context['errorStatus'] origOid = context['origOid'] sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')]) if context['setFlag']: if 'hexvalue' in context: textTag = context['hextag'] textValue = context['hexvalue'] else: textTag = SnmprecGrammar().getTagByType(context['origValue']) textValue = str(context['origValue']) cursor.execute( 'select maxaccess,tag from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid) ) resultset = cursor.fetchone() if resultset: maxaccess = resultset[0] if maxaccess != 'read-write': return origOid, tag, context['errorStatus'] cursor.execute( 'update %s set tag=\'%s\',value=\'%s\' where oid=\'%s\'' % (dbTable, textTag, textValue, sqlOid) ) else: cursor.execute( 'insert into %s values (\'%s\', \'%s\', \'%s\', \'read-write\')' % (dbTable, sqlOid, textTag, textValue) ) if context['varsRemaining'] == 0: # last OID in PDU dbConn.commit() cursor.close() return origOid, textTag, context['origValue'] else: if context['nextFlag']: cursor.execute('select oid from %s where oid>\'%s\' order by oid limit 1' % (dbTable, sqlOid)) resultset = cursor.fetchone() if resultset: origOid = origOid.clone( '.'.join([x.strip() for x in str(resultset[0]).split('.')]) ) sqlOid = '.'.join(['%10s' % x for x in str(origOid).split('.')]) else: cursor.close() return origOid, tag, context['errorStatus'] cursor.execute('select tag, value from %s where oid=\'%s\' limit 1' % (dbTable, sqlOid)) resultset = cursor.fetchone() cursor.close() if resultset: return origOid, str(resultset[0]), str(resultset[1]) else: return origOid, tag, context['errorStatus']
def variate(oid, tag, value, **context): if 'dbConn' in moduleContext: dbConn = moduleContext['dbConn'] else: raise error.SnmpsimError('variation module not initialized') if 'settings' not in recordContext: settings = recordContext['settings'] = dict( [split(x, '=') for x in split(value, ',')]) if 'key-spaces-id' not in settings: log.msg('redis:mandatory key-spaces-id option is missing') return context['origOid'], tag, context['errorStatus'] settings['period'] = float(settings.get('period', 60)) if 'evalsha' in settings: if not dbConn.script_exists(settings['evalsha']): log.msg('redis: lua script %s does not exist ' 'at Redis' % settings['evalsha']) return context['origOid'], tag, context['errorStatus'] recordContext['ready'] = True if 'ready' not in recordContext: return context['origOid'], tag, context['errorStatus'] redisScript = recordContext['settings'].get('evalsha') keySpacesId = recordContext['settings']['key-spaces-id'] if recordContext['settings']['period']: booted = time.time() - moduleContext['booted'] slot = int(dbConn.llen(keySpacesId)) // recordContext['settings']['period'] keySpaceIdx = int(booted) % (recordContext['settings']['period'] * slot) else: keySpaceIdx = 0 keySpace = dbConn.lindex(keySpacesId, keySpaceIdx) if ('current-keyspace' not in recordContext or recordContext['current-keyspace'] != keySpace): log.msg('redis: now using keyspace %s (cycling period' ' %s)' % ( keySpace, recordCoentext['settings']['period'] or '<disabled>')) recordContext['current-keyspace'] = keySpace if keySpace is None: return origOid, tag, context['errorStatus'] origOid = context['origOid'] dbOid = '.'.join(['%10s' % x for x in str(origOid).split('.')]) if context['setFlag']: if 'hexvalue' in context: textTag = context['hextag'] textValue = context['hexvalue'] else: textTag = SnmprecGrammar().getTagByType(context['origValue']) textValue = str(context['origValue']) if redisScript: prevTagAndValue = dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid) else: prevTagAndValue = dbConn.get(keySpace + '-' + dbOid) if prevTagAndValue: prevTag, prevValue = prevTagAndValue.split('|') if unpackTag(prevTag)[0] != unpackTag(textTag)[0]: idx = max(0, context['varsTotal'] - context['varsRemaining'] - 1) raise WrongValueError(name=origOid, idx=idx) else: dbConn.linsert( keySpace + '-oids_ordering', 'after', getNextOid(dbConn, keySpace, dbOid), dbOid) if redisScript: dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid, textTag + '|' + textValue) else: dbConn.set(keySpace + '-' + dbOid, textTag + '|' + textValue) return origOid, textTag, context['origValue'] else: if context['nextFlag']: textOid = dbConn.lindex( keySpace + '-oids_ordering', getNextOid(dbConn, keySpace, dbOid, index=True)) else: textOid = keySpace + '-' + dbOid if redisScript: tagAndValue = dbConn.evalsha(redisScript, 1, textOid) else: tagAndValue = dbConn.get(textOid) if not tagAndValue: return origOid, tag, context['errorStatus'] textOid = '.'.join( [x.strip() for x in textOid.split('-', 1)[1].split('.')]) textTag, textValue = tagAndValue.split('|', 1) return textOid, textTag, textValue
def record(oid, tag, value, **context): if 'ready' not in moduleContext: raise error.SnmpsimError('module not initialized') if 'dbConn' in moduleContext: dbConn = moduleContext['dbConn'] else: raise error.SnmpsimError('variation module not initialized') if 'started' not in moduleContext: moduleContext['started'] = time.time() redisScript = moduleContext.get('evalsha') keySpace = '%.10d' % (moduleContext['key-spaces-id'] + moduleContext.get('iterations', 0)) if context['stopFlag']: dbConn.sort(keySpace + '-' + 'temp_oids_ordering', store=keySpace + '-' + 'oids_ordering', alpha=True) dbConn.delete(keySpace + '-' + 'temp_oids_ordering') dbConn.rpush(moduleContext['key-spaces-id'], keySpace) log.msg('redis: done with key-space %s' % keySpace) if 'iterations' in moduleContext and moduleContext['iterations']: log.msg('redis: %s iterations remaining' % moduleContext['iterations']) moduleContext['started'] = time.time() moduleContext['iterations'] -= 1 runtime = time.time() - moduleContext['started'] wait = max(0, moduleContext['period'] - runtime) raise error.MoreDataNotification(period=wait) else: raise error.NoDataNotification() dbOid = '.'.join(['%10s' % x for x in oid.split('.')]) if 'hexvalue' in context: textTag = context['hextag'] textValue = context['hexvalue'] else: textTag = SnmprecGrammar().getTagByType(context['origValue']) textValue = str(context['origValue']) dbConn.lpush(keySpace + '-temp_oids_ordering', keySpace + '-' + dbOid) if redisScript: dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid, textTag + '|' + textValue) else: dbConn.set(keySpace + '-' + dbOid, textTag + '|' + textValue) if not context['count']: settings = {'key-spaces-id': moduleContext['key-spaces-id']} if 'period' in moduleContext: settings['period'] = '%.2f' % float(moduleContext['period']) if 'addon' in moduleContext: settings.update( dict([split(x, '=') for x in moduleContext['addon']])) value = ','.join(['%s=%s' % (k, v) for k, v in settings.items()]) return str(context['startOID']), ':redis', value else: raise error.NoDataNotification()
def variate(oid, tag, value, **context): if not context['nextFlag'] and not context['exactMatch']: return context['origOid'], tag, context['errorStatus'] if 'settings' not in recordContext: recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')]) if 'vlist' in recordContext['settings']: vlist = {} recordContext['settings']['vlist'] = split( recordContext['settings']['vlist'], ':') while recordContext['settings']['vlist']: o, v, e = recordContext['settings']['vlist'][:3] vl = recordContext['settings']['vlist'][3:] recordContext['settings']['vlist'] = vl typeTag, _ = SnmprecRecord.unpackTag(tag) v = SnmprecGrammar.TAG_MAP[typeTag](v) if o not in vlist: vlist[o] = {} if o == 'eq': vlist[o][v] = e elif o in ('lt', 'gt'): vlist[o] = v, e else: log.msg('writecache: bad vlist syntax: ' '%s' % recordContext['settings']['vlist']) recordContext['settings']['vlist'] = vlist if 'status' in recordContext['settings']: st = recordContext['settings']['status'].lower() recordContext['settings']['status'] = st if oid not in moduleContext: moduleContext[oid] = {} typeTag, _ = SnmprecRecord.unpackTag(tag) moduleContext[oid]['type'] = SnmprecGrammar.TAG_MAP[typeTag]() textOid = str(oid) if context['setFlag']: if 'vlist' in recordContext['settings']: if ('eq' in recordContext['settings']['vlist'] and context['origValue'] in recordContext['settings']['vlist']['eq']): e = recordContext['settings']['vlist']['eq'][context['origValue']] elif ('lt' in recordContext['settings']['vlist'] and context['origValue'] < recordContext['settings']['vlist']['lt'][0]): e = recordContext['settings']['vlist']['lt'][1] elif ('gt' in recordContext['settings']['vlist'] and context['origValue'] > recordContext['settings']['vlist']['gt'][0]): e = recordContext['settings']['vlist']['gt'][1] else: e = None if e in ERROR_TYPES: idx = max(0, context['varsTotal'] - context['varsRemaining'] - 1) raise ERROR_TYPES[e](name=oid, idx=idx) if moduleContext[oid]['type'].isSameTypeWith(context['origValue']): moduleContext['cache'][textOid] = context['origValue'] else: return context['origOid'], tag, context['errorStatus'] if 'status' in recordContext['settings']: if ('op' not in recordContext['settings'] or recordContext['settings']['op'] == 'any' or recordContext['settings']['op'] == 'set' and context['setFlag'] or recordContext['settings']['op'] == 'get' and not context['setFlag']): e = recordContext['settings']['status'] if e in ERROR_TYPES: idx = max(0, context['varsTotal'] - context['varsRemaining'] - 1) raise ERROR_TYPES[e](name=oid, idx=idx) if textOid in moduleContext['cache']: return oid, tag, moduleContext['cache'][textOid] elif 'hexvalue' in recordContext['settings']: return oid, tag, moduleContext[oid]['type'].clone( hexValue=recordContext['settings']['hexvalue']) elif 'value' in recordContext['settings']: return oid, tag, moduleContext[oid]['type'].clone( recordContext['settings']['value']) else: return oid, tag, context['errorStatus']
def variate(oid, tag, value, **context): if 'dbConn' in moduleContext: dbConn = moduleContext['dbConn'] else: raise error.SnmpsimError('variation module not initialized') if 'settings' not in recordContext: settings = recordContext['settings'] = dict( [split(x, '=') for x in split(value, ',')]) if 'key-spaces-id' not in settings: log.msg('redis:mandatory key-spaces-id option is missing') return context['origOid'], tag, context['errorStatus'] settings['period'] = float(settings.get('period', 60)) if 'evalsha' in settings: if not dbConn.script_exists(settings['evalsha']): log.msg('redis: lua script %s does not exist ' 'at Redis' % settings['evalsha']) return context['origOid'], tag, context['errorStatus'] recordContext['ready'] = True if 'ready' not in recordContext: return context['origOid'], tag, context['errorStatus'] redisScript = recordContext['settings'].get('evalsha') keySpacesId = recordContext['settings']['key-spaces-id'] if recordContext['settings']['period']: booted = time.time() - moduleContext['booted'] slot = int( dbConn.llen(keySpacesId)) // recordContext['settings']['period'] keySpaceIdx = int(booted) % (recordContext['settings']['period'] * slot) else: keySpaceIdx = 0 keySpace = dbConn.lindex(keySpacesId, keySpaceIdx) if ('current-keyspace' not in recordContext or recordContext['current-keyspace'] != keySpace): log.msg( 'redis: now using keyspace %s (cycling period' ' %s)' % (keySpace, recordCoentext['settings']['period'] or '<disabled>')) recordContext['current-keyspace'] = keySpace if keySpace is None: return origOid, tag, context['errorStatus'] origOid = context['origOid'] dbOid = '.'.join(['%10s' % x for x in str(origOid).split('.')]) if context['setFlag']: if 'hexvalue' in context: textTag = context['hextag'] textValue = context['hexvalue'] else: textTag = SnmprecGrammar().getTagByType(context['origValue']) textValue = str(context['origValue']) if redisScript: prevTagAndValue = dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid) else: prevTagAndValue = dbConn.get(keySpace + '-' + dbOid) if prevTagAndValue: prevTag, prevValue = prevTagAndValue.split('|') if unpackTag(prevTag)[0] != unpackTag(textTag)[0]: idx = max(0, context['varsTotal'] - context['varsRemaining'] - 1) raise WrongValueError(name=origOid, idx=idx) else: dbConn.linsert(keySpace + '-oids_ordering', 'after', getNextOid(dbConn, keySpace, dbOid), dbOid) if redisScript: dbConn.evalsha(redisScript, 1, keySpace + '-' + dbOid, textTag + '|' + textValue) else: dbConn.set(keySpace + '-' + dbOid, textTag + '|' + textValue) return origOid, textTag, context['origValue'] else: if context['nextFlag']: textOid = dbConn.lindex( keySpace + '-oids_ordering', getNextOid(dbConn, keySpace, dbOid, index=True)) else: textOid = keySpace + '-' + dbOid if redisScript: tagAndValue = dbConn.evalsha(redisScript, 1, textOid) else: tagAndValue = dbConn.get(textOid) if not tagAndValue: return origOid, tag, context['errorStatus'] textOid = '.'.join( [x.strip() for x in textOid.split('-', 1)[1].split('.')]) textTag, textValue = tagAndValue.split('|', 1) return textOid, textTag, textValue
if privProtocols[v3PrivProto] == config.usmNoPrivProtocol: if v3PrivKey is not None: v3PrivProto = 'DES' else: if v3PrivKey is None: sys.stderr.write('ERROR: --v3-priv-key is missing\r\n%s\r\n' % helpMessage) sys.exit(-1) else: v3ContextEngineId = None v3ContextName = '' log.setLogger('snmprec', 'stderr') if getBulkFlag and not snmpVersion: log.msg('WARNING: will be using GETNEXT with SNMPv1!') getBulkFlag = False # Attempt to reopen std output stream in binary mode if outputFile is sys.stderr: if sys.version_info[0] > 2: outputFile = outputFile.buffer elif sys.platform == "win32": import msvcrt msvcrt.setmode(outputFile.fileno(), os.O_BINARY) # Load variation module if variationModuleName: for variationModulesDir in confdir.variation:
def variate(oid, tag, value, **context): if 'settings' not in recordContext: recordContext['settings'] = dict( [split(x, '=') for x in split(value, ',')]) if 'dir' not in recordContext['settings']: log.msg('multiplex: snapshot directory not specified') return context['origOid'], tag, context['errorStatus'] recordContext['settings']['dir'] = recordContext['settings'][ 'dir'].replace('/', os.path.sep) if recordContext['settings']['dir'][0] != os.path.sep: for x in confdir.data: d = os.path.join(x, recordContext['settings']['dir']) if os.path.exists(d): break else: log.msg('multiplex: directory %s not found' % recordContext['settings']['dir']) return context['origOid'], tag, context['errorStatus'] else: d = recordContext['settings']['dir'] recordContext['dirmap'] = dict([ (int(os.path.basename(x).split(os.path.extsep)[0]), os.path.join(d, x)) for x in os.listdir(d) if x[-7:] == 'snmprec' ]) recordContext['keys'] = list(recordContext['dirmap'].keys()) recordContext['bounds'] = (min(recordContext['keys']), max(recordContext['keys'])) if 'period' in recordContext['settings']: recordContext['settings']['period'] = float( recordContext['settings']['period']) else: recordContext['settings']['period'] = 60.0 if 'wrap' in recordContext['settings']: recordContext['settings']['wrap'] = bool( recordContext['settings']['wrap']) else: recordContext['settings']['wrap'] = False if 'control' in recordContext['settings']: recordContext['settings']['control'] = rfc1902.ObjectName( recordContext['settings']['control']) log.msg( 'multiplex: using control OID %s for subtree %s, time-based multiplexing disabled' % (recordContext['settings']['control'], oid)) recordContext['ready'] = True if 'ready' not in recordContext: return context['origOid'], tag, context['errorStatus'] if oid not in moduleContext: moduleContext[oid] = {} if context['setFlag']: if 'control' in recordContext['settings'] and \ recordContext['settings']['control'] == context['origOid']: fileno = int(context['origValue']) if fileno >= len(recordContext['keys']): log.msg('multiplex: .snmprec file number %s over limit of %s' % (fileno, len(recordContext['keys']))) return context['origOid'], tag, context['errorStatus'] moduleContext[oid]['fileno'] = fileno log.msg('multiplex: switched to file #%s (%s)' % (recordContext['keys'][fileno], recordContext['dirmap'][recordContext['keys'][fileno]])) return context['origOid'], tag, context['origValue'] else: return context['origOid'], tag, context['errorStatus'] if 'control' in recordContext['settings']: if 'fileno' not in moduleContext[oid]: moduleContext[oid]['fileno'] = 0 if (not context['nextFlag'] and recordContext['settings']['control'] == context['origOid']): return context['origOid'], tag, rfc1902.Integer32( moduleContext[oid]['fileno']) else: timeslot = (time.time() - moduleContext['booted']) % ( recordContext['settings']['period'] * len(recordContext['dirmap'])) fileslot = int( timeslot / recordContext['settings']['period']) + recordContext['bounds'][0] fileno = bisect.bisect(recordContext['keys'], fileslot) - 1 if ('fileno' not in moduleContext[oid] or moduleContext[oid]['fileno'] < fileno or recordContext['settings']['wrap']): moduleContext[oid]['fileno'] = fileno datafile = recordContext['dirmap'][recordContext['keys'][moduleContext[oid] ['fileno']]] if ('datafile' not in moduleContext[oid] or moduleContext[oid]['datafile'] != datafile): if 'datafileobj' in moduleContext[oid]: moduleContext[oid]['datafileobj'].close() moduleContext[oid]['datafileobj'] = RecordIndex( datafile, SnmprecRecord()).create() moduleContext[oid]['datafile'] = datafile log.msg('multiplex: switching to data file %s for %s' % (datafile, context['origOid'])) text, db = moduleContext[oid]['datafileobj'].getHandles() textOid = str( rfc1902.OctetString('.'.join(['%s' % x for x in context['origOid']]))) try: line = moduleContext[oid]['datafileobj'].lookup(textOid) except KeyError: offset = searchRecordByOid(context['origOid'], text, SnmprecRecord()) exactMatch = False else: offset, subtreeFlag, prevOffset = line.split(str2octs(',')) exactMatch = True text.seek(int(offset)) line, _, _ = getRecord(text) # matched line if context['nextFlag']: if exactMatch: line, _, _ = getRecord(text) else: if not exactMatch: return context['origOid'], tag, context['errorStatus'] if not line: return context['origOid'], tag, context['errorStatus'] try: oid, value = SnmprecRecord().evaluate(line) except error.SnmpsimError: oid, value = context['origOid'], context['errorStatus'] return oid, tag, value
def cbFun(snmpEngine, sendRequestHandle, errorIndication, errorStatus, errorIndex, varBindTable, cbCtx): if errorIndication and not cbCtx['retries']: cbCtx['errors'] += 1 log.msg('SNMP Engine error: %s' % errorIndication) return # SNMPv1 response may contain noSuchName error *and* SNMPv2c exception, # so we ignore noSuchName error here if errorStatus and errorStatus != 2 or errorIndication: log.msg('Remote SNMP error %s' % (errorIndication or errorStatus.prettyPrint())) if cbCtx['retries']: try: nextOID = varBindTable[-1][0][0] except IndexError: nextOID = cbCtx['lastOID'] else: log.msg('Failed OID: %s' % nextOID) # fuzzy logic of walking a broken OID if len(nextOID) < 4: pass elif (continueOnErrors - cbCtx['retries']) * 10 / continueOnErrors > 5: nextOID = nextOID[:-2] + (nextOID[-2] + 1, ) elif nextOID[-1]: nextOID = nextOID[:-1] + (nextOID[-1] + 1, ) else: nextOID = nextOID[:-2] + (nextOID[-2] + 1, 0) cbCtx['retries'] -= 1 cbCtx['lastOID'] = nextOID log.msg('Retrying with OID %s (%s retries left)...' % (nextOID, cbCtx['retries'])) # initiate another SNMP walk iteration if getBulkFlag: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, 0, getBulkRepetitions, [(nextOID, None)], cbFun, cbCtx) else: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, [(nextOID, None)], cbFun, cbCtx) cbCtx['errors'] += 1 return if continueOnErrors != cbCtx['retries']: cbCtx['retries'] += 1 if varBindTable and varBindTable[-1] and varBindTable[-1][0]: cbCtx['lastOID'] = varBindTable[-1][0][0] stopFlag = False # Walk var-binds for varBindRow in varBindTable: for oid, val in varBindRow: # EOM if stopOID and oid >= stopOID: stopFlag = True # stop on out of range condition elif val is None or \ val.tagSet in (rfc1905.NoSuchObject.tagSet, rfc1905.NoSuchInstance.tagSet, rfc1905.EndOfMibView.tagSet): stopFlag = True # Build .snmprec record context = { 'origOid': oid, 'origValue': val, 'count': cbCtx['count'], 'total': cbCtx['total'], 'iteration': cbCtx['iteration'], 'reqTime': cbCtx['reqTime'], 'startOID': startOID, 'stopOID': stopOID, 'stopFlag': stopFlag, 'variationModule': variationModule } try: line = dataFileHandler.format(oid, val, **context) except error.MoreDataNotification: cbCtx['count'] = 0 cbCtx['iteration'] += 1 moreDataNotification = sys.exc_info()[1] if 'period' in moreDataNotification: log.msg('%s OIDs dumped, waiting %.2f sec(s)...' % (cbCtx['total'], moreDataNotification['period'])) time.sleep(moreDataNotification['period']) # initiate another SNMP walk iteration if getBulkFlag: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, 0, getBulkRepetitions, [(startOID, None)], cbFun, cbCtx) else: cmdGen.sendVarBinds(snmpEngine, 'tgt', v3ContextEngineId, v3Context, [(startOID, None)], cbFun, cbCtx) stopFlag = True # stop current iteration except error.NoDataNotification: pass except error.SnmpsimError: log.msg('ERROR: %s' % (sys.exc_info()[1], )) continue else: outputFile.write(line) cbCtx['count'] += 1 cbCtx['total'] += 1 if cbCtx['count'] % 100 == 0: log.msg('OIDs dumped: %s/%s' % (cbCtx['iteration'], cbCtx['count'])) # Next request time cbCtx['reqTime'] = time.time() # Continue walking return not stopFlag
def create(self, forceIndexBuild=False, validateData=False): textFileTime = os.stat(self.__textFile)[8] # gdbm on OS X seems to voluntarily append .db, trying to catch that indexNeeded = forceIndexBuild for dbFile in ( self.__dbFile + os.path.extsep + 'db', self.__dbFile ): if os.path.exists(dbFile): if textFileTime < os.stat(dbFile)[8]: if indexNeeded: log.msg('Forced index rebuild %s' % dbFile) elif not whichdb(dbFile): indexNeeded = True log.msg('Unsupported index format, rebuilding index %s' % dbFile) else: indexNeeded = True log.msg('Index %s out of date' % dbFile) break else: indexNeeded = True log.msg('Index %s does not exist for data file %s' % (self.__dbFile, self.__textFile)) if indexNeeded: # these might speed-up indexing open_flags = 'nfu' while open_flags: try: db = dbm.open(self.__dbFile, open_flags) except Exception: open_flags = open_flags[:-1] continue else: break else: raise error.SnmpsimError('Failed to create %s for data file %s: %s' % (self.__dbFile, self.__textFile, sys.exc_info()[1])) try: text = open(self.__textFile, 'rb') except: raise error.SnmpsimError('Failed to open data file %s: %s' % (self.__dbFile, sys.exc_info()[0])) log.msg('Building index %s for data file %s (open flags \"%s\")...' % (self.__dbFile, self.__textFile, open_flags)) sys.stdout.flush() lineNo = 0 offset = 0 prevOffset = -1 while 1: line, lineNo, offset = getRecord(text, lineNo, offset) if not line: # reference to last OID in data file db['last'] = '%d,%d,%d' % (offset, 0, prevOffset) break try: oid, tag, val = self.__textParser.grammar.parse(line) except Exception: db.close() exc = sys.exc_info()[1] try: os.remove(self.__dbFile) except OSError: pass raise error.SnmpsimError('Data error at %s:%d: %s' % (self.__textFile, lineNo, exc)) if validateData: try: self.__textParser.evaluateOid(oid) except Exception: db.close() exc = sys.exc_info()[1] try: os.remove(self.__dbFile) except OSError: pass raise error.SnmpsimError('OID error at %s:%d: %s' % (self.__textFile, lineNo, exc)) try: self.__textParser.evaluateValue( oid, tag, val, dataValidation=True ) except Exception: log.msg( 'ERROR at line %s, value %r: %s' % \ (lineNo, val, sys.exc_info()[1]) ) # for lines serving subtrees, type is empty in tag field db[oid] = '%d,%d,%d' % (offset, tag[0] == ':', prevOffset) if tag[0] == ':': prevOffset = offset else: prevOffset = -1 # not a subtree - no backreference offset += len(line) text.close() db.close() log.msg('...%d entries indexed' % lineNo) self.__textFileTime = os.stat(self.__textFile)[8] self.__dbType = whichdb(self.__dbFile) return self
def variate(oid, tag, value, **context): if not context['nextFlag'] and not context['exactMatch']: return context['origOid'], tag, context['errorStatus'] if 'settings' not in recordContext: recordContext['settings'] = dict( [split(x, '=') for x in split(value, ',')]) if 'hexvalue' in recordContext['settings']: recordContext['settings']['value'] = [ int(recordContext['settings']['hexvalue'][x:x + 2], 16) for x in range(0, len(recordContext['settings']['hexvalue']), 2)] if 'wait' in recordContext['settings']: recordContext['settings']['wait'] = float( recordContext['settings']['wait']) else: recordContext['settings']['wait'] = 500.0 if 'deviation' in recordContext['settings']: recordContext['settings']['deviation'] = float( recordContext['settings']['deviation']) else: recordContext['settings']['deviation'] = 0.0 if 'vlist' in recordContext['settings']: vlist = {} recordContext['settings']['vlist'] = split( recordContext['settings']['vlist'], ':') while recordContext['settings']['vlist']: o, v, d = recordContext['settings']['vlist'][:3] recordContext['settings']['vlist'] = recordContext['settings']['vlist'][3:] d = int(d) typeTag, _ = SnmprecRecord.unpackTag(tag) v = SnmprecGrammar.TAG_MAP[typeTag](v) if o not in vlist: vlist[o] = {} if o == 'eq': vlist[o][v] = d elif o in ('lt', 'gt'): vlist[o] = v, d else: log.msg('delay: bad vlist syntax: ' '%s' % recordContext['settings']['vlist']) recordContext['settings']['vlist'] = vlist if 'tlist' in recordContext['settings']: tlist = {} recordContext['settings']['tlist'] = split( recordContext['settings']['tlist'], ':') while recordContext['settings']['tlist']: o, v, d = recordContext['settings']['tlist'][:3] recordContext['settings']['tlist'] = recordContext['settings']['tlist'][3:] v = int(v) d = int(d) if o not in tlist: tlist[o] = {} if o == 'eq': tlist[o][v] = d elif o in ('lt', 'gt'): tlist[o] = v, d else: log.msg('delay: bad tlist syntax: ' '%s' % recordContext['settings']['tlist']) recordContext['settings']['tlist'] = tlist if context['setFlag'] and 'vlist' in recordContext['settings']: if ('eq' in recordContext['settings']['vlist'] and context['origValue'] in recordContext['settings']['vlist']['eq']): delay = recordContext['settings']['vlist']['eq'][context['origValue']] elif ('lt' in recordContext['settings']['vlist'] and context['origValue'] < recordContext['settings']['vlist']['lt'][0]): delay = recordContext['settings']['vlist']['lt'][1] elif ('gt' in recordContext['settings']['vlist'] and context['origValue'] > recordContext['settings']['vlist']['gt'][0]): delay = recordContext['settings']['vlist']['gt'][1] else: delay = recordContext['settings']['wait'] elif 'tlist' in recordContext['settings']: now = int(time.time()) if ('eq' in recordContext['settings']['tlist'] and now == recordContext['settings']['tlist']['eq']): delay = recordContext['settings']['tlist']['eq'][now] elif ('lt' in recordContext['settings']['tlist'] and now < recordContext['settings']['tlist']['lt'][0]): delay = recordContext['settings']['tlist']['lt'][1] elif ('gt' in recordContext['settings']['tlist'] and now > recordContext['settings']['tlist']['gt'][0]): delay = recordContext['settings']['tlist']['gt'][1] else: delay = recordContext['settings']['wait'] else: delay = recordContext['settings']['wait'] if recordContext['settings']['deviation']: delay += random.randrange( -recordContext['settings']['deviation'], recordContext['settings']['deviation']) if delay < 0: delay = 0 elif delay > 99999: log.msg('delay: dropping response for %s' % oid) raise error.NoDataNotification() log.msg('delay: waiting %d milliseconds for %s' % (delay, oid)) time.sleep(delay / 1000) # ms if context['setFlag'] or 'value' not in recordContext['settings']: return oid, tag, context['origValue'] else: return oid, tag, recordContext['settings']['value']
def create(self, forceIndexBuild=False, validateData=False): textFileTime = os.stat(self.__textFile)[8] # gdbm on OS X seems to voluntarily append .db, trying to catch that indexNeeded = forceIndexBuild for dbFile in ( self.__dbFile + os.path.extsep + 'db', self.__dbFile ): if os.path.exists(dbFile): if textFileTime < os.stat(dbFile)[8]: if indexNeeded: log.msg('Forced index rebuild %s' % dbFile) elif not whichdb(dbFile): indexNeeded = True log.msg('Unsupported index format, rebuilding index %s' % dbFile) else: indexNeeded = True log.msg('Index %s out of date' % dbFile) break else: indexNeeded = True log.msg('Index %s does not exist for data file %s' % (self.__dbFile, self.__textFile)) if indexNeeded: # these might speed-up indexing open_flags = 'nfu' while open_flags: try: db = dbm.open(self.__dbFile, open_flags) except Exception: open_flags = open_flags[:-1] continue else: break else: raise error.SnmpsimError('Failed to create %s for data file %s: %s' % (self.__dbFile, self.__textFile, sys.exc_info()[1])) try: text = open(self.__textFile, 'rb') except: raise error.SnmpsimError('Failed to open data file %s: %s' % (self.__dbFile, sys.exc_info()[0])) log.msg('Building index %s for data file %s (open flags \"%s\")...' % (self.__dbFile, self.__textFile, open_flags)) sys.stdout.flush() lineNo = 0 offset = 0 prevOffset = -1 while True: line, lineNo, offset = getRecord(text, lineNo, offset) if not line: # reference to last OID in data file db['last'] = '%d,%d,%d' % (offset, 0, prevOffset) break try: oid, tag, val = self.__textParser.grammar.parse(line) except Exception: db.close() exc = sys.exc_info()[1] try: os.remove(self.__dbFile) except OSError: pass raise error.SnmpsimError('Data error at %s:%d: %s' % (self.__textFile, lineNo, exc)) if validateData: try: self.__textParser.evaluateOid(oid) except Exception: db.close() exc = sys.exc_info()[1] try: os.remove(self.__dbFile) except OSError: pass raise error.SnmpsimError('OID error at %s:%d: %s' % (self.__textFile, lineNo, exc)) try: self.__textParser.evaluateValue( oid, tag, val, dataValidation=True ) except Exception: log.msg( 'ERROR at line %s, value %r: %s' % \ (lineNo, val, sys.exc_info()[1]) ) # for lines serving subtrees, type is empty in tag field db[oid] = '%d,%d,%d' % (offset, tag[0] == ':', prevOffset) if tag[0] == ':': prevOffset = offset else: prevOffset = -1 # not a subtree - no backreference offset += len(line) text.close() db.close() log.msg('...%d entries indexed' % lineNo) self.__textFileTime = os.stat(self.__textFile)[8] self.__dbType = whichdb(self.__dbFile) return self
def variate(oid, tag, value, **context): if not context['nextFlag'] and not context['exactMatch']: return context['origOid'], tag, context['errorStatus'] if 'settings' not in recordContext: recordContext['settings'] = dict([split(x, '=') for x in split(value, ',')]) if 'vlist' in recordContext['settings']: vlist = {} recordContext['settings']['vlist'] = split(recordContext['settings']['vlist'], ':') while recordContext['settings']['vlist']: o,v,e = recordContext['settings']['vlist'][:3] recordContext['settings']['vlist'] = recordContext['settings']['vlist'][3:] v = SnmprecGrammar.tagMap[tag](v) if o not in vlist: vlist[o] = {} if o == 'eq': vlist[o][v] = e elif o in ('lt', 'gt'): vlist[o] = v, e else: log.msg('writecache: bad vlist syntax: %s' % recordContext['settings']['vlist']) recordContext['settings']['vlist'] = vlist if oid not in moduleContext: moduleContext[oid] = {} moduleContext[oid]['type'] = SnmprecGrammar().tagMap[tag]() textOid = str(oid) if context['setFlag']: if 'vlist' in recordContext['settings']: if 'eq' in recordContext['settings']['vlist'] and \ context['origValue'] in recordContext['settings']['vlist']['eq']: e = recordContext['settings']['vlist']['eq'][context['origValue']] elif 'lt' in recordContext['settings']['vlist'] and \ context['origValue']<recordContext['settings']['vlist']['lt'][0]: e = recordContext['settings']['vlist']['lt'][1] elif 'gt' in recordContext['settings']['vlist'] and \ context['origValue']>recordContext['settings']['vlist']['gt'][0]: e = recordContext['settings']['vlist']['gt'][1] else: e = None if e in errorTypes: raise errorTypes[e]( name=oid, idx=max(0, context['varsTotal']-context['varsRemaining']-1) ) if moduleContext[oid]['type'].isSameTypeWith(context['origValue']): moduleContext['cache'][textOid] = context['origValue'] else: return context['origOid'], tag, context['errorStatus'] if textOid in moduleContext['cache']: return oid, tag, moduleContext['cache'][textOid] elif 'hexvalue' in recordContext['settings']: return oid, tag, moduleContext[oid]['type'].clone(hexValue=recordContext['settings']['hexvalue']) elif 'value' in recordContext['settings']: return oid, tag, moduleContext[oid]['type'].clone(recordContext['settings']['value']) else: return oid, tag, context['errorStatus']