Exemplo n.º 1
0
    def find(self, query, request):
        # XXX --- revisit this code
        query = remove_metachars(query)
        parts = query.split('.')
        if is_pattern(parts[-1]):
            path = '/'.join([p.replace('@', '.') for p in parts[:-1]])
            metric_path = '.'.join(parts[:-1])
            pattern = parts[-1]
        else:
            path = '/'.join([p.replace('@', '.') for p in parts])
            metric_path = '.'.join(parts)
            pattern = None


        if request and request.user and request.user.is_authenticated():
            client = self.auth_client
        else:
            client = self.client

        r = client.get(path)

        if type(r) == list:
            # XXX hack -- if we get multiple results use the most recent
            r = r[-1]

        if r.has_key('children'):
            for child in r['children']:
                if path != '':
                    cpath = metric_path + '.'
                else:
                    cpath = ''

                label = None
                if child.has_key('name'):
                    if path.endswith('interface') and \
                            (not child.has_key('descr')
                                    or child['descr'] == ''):
                        if not 'dev-alu' in path:
                            continue
                    name = child['name']
                    if child.has_key('descr'):
                        label = "%s %s" % (name, child['descr'])
                        label = label.replace('"','')
                else:
                    name = parts[-1]

                cpath += name.replace('.','@')
                # XXX KLUDGE! need to revist various path translation crap
                if 'error/' in cpath:
                    cpath = cpath.replace('error/', 'error.')
                if 'discard/' in cpath:
                    cpath = cpath.replace('discard/', 'discard.')

                if child['leaf']:
                    yield ESxSNMPLeaf(cpath, cpath, client=client,
                            name=name, label=label)
                else:
                    yield ESxSNMPBranch(cpath, cpath, name=name, label=label)
        else:
            yield ESxSNMPLeaf(path, path, client=client)
Exemplo n.º 2
0
 def setup(self, data):
     oid = self.oids[0]
     self.xlate = {}
     for (var, val) in data:
         if var.startswith(oid):
             self.xlate[var[len(oid) + 1:]] = '/'.join(
                 (oid, remove_metachars(val)))
Exemplo n.º 3
0
            def build_iface(iface):

                if not iface.ifhighspeed or iface.ifhighspeed == 0:
                    speed = iface.ifspeed
                else:
                    speed = iface.ifhighspeed * int(1e6)
                return dict(name=iface.ifdescr,
                    uri="%s/%s/interface/%s" % (SNMP_URI, device.name,
                        remove_metachars(iface.ifdescr)),
                    descr=iface.ifalias,
                    speed=speed, 
                    begin_time=iface.begin_time,
                    end_time=iface.end_time,
                    ifIndex=iface.ifindex,
                    ifDescr=iface.ifdescr,
                    ifAlias=iface.ifalias,
                    ifSpeed=iface.ifspeed,
                    ifHighSpeed=iface.ifhighspeed,
                    ipAddr=iface.ipaddr,
                    device_uri='%s/%s' % (SNMP_URI, device.name),
                    leaf=False)
Exemplo n.º 4
0
            def build_iface(iface):

                if not iface.ifhighspeed or iface.ifhighspeed == 0:
                    speed = iface.ifspeed
                else:
                    speed = iface.ifhighspeed * int(1e6)
                return dict(
                    name=iface.ifdescr,
                    uri="%s/%s/interface/%s" %
                    (SNMP_URI, device.name, remove_metachars(iface.ifdescr)),
                    descr=iface.ifalias,
                    speed=speed,
                    begin_time=iface.begin_time,
                    end_time=iface.end_time,
                    ifIndex=iface.ifindex,
                    ifDescr=iface.ifdescr,
                    ifAlias=iface.ifalias,
                    ifSpeed=iface.ifspeed,
                    ifHighSpeed=iface.ifhighspeed,
                    ipAddr=iface.ipaddr,
                    device_uri='%s/%s' % (SNMP_URI, device.name),
                    leaf=False)
Exemplo n.º 5
0
 def _table_parse(self, data):
     d = {}
     for (var, val) in data:
         d[var.split('.')[-1]] = remove_metachars(val)
     return d
Exemplo n.º 6
0
 def setup(self,data):
     oid = self.oids[0]
     self.xlate={}
     for (var, val) in data:
         if var.startswith(oid):
             self.xlate[var[len(oid)+1:]] = '/'.join((oid,remove_metachars(val)))
Exemplo n.º 7
0
 def _table_parse(self, data):
     d = {}
     for (var, val) in data:
         val = val.split(',')[0] # weird comma separated thing
         d[var.split('.')[-1]] = remove_metachars(val)
     return d
Exemplo n.º 8
0
    def find(self, query, request):
        # XXX --- revisit this code
        query = remove_metachars(query)
        parts = query.split('.')
        if is_pattern(parts[-1]):
            path = '/'.join([p.replace('@', '.') for p in parts[:-1]])
            metric_path = '.'.join(parts[:-1])
            pattern = parts[-1]
        else:
            path = '/'.join([p.replace('@', '.') for p in parts])
            metric_path = '.'.join(parts)
            pattern = None

        if request and request.user and request.user.is_authenticated():
            client = self.auth_client
        else:
            client = self.client

        r = client.get(path)

        if type(r) == list:
            # XXX hack -- if we get multiple results use the most recent
            r = r[-1]

        if r.has_key('children'):
            for child in r['children']:
                if path != '':
                    cpath = metric_path + '.'
                else:
                    cpath = ''

                label = None
                if child.has_key('name'):
                    if path.endswith('interface') and \
                            (not child.has_key('descr')
                                    or child['descr'] == ''):
                        if not 'dev-alu' in path:
                            continue
                    name = child['name']
                    if child.has_key('descr'):
                        label = "%s %s" % (name, child['descr'])
                        label = label.replace('"', '')
                else:
                    name = parts[-1]

                cpath += name.replace('.', '@')
                # XXX KLUDGE! need to revist various path translation crap
                if 'error/' in cpath:
                    cpath = cpath.replace('error/', 'error.')
                if 'discard/' in cpath:
                    cpath = cpath.replace('discard/', 'discard.')

                if child['leaf']:
                    yield ESxSNMPLeaf(cpath,
                                      cpath,
                                      client=client,
                                      name=name,
                                      label=label)
                else:
                    yield ESxSNMPBranch(cpath, cpath, name=name, label=label)
        else:
            yield ESxSNMPLeaf(path, path, client=client)
Exemplo n.º 9
0
 def _table_parse(self, data):
     d = {}
     for (var, val) in data:
         d[var.split('.')[-1]] = remove_metachars(val)
     return d
Exemplo n.º 10
0
 def _table_parse(self, data):
     d = {}
     for (var, val) in data:
         val = val.split(',')[0]  # weird comma separated thing
         d[var.split('.')[-1]] = remove_metachars(val)
     return d
Exemplo n.º 11
0
    def get_interface_data(self, devicename, iface, dataset, rest):
        """Returns a JSON object representing counter data for an interface.

        This is obtained by doing a GET of one of the follwing URIs:

            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/in
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/out
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/error/in
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/error/out
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/discard/in
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/discard/out

        For in and out 

        get_interface_data accepts several query parameters:

            begin --  expressed a seconds since the epoch
            end --  expressed a seconds since the epoch
            agg -- use a precomputed aggregate for data, defaults to highest available resolution
            cf -- consolidation function. defaults to average
            calc -- calculate an aggregate, see below for more details
            calc_func --
            oidset -- specifically specify an oidset, see below

        agg specifies which precomputed aggregate to use.  Aggregates are
        represented as rates (eg. bytes/sec) and are calculated for the base
        rate at the time the data is persisted to disk.   This is specified as
        the number of seconds in the aggregation period or as 'raw'.  'raw'
        returns the counter data as collected from the device without any
        processing.  Currently there is only the aggreagate for the base polling
        interval and as a result this is rarely used.  cf determines how
        datapoints are agreggated into a single datapoint.  By default the
        datapoints are averaged but the maximum and minimum can also be used.
        valid options for this parameter are 'min', 'max' and 'average'.  This
        applies to precomputed aggregates that are greater than the base polling
        frequency.

        calc requests that the database dynamically generate an aggregate from
        the base aggregate for this counter.  The parameter is set to the
        numberof seconds to be used in the aggregation period.  The function
        used to consolidate each group of data points into a single data in the
        aggregate is controlled by the calc_func parameter.

        calc_func specifies the function to use when calculating an aggregate.
        It may be one of 'average', 'min',  or 'max' and defaults to 'average'.

        oidset allows the query to specify a specific oidset to get the data
        from rather than using the usual method for locating the oidset.  This
        is very rarely used.

        An interface data JSON object has the following fields:

            :param data: a list of tuples.  each tuple is [timestamp, value]
            :param begin_time: the requested begin_time
            :param end_time: the requested end_time
            :param agg: the requested aggregation period
            :param cf: the requestion consolidation function

        Example:

            {"agg": "30",
             "end_time": 1254350090,
             "data": [[1254349980, 163.0],
                      [1254350010, 28.133333333333333],
                      [1254350040, 96.966666666666669],
                      [1254350070, 110.03333333333333]],
             "cf": "average",
             "begin_time": 1254350000}
        """

        next = None
        if rest:
            next, rest = split_url(rest)
            if next == 'aggs':
                # XXX list actual aggs
                return dict(aggregates=[30], cf=['average'])
            elif dataset not in ['error', 'discard'
                                 ] and next not in ['in', 'out']:
                return web.notfound("nope")

        args = parse_query_string()

        if args.has_key('begin'):
            begin = args['begin']
        else:
            begin = int(time.time() - 3600)

        if args.has_key('end'):
            end = args['end']
        else:
            end = int(time.time())

        if args.has_key('cf'):
            cf = args['cf']
        else:
            cf = 'average'

        if args.has_key('oidset'):
            traffic_oidset = args['oidset']
            if traffic_oidset == 'FastPoll':
                traffic_mod = ''
            else:
                traffic_mod = 'HC'
        else:
            traffic_oidset, traffic_mod = get_traffic_oidset(devicename)

        if args.has_key('agg'):
            agg = args['agg']
            suffix = 'TSDBAggregates/%s/' % (args['agg'], )
        else:
            if cf == 'raw':
                suffix = ''
                agg = ''
            else:
                if traffic_oidset != 'SuperFastPollHC':
                    suffix = 'TSDBAggregates/30/'
                    agg = '30'
                else:
                    suffix = 'TSDBAggregates/10/'
                    agg = '10'

        if dataset in ['in', 'out']:  # traffic
            begin, end = int(begin), int(end)

            if traffic_oidset == 'InfFastPollHC':
                path = '%s/%s/gigeClientCtpPmReal%sOctets/%s/%s' % (
                    devicename, traffic_oidset, DATASET_INFINERA_MAP[dataset],
                    remove_metachars(iface), suffix)
            else:
                path = '%s/%s/if%s%sOctets/%s/%s' % (
                    devicename, traffic_oidset, traffic_mod,
                    dataset.capitalize(), remove_metachars(iface), suffix)
        elif dataset in ['error', 'discard']:
            # XXX set agg to delta rather than average
            path = '%s/Errors/if%s%ss/%s' % (devicename, next.capitalize(),
                                             dataset.capitalize(),
                                             remove_metachars(iface))
            path += '/TSDBAggregates/300/'
            agg = '300'
        else:
            print "ERR> can't resolve path"
            return web.notfound()  # Requested variable does not exist

        try:
            v = self.db.get_var(path)
        except TSDBVarDoesNotExistError:
            print "ERR> var doesn't exist: %s" % path
            return web.notfound()  # Requested variable does not exist
        except InvalidMetaData:
            print "ERR> invalid metadata: %s" % path
            return web.notfound()

        try:
            data = v.select(begin=begin, end=end)
        except TSDBVarEmpty:
            print "ERR> var has no data: %s" % path
            return web.notfound()

        data = [d for d in data]
        r = []

        for datum in data:
            if cf != 'raw':
                d = [datum.timestamp, getattr(datum, cf)]
            else:
                d = [datum.timestamp, datum.value]

            if isNaN(d[1]):
                d[1] = None

            r.append(d)

        result = dict(data=r, begin_time=begin, end_time=end, cf=cf, agg=agg)

        if args.has_key('calc'):
            if args.has_key('calc_func'):
                calc_func = args['calc_func']
            else:
                calc_func = 'average'

            r = self.calculate(args['calc'], agg, calc_func, r)
            if isinstance(r, HTTPError):
                return r

            result['data'] = r
            result['calc'] = args['calc']
            result['calc_func'] = calc_func

            # these don't make sense if we're using calc
            del result['agg']
            del result['cf']

        return result
Exemplo n.º 12
0
    def get_interface_data(self, devicename, iface, dataset, rest):
        """Returns a JSON object representing counter data for an interface.

        This is obtained by doing a GET of one of the follwing URIs:

            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/in
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/out
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/error/in
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/error/out
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/discard/in
            /snmp/DEVICE_NAME/interface/INTERFACE_NAME/discard/out

        For in and out 

        get_interface_data accepts several query parameters:

            begin --  expressed a seconds since the epoch
            end --  expressed a seconds since the epoch
            agg -- use a precomputed aggregate for data, defaults to highest available resolution
            cf -- consolidation function. defaults to average
            calc -- calculate an aggregate, see below for more details
            calc_func --
            oidset -- specifically specify an oidset, see below

        agg specifies which precomputed aggregate to use.  Aggregates are
        represented as rates (eg. bytes/sec) and are calculated for the base
        rate at the time the data is persisted to disk.   This is specified as
        the number of seconds in the aggregation period or as 'raw'.  'raw'
        returns the counter data as collected from the device without any
        processing.  Currently there is only the aggreagate for the base polling
        interval and as a result this is rarely used.  cf determines how
        datapoints are agreggated into a single datapoint.  By default the
        datapoints are averaged but the maximum and minimum can also be used.
        valid options for this parameter are 'min', 'max' and 'average'.  This
        applies to precomputed aggregates that are greater than the base polling
        frequency.

        calc requests that the database dynamically generate an aggregate from
        the base aggregate for this counter.  The parameter is set to the
        numberof seconds to be used in the aggregation period.  The function
        used to consolidate each group of data points into a single data in the
        aggregate is controlled by the calc_func parameter.

        calc_func specifies the function to use when calculating an aggregate.
        It may be one of 'average', 'min',  or 'max' and defaults to 'average'.

        oidset allows the query to specify a specific oidset to get the data
        from rather than using the usual method for locating the oidset.  This
        is very rarely used.

        An interface data JSON object has the following fields:

            :param data: a list of tuples.  each tuple is [timestamp, value]
            :param begin_time: the requested begin_time
            :param end_time: the requested end_time
            :param agg: the requested aggregation period
            :param cf: the requestion consolidation function

        Example:

            {"agg": "30",
             "end_time": 1254350090,
             "data": [[1254349980, 163.0],
                      [1254350010, 28.133333333333333],
                      [1254350040, 96.966666666666669],
                      [1254350070, 110.03333333333333]],
             "cf": "average",
             "begin_time": 1254350000}
        """

        next = None
        if rest:
            next, rest = split_url(rest)
            if next == 'aggs':
                # XXX list actual aggs
                return dict(aggregates=[30], cf=['average'])
            elif dataset not in ['error', 'discard'] and next not in ['in', 'out']:
                return web.notfound("nope")

        args = parse_query_string()

        if args.has_key('begin'):
            begin = args['begin']
        else:
            begin = int(time.time() - 3600)

        if args.has_key('end'):
            end = args['end']
        else:
            end = int(time.time())

        if args.has_key('cf'):
            cf = args['cf']
        else:
            cf = 'average'

        if args.has_key('oidset'):
            traffic_oidset = args['oidset']
            if traffic_oidset == 'FastPoll':
                traffic_mod = ''
            else:
                traffic_mod = 'HC'
        else:
            traffic_oidset, traffic_mod = get_traffic_oidset(devicename)

        if args.has_key('agg'):
            agg = args['agg']
            suffix = 'TSDBAggregates/%s/' % (args['agg'], )
        else:
            if cf == 'raw':
                suffix = ''
                agg = ''
            else:
                if traffic_oidset != 'SuperFastPollHC':
                    suffix = 'TSDBAggregates/30/'
                    agg = '30'
                else:
                    suffix = 'TSDBAggregates/10/'
                    agg = '10'

        if dataset in ['in', 'out']: # traffic
            begin, end = int(begin), int(end)

            if traffic_oidset == 'InfFastPollHC':
                path = '%s/%s/gigeClientCtpPmReal%sOctets/%s/%s' % (devicename,
                        traffic_oidset, DATASET_INFINERA_MAP[dataset],
                        remove_metachars(iface), suffix)
            else:
                path = '%s/%s/if%s%sOctets/%s/%s' % (devicename, traffic_oidset,
                    traffic_mod, dataset.capitalize(),
                    remove_metachars(iface), suffix)
        elif dataset in ['error', 'discard']:
            # XXX set agg to delta rather than average
            path = '%s/Errors/if%s%ss/%s' % (devicename, next.capitalize(),
                    dataset.capitalize(), remove_metachars(iface))
            path += '/TSDBAggregates/300/'
            agg = '300'
        else:
            print "ERR> can't resolve path"
            return web.notfound()  # Requested variable does not exist
            
        try:
            v = self.db.get_var(path)
        except TSDBVarDoesNotExistError:
            print "ERR> var doesn't exist: %s" % path
            return web.notfound()  # Requested variable does not exist
        except InvalidMetaData:
            print "ERR> invalid metadata: %s" % path
            return web.notfound()

        try:
            data = v.select(begin=begin, end=end)
        except TSDBVarEmpty:
            print "ERR> var has no data: %s" % path
            return web.notfound()

        data = [d for d in data]
        r = []

        for datum in data:
            if cf != 'raw':
                d = [datum.timestamp, getattr(datum, cf)]
            else:
                d = [datum.timestamp, datum.value]

            if isNaN(d[1]):
                d[1] = None

            r.append(d)

        result = dict(data=r, begin_time=begin, end_time=end, cf=cf, agg=agg)

        if args.has_key('calc'):
            if args.has_key('calc_func'):
                calc_func = args['calc_func']
            else:
                calc_func = 'average'

            r = self.calculate(args['calc'], agg, calc_func, r)
            if isinstance(r, HTTPError):
                return r

            result['data'] = r
            result['calc'] = args['calc']
            result['calc_func'] = calc_func

            # these don't make sense if we're using calc
            del result['agg']
            del result['cf']

        return result