Ejemplo n.º 1
0
def init(**context):
    moduleContext['settings'] = {}

    if context['options']:
        moduleContext['settings'].update(
            dict([split(x, ':') for x in split(context['options'], ',')]))

    if 'shell' not in moduleContext['settings']:
        moduleContext['settings']['shell'] = sys.platform[:3] == 'win'

    else:
        moduleContext['settings']['shell'] = int(
            moduleContext['settings']['shell'])
Ejemplo n.º 2
0
def init(**context):
    moduleContext['settings'] = {}

    if context['options']:
        moduleContext['settings'].update(
            dict([split(x, ':')
                  for x in split(context['options'], ',')]))

    if 'file' in moduleContext['settings']:
        moduleContext['cache'] = shelve.open(moduleContext['settings']['file'])

    else:
        moduleContext['cache'] = {}
Ejemplo n.º 3
0
def init(**context):
    options = {}

    if context['options']:
        options.update(
            dict([utils.split(x, ':')
                  for x in utils.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 not redis:
        raise error.SnmpsimError('redis-py Python package must be installed!')

    moduleContext['dbConn'] = redis.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.info('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.info('redis: using server-side script %s' % redisScript)

    elif context['mode'] == 'variating':
        moduleContext['booted'] = time.time()

    moduleContext['ready'] = True
Ejemplo n.º 4
0
def init(**context):

    if context['options']:
        for x in split(context['options'], ','):
            k, v = split(x, ':')
            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.info('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
Ejemplo n.º 5
0
def init(**context):
    if context['mode'] == 'variating':
        random.seed()

    if context['mode'] == 'recording':
        moduleContext['settings'] = {}

        if context['options']:
            for x in split(context['options'], ','):
                for k, v in split(x, ':'):
                    if k == 'addon':
                        if k in moduleContext['settings']:
                            moduleContext['settings'][k].append(v)

                        else:
                            moduleContext['settings'][k] = [v]

                    else:
                        moduleContext['settings'][k] = v

                if 'iterations' in moduleContext['settings']:
                    moduleContext['settings']['iterations'] = int(
                        moduleContext['settings']['iterations'])

                    if moduleContext['settings']['iterations']:
                        # no reason for more
                        moduleContext['settings']['iterations'] = 1

                if 'period' in moduleContext['settings']:
                    moduleContext['settings']['period'] = float(
                        moduleContext['settings']['period'])

                else:
                    moduleContext['settings']['period'] = 10.0

                if 'taglist' not in moduleContext['settings']:
                    moduleContext['settings']['taglist'] = '2-65-66-67-70'
Ejemplo n.º 6
0
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.info('redis: done with key-space %s' % keySpace)

        if 'iterations' in moduleContext and moduleContext['iterations']:
            log.info('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().get_tag_by_type(context['origValue'])
        textValue = str(context['origValue'])

    dbConn.lpush(keySpace + '-temp_oids_ordering', keySpace + '-' + dbOid)

    if redisScript:
        evalsha(dbConn, 
            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([utils.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()
Ejemplo n.º 7
0
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(
            [utils.split(x, '=') for x in utils.split(value, ',')])

        if 'key-spaces-id' not in settings:
            log.info('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.info('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'] and dbConn.llen(keySpacesId):
        booted = time.time() - moduleContext['booted']
        keySpaceIdx = int(booted) % dbConn.llen(keySpacesId)

    else:
        keySpaceIdx = 0

    keySpace = lindex(dbConn, keySpacesId, keySpaceIdx)

    if ('current-keyspace' not in recordContext or
            recordContext['current-keyspace'] != keySpace):
        log.info('redis: now using keyspace %s (cycling period'
                ' %s)' % (
            keySpace, recordContext['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().get_tag_by_type(context['origValue'])
            textValue = str(context['origValue'])

        if redisScript:
            prevTagAndValue = evalsha(dbConn, redisScript, 1, keySpace + '-' + dbOid)

        else:
            prevTagAndValue = get(dbConn, 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:
            evalsha(dbConn, redisScript, 1, keySpace + '-' + dbOid,
                           textTag + '|' + textValue)

        else:
            dbConn.set(keySpace + '-' + dbOid, textTag + '|' + textValue)

        return origOid, textTag, context['origValue']

    else:
        if context['nextFlag']:
            textOid = lindex(
                dbConn, keySpace + '-oids_ordering',
                getNextOid(dbConn, keySpace, dbOid, index=True))

        else:
            textOid = keySpace + '-' + dbOid

        if redisScript:
            tagAndValue = evalsha(dbConn, redisScript, 1, textOid)

        else:
            tagAndValue = get(dbConn, 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
Ejemplo n.º 8
0
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.unpack_tag(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.info('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 ERROR_TYPES:
        log.info('error: reporting %s for %s' % (e, oid))
        raise ERROR_TYPES[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'])
Ejemplo n.º 9
0
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)

                type_tag, _ = SnmprecRecord.unpack_tag(tag)

                v = SnmprecGrammar.TAG_MAP[type_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.info('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.info('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.info('delay: dropping response for %s' % oid)
        raise error.NoDataNotification()

    log.info('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']
Ejemplo n.º 10
0
def variate(oid, tag, value, **context):
    if not context['nextFlag'] and not context['exactMatch']:
        return context['origOid'], tag, context['errorStatus']

    if context['setFlag']:
        return context['origOid'], tag, context['errorStatus']

    if 'settings' not in recordContext:
        recordContext['settings'] = dict(
            [split(x, '=') for x in split(value, ',')])

        for k in recordContext['settings']:
            if k != 'function':
                recordContext['settings'][k] = float(
                    recordContext['settings'][k])

        if 'min' not in recordContext['settings']:
            recordContext['settings']['min'] = 0

        if 'max' not in recordContext['settings']:
            if tag == '70':
                recordContext['settings']['max'] = 0xffffffffffffffff

            else:
                recordContext['settings']['max'] = 0xffffffff

        if 'rate' not in recordContext['settings']:
            recordContext['settings']['rate'] = 1

        if 'function' in recordContext['settings']:
            f = split(recordContext['settings']['function'], '%')
            recordContext['settings']['function'] = getattr(math, f[0]), f[1:]

        else:
            recordContext['settings']['function'] = lambda x: x, ()

    vold, told = recordContext['settings'].get(
        'initial', recordContext['settings']['min']), BOOTED

    if 'cumulative' in recordContext['settings']:
        if 'value' not in recordContext:
            recordContext['value'] = vold, told

        vold, told = recordContext['value']

    tnow = time.time()

    if 'atime' in recordContext['settings']:
        t = tnow

    else:
        t = tnow - BOOTED

    f, args = recordContext['settings']['function']

    _args = []

    if args:
        for x in args:
            if x == '<time>':
                _args.append(t * recordContext['settings']['rate'])

            else:
                _args.append(float(x))

    else:
        _args.append(t * recordContext['settings']['rate'])

    v = f(*_args)

    if 'scale' in recordContext['settings']:
        v *= recordContext['settings']['scale']

    if 'offset' in recordContext['settings']:
        if 'cumulative' in recordContext['settings']:
            rate = recordContext['settings']['rate']
            v += recordContext['settings']['offset'] * (tnow - told) * rate

        else:
            v += recordContext['settings']['offset']

    deviation = recordContext['settings'].get('deviation')
    if deviation:
        v += random.randrange(-deviation, deviation)

    if 'cumulative' in recordContext['settings']:
        v = max(v, 0)

    v += vold

    if v < recordContext['settings']['min']:
        v = recordContext['settings']['min']

    elif v > recordContext['settings']['max']:
        if 'wrap' in recordContext['settings']:
            v %= recordContext['settings']['max']
            v += recordContext['settings']['min']

        else:
            v = recordContext['settings']['max']

    if 'cumulative' in recordContext['settings']:
        recordContext['value'] = v, tnow

    return oid, tag, v
Ejemplo n.º 11
0
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.info('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.info('multiplex: directory %s not '
                         'found' % recordContext['settings']['dir'])
                return context['origOid'], tag, context['errorStatus']

        else:
            d = recordContext['settings']['dir']

        recordContext['dirmap'] = {}
        recordContext['parsermap'] = {}

        for fl in os.listdir(d):
            for ext in RECORD_SET:
                if not fl.endswith(ext):
                    continue
                ident = int(os.path.basename(fl)[:-len(ext) - 1])
                datafile = os.path.join(d, fl)
                recordContext['dirmap'][ident] = datafile
                recordContext['parsermap'][datafile] = RECORD_SET[ext]

        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.info('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.info('multiplex: .snmprec file number %s over limit of'
                         ' %s' % (fileno, len(recordContext['keys'])))

                return context['origOid'], tag, context['errorStatus']

            moduleContext[oid]['fileno'] = fileno

            log.info('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']]]

    parser = recordContext['parsermap'][datafile]

    if ('datafile' not in moduleContext[oid]
            or moduleContext[oid]['datafile'] != datafile):

        if 'datafileobj' in moduleContext[oid]:
            moduleContext[oid]['datafileobj'].close()

        recordIndex = RecordIndex(datafile, parser).create()

        moduleContext[oid]['datafileobj'] = recordIndex

        moduleContext[oid]['datafile'] = datafile

        log.info('multiplex: switching to data file %s for '
                 '%s' % (datafile, context['origOid']))

    text, db = moduleContext[oid]['datafileobj'].get_handles()

    textOid = str(
        rfc1902.OctetString('.'.join(['%s' % x for x in context['origOid']])))

    try:
        line = moduleContext[oid]['datafileobj'].lookup(textOid)

    except KeyError:
        offset = search_record_by_oid(context['origOid'], text, parser)
        exactMatch = False

    else:
        offset, subtreeFlag, prevOffset = line.split(str2octs(','))
        exactMatch = True

    text.seek(int(offset))

    line, _, _ = get_record(text)  # matched line

    if context['nextFlag']:
        if exactMatch:
            line, _, _ = get_record(text)

    else:
        if not exactMatch:
            return context['origOid'], tag, context['errorStatus']

    if not line:
        return context['origOid'], tag, context['errorStatus']

    try:
        oid, value = parser.evaluate(line)

    except error.SnmpsimError:
        oid, value = context['origOid'], context['errorStatus']

    return oid, tag, value
Ejemplo n.º 12
0
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.info('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

        dstRecordType = moduleContext.get('recordtype', 'snmprec')

        ext = os.path.extsep + RECORD_SET[dstRecordType].ext

        snmprecFile = '%.5d%s%s' % (moduleContext['filenum'], os.path.extsep,
                                    ext)

        snmprecfile = os.path.join(moduleContext['dir'], snmprecFile)

        moduleContext['parser'] = RECORD_SET[dstRecordType]
        moduleContext['file'] = moduleContext['parser'].open(snmprecfile, 'wb')

        log.info('multiplex: writing into %s file...' % snmprecfile)

    record = moduleContext['parser'].format(context['origOid'],
                                            context['origValue'])

    moduleContext['file'].write(record)

    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()
Ejemplo n.º 13
0
def variate(oid, tag, value, **context):
    # in --v2c-arch some of the items are not defined
    transport_domain = transport_address = security_model = '<undefined>'
    security_name = security_level = context_name = transport_domain

    if 'transportDomain' in context:
        transport_domain = rfc1902.ObjectName(
            context['transportDomain']).prettyPrint()

    if 'transportAddress' in context:
        transport_address = ':'.join(
            [str(x) for x in context['transportAddress']])

    if 'securityModel' in context:
        security_model = str(context['securityModel'])

    if 'securityName' in context:
        security_name = str(context['securityName'])

    if 'securityLevel' in context:
        security_level = str(context['securityLevel'])

    if 'contextName' in context:
        context_name = str(context['contextName'])

    args = [(x.replace('@TRANSPORTDOMAIN@', transport_domain).replace(
        '@TRANSPORTADDRESS@', transport_address).replace(
            '@SECURITYMODEL@',
            security_model).replace('@SECURITYNAME@', security_name).replace(
                '@SECURITYLEVEL@',
                security_level).replace('@CONTEXTNAME@', context_name).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.info('subprocess: executing external process "%s"' % ' '.join(args))

    try:
        handler = subprocess.check_output

    except AttributeError:
        log.info('subprocess: old Python, expect no output!')

        try:
            handler = subprocess.check_call

        except AttributeError:
            handler = subprocess.call

    try:
        return oid, tag, handler(args,
                                 shell=moduleContext['settings']['shell'])

    except getattr(subprocess, 'CalledProcessError', Exception):
        log.info('subprocess: external program execution failed')
        return context['origOid'], tag, context['errorStatus']
Ejemplo n.º 14
0
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

                type_tag, _ = SnmprecRecord.unpack_tag(tag)

                v = SnmprecGrammar.TAG_MAP[type_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.info('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] = {}

        type_tag, _ = SnmprecRecord.unpack_tag(tag)

        moduleContext[oid]['type'] = SnmprecGrammar.TAG_MAP[type_tag]()

    text_oid = 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'][text_oid] = 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 text_oid in moduleContext['cache']:
        return oid, tag, moduleContext['cache'][text_oid]

    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']
Ejemplo n.º 15
0
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.info('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()
Ejemplo n.º 16
0
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 is not given snmpEngine. '
            'Make sure you are not running in --v2c-arch mode')

    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 MODULE_OPTIONS:
            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]

                vlist = recordContext['settings']['vlist'][2:]
                recordContext['settings']['vlist'] = vlist

                typeTag, _ = SnmprecRecord.unpack_tag(tag)

                v = SnmprecGrammar.TAG_MAP[typeTag](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.info('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.info('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.info('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.info('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.info('notification: unknown SNMP version %s' % args['version'])
            return context['origOid'], tag, context['errorStatus']

        if 'host' not in args:
            log.info('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.info('notification: unknown transport %s' % args['proto'])
            return context['origOid'], tag, context['errorStatus']

        localAddress = None

        if 'bindaddr' in args:
            localAddress = args['bindaddr']

        else:
            transportDomain = context['transportDomain'][:len(target.
                                                              transportDomain)]
            if transportDomain == target.transportDomain:
                localAddress = snmpEngine.transportDispatcher.getTransport(
                    context['transportDomain']).getLocalAddress()[0]

            else:
                log.info(
                    'notification: incompatible network transport types used by '
                    'CommandResponder vs NotificationOriginator')

                if 'bindaddr' in args:
                    localAddress = args['bindaddr']

        if localAddress:
            log.info('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]), TYPE_MAP[vbs[1]](vbs[2])))
                vbs = vbs[3:]

        notificationType = NotificationType(ObjectIdentity(
            args['trapoid'])).addVarBinds(*varBinds)

        sendNotification(snmpEngine,
                         authData,
                         target,
                         ContextData(),
                         args['ntftype'],
                         notificationType,
                         cbFun=_cbFun,
                         cbCtx=(oid, value))

        log.info('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']
Ejemplo n.º 17
0
def init(**context):
    options = {}

    if context['options']:
        options.update(
            dict([split(x, ':') for x in split(context['options'], ',')]))

    if 'dbtype' not in options:
        raise error.SnmpsimError('database type not specified')

    db = __import__(options['dbtype'], globals(), locals(),
                    options['dbtype'].split('.')[:-1])

    if 'dboptions' in options:  # legacy
        connectParams = {'database': options['dboptions']}

    else:
        connectOpts = ('host', 'port', 'user', 'passwd', 'password', 'db',
                       'database', 'unix_socket', 'named_pipe')

        connectParams = dict([(k, options[k]) for k in options
                              if k in connectOpts])

        for k in 'port', 'connect_timeout':
            if k in connectParams:
                connectParams[k] = int(connectParams[k])

    if not connectParams:
        raise error.SnmpsimError('database connect parameters not specified')

    moduleContext['dbConn'] = dbConn = db.connect(**connectParams)
    moduleContext['dbTable'] = dbTable = options.get('dbtable', 'snmprec')
    moduleContext['isolationLevel'] = options.get('isolationlevel', '1')

    if moduleContext['isolationLevel'] not in ISOLATION_LEVELS:
        raise error.SnmpsimError('unknown SQL transaction isolation level '
                                 '%s' % moduleContext['isolationLevel'])

    if 'mode' in context and context['mode'] == 'recording':
        cursor = dbConn.cursor()

        try:
            cursor.execute('select * from information_schema.tables '
                           'where table_name=\'%s\' limit 1' % dbTable)

        except Exception:  # non-ANSI database

            try:
                cursor.execute('select * from %s limit 1' % dbTable)

            except Exception:
                createTable = True

            else:
                createTable = False

        else:
            createTable = not cursor.fetchone()

        if createTable:
            cursor.execute('CREATE TABLE %s (oid text, tag text, value text, '
                           'maxaccess text)' % dbTable)

        cursor.close()