Ejemplo n.º 1
0
    def get_ifmaxspeed(self, if_name=None, if_id=None):
        if if_id:
            self.if_id = str(if_id)
        else:
            if hasattr(self, 'if_id'):
                if_id = self.if_id
            else:
                if if_name is None:
                    if hasattr(self, 'if_name'):
                        if_name = self.if_name
                    else:
                        raise MyError('no interface specified!')
                if_id = self.find_interface_id(if_name)

        rs = snmpget(self.address,
                     '{0}.{1}'.format(OIDS['ifSpeed'], if_id),
                     self.community,
                     self.snmpver,
                     exception=True)
        try:
            self.ifspeed_max = int(rs['value'])
        except:
            self.ifspeed_max = None
            raise MyError(
                "can't get maxspeed with interface id = {0}, oid = {1}".format(
                    if_id, '{0}.{1}'.format(OIDS['ifSpeed'], if_id)))
        if self.ifspeed_max >= 4 * 1e9:
            # experimental and dirty, need to improve
            rs = snmpget(self.address,
                         '{0}.{1}'.format(OIDS['ifHighSpeed'], if_id),
                         self.community,
                         self.snmpver,
                         exception=True)
            self.ifspeed_max = int(rs['value']) * 1e6
        return self.ifspeed_max
Ejemplo n.º 2
0
 def get_ifmaxspeed(self, if_name=None, if_id=None):
     if if_id:
         self.if_id = str(if_id)
     else:
         if hasattr(self, 'if_id'):
             if_id = self.if_id
         else:
             if if_name is None:
                 if hasattr(self, 'if_name'):
                     if_name = self.if_name
                 else:
                     raise MyError('no interface specified!')
             if_id = self.find_interface_id(if_name)
             
     rs = snmpget(self.address, '{0}.{1}'.format(OIDS['ifSpeed'], if_id), self.community, 
                                                                     self.snmpver, exception=True)
     try:
         self.ifspeed_max = int(rs['value'])
     except:
         self.ifspeed_max = None
         raise MyError("can't get maxspeed with interface id = {0}, oid = {1}".
                     format(if_id, '{0}.{1}'.format(OIDS['ifSpeed'], if_id)))
     if self.ifspeed_max >= 4 * 1e9: 
         # experimental and dirty, need to improve
         rs = snmpget(self.address, '{0}.{1}'.format(OIDS['ifHighSpeed'], if_id), self.community, 
                                                                     self.snmpver, exception=True)
         self.ifspeed_max = int(rs['value']) * 1e6
     return self.ifspeed_max
Ejemplo n.º 3
0
    def if_check64(self, if_name=None):
        '''returns true if 64 bit counters can be used (useful for high speed interfaces)
        '''
        if if_name is None:  # use already saved data
            if hasattr(self, 'if_name'):
                if_name = self.if_name
            else:
                raise MyError('no interface specified to poll')
            if not hasattr(self, 'if_id'):
                self.find_interface_id(if_name)  # find if_id
        else:
            self.find_interface_id(if_name)  # find if_id

        try:
            rs = snmpget(self.address,
                         '{0}.{1}'.format(OIDS['ifHCInOctets'], self.if_id),
                         self.community,
                         self.snmpver,
                         exception=True)
        except SnmpError:  # no data recieved
            self.use64bit = False

        if not rs['value']:
            self.use64bit = False
        else:
            self.use64bit = True
        return self.use64bit
Ejemplo n.º 4
0
 def get_sysdescr(self):
     '''get agent sysdescr and trivial detect of Cisco device
     '''
     rs = snmpget(self.address,
                  OIDS['sysDescr'],
                  self.community,
                  self.snmpver,
                  exception=True)
     self.sysdescr = rs['value']
     return self.sysdescr
Ejemplo n.º 5
0
 def get_sysname(self):
     '''get agent sysname
     '''
     rs = snmpget(self.address,
                  OIDS['sysName'],
                  self.community,
                  self.snmpver,
                  exception=True)
     self.sysname = rs['value']
     return self.sysname
Ejemplo n.º 6
0
    def get_ifbytes(
        self,
        if_name=None,
        if_id=None,
        force64bit=False,
    ):
        '''get interface octets: .ifInOctets, .ifOutOctets, sysUptime,ifInErrors, ifOutErrors
           if_name = None to skip id searching (no additional requests for looped polls)
        '''
        if if_id:
            self.if_id = str(if_id)
        else:
            if if_name is None:  # use already saved data, used for looped polls
                if hasattr(self, 'if_name'):
                    if_name = self.if_name
                else:
                    raise MyError('no interface specified to poll')
                if not hasattr(self, 'if_id'):
                    self.find_interface_id(if_name)  # find if_id
                    force64bit = self.if_check64()  # ne pomeshaet :)
            else:
                self.find_interface_id(if_name)  # find if_id
                force64bit = self.if_check64()  # ne pomeshaet :)

        sysUpTime = OIDS['sysUpTime']
        if force64bit:
            ifinoctets = OIDS['ifHCInOctets']
            ifoutoctets = OIDS['ifHCOutOctets']
        else:
            ifinoctets = OIDS['ifInOctets']
            ifoutoctets = OIDS['ifOutOctets']

        rs = snmpget(self.address, (
            ifinoctets + '.' + self.if_id,
            ifoutoctets + '.' + self.if_id,
            sysUpTime,
            OIDS['ifInErrors'] + '.' + self.if_id,
            OIDS['ifOutErrors'] + '.' + self.if_id,
        ),
                     self.community,
                     self.snmpver,
                     exception=True)

        # save for further use (for looped polls)
        self.if_name = if_name
        return rs
Ejemplo n.º 7
0
 def get_ifbytes(self, if_name=None, if_id=None, force64bit=False,):
     '''get interface octets: .ifInOctets, .ifOutOctets, sysUptime,ifInErrors, ifOutErrors
        if_name = None to skip id searching (no additional requests for looped polls)
     '''
     if if_id:
         self.if_id = str(if_id)
     else:
         if if_name is None:     # use already saved data, used for looped polls
             if hasattr(self, 'if_name'):
                 if_name = self.if_name
             else:
                 raise MyError('no interface specified to poll')
             if not hasattr(self, 'if_id'):
                 self.find_interface_id(if_name)     # find if_id
                 force64bit = self.if_check64()  # ne pomeshaet :)
         else:
             self.find_interface_id(if_name)     # find if_id
             force64bit = self.if_check64()  # ne pomeshaet :)
     
     sysUpTime = OIDS['sysUpTime']
     if force64bit:
         ifinoctets = OIDS['ifHCInOctets']
         ifoutoctets = OIDS['ifHCOutOctets']
     else:
         ifinoctets = OIDS['ifInOctets']
         ifoutoctets = OIDS['ifOutOctets']
         
     rs = snmpget(self.address, (
             ifinoctets + '.' + self.if_id,
             ifoutoctets + '.' + self.if_id,
             sysUpTime,
             OIDS['ifInErrors'] + '.' + self.if_id,
             OIDS['ifOutErrors'] + '.' + self.if_id,
     ), self.community, self.snmpver, exception=True)
     
     # save for further use (for looped polls)
     self.if_name = if_name
     return rs
Ejemplo n.º 8
0
    def if_check64(self, if_name=None):
        '''returns true if 64 bit counters can be used (useful for high speed interfaces)
        '''
        if if_name is None:     # use already saved data
            if hasattr(self, 'if_name'):
                if_name = self.if_name
            else:
                raise MyError('no interface specified to poll')
            if not hasattr(self, 'if_id'):
                self.find_interface_id(if_name)     # find if_id
        else:
            self.find_interface_id(if_name)     # find if_id
            
        try:
            rs = snmpget(self.address, '{0}.{1}'.format(OIDS['ifHCInOctets'], self.if_id),
                                                    self.community, self.snmpver, exception=True)
        except SnmpError:    # no data recieved
            self.use64bit = False

        if not rs['value']:
            self.use64bit = False
        else:
            self.use64bit = True
        return self.use64bit
Ejemplo n.º 9
0
 def get_sysdescr(self):
     '''get agent sysdescr and trivial detect of Cisco device
     '''
     rs = snmpget(self.address, OIDS['sysDescr'], self.community, self.snmpver, exception=True)
     self.sysdescr = rs['value']
     return self.sysdescr
Ejemplo n.º 10
0
 def get_sysname(self):
     '''get agent sysname
     '''
     rs = snmpget(self.address, OIDS['sysName'], self.community, self.snmpver, exception=True)
     self.sysname = rs['value']
     return self.sysname
Ejemplo n.º 11
0
def main():
    parser = optparse.OptionParser(usage=__doc__)
    parser.add_option("-c",
                      help="snmp agent's community", default=COMMUNITY, dest="community", metavar="COMMUNITY")
    parser.add_option("-v",
                      help="snmp version: default is %default", default=SNMPVER, dest="snmpver", metavar="VERSION")
    parser.add_option("-u",
                      help="update interval: default is %default", dest="updtime", default=UPDTIME, metavar="SECONDS")
    parser.add_option("-m",
                      help="set maximum bandwidth manually", dest="maxspeed", default=None, metavar="BITS/S")
    parser.add_option("--64",
                      help="force to use 64 bit counters", action="store_true", dest="use64bit", default=False)
    parser.add_option("-g", "--hist",
                      action="store_false", dest="hist", default=True,
                      help="histogram mode")
    parser.add_option("-t",
                      action="store_true", dest="histT", default=False,
                      help="histogram mode with timestamps")
    parser.add_option("-l",
                      action="store_true", dest="list", default=False,
                      help="list index of available interfaces")
    parser.add_option("-q",
                      action="store_true", dest="verbose", default=False,
                      help="verbose output")
    (opts, args) = parser.parse_args()
    if len(args) < 1:
        parser.error("no address specified")

    opts.address = args[0]
    opts.updtime = int(opts.updtime)
    if len(args) > 1:
        opts.if_name = args[1]
    else:
        opts.if_name = None
    if opts.address is None:
        parser.error("no address specified")
    elif opts.community is None:
        parser.error("no community specified")
#######################################################################################################################

    if opts.verbose: print('* Trying the host {0}...'.format(opts.address))
    poller = SnmpIfInfo(opts.address, opts.community, opts.snmpver)
    poller.get_sysdescr()
    if opts.verbose: print poller.sysdescr
    
    rows, columns = terminal_size()
    if opts.verbose: print '* Getting interface table...'
    poller.get_ifnametable()
    
    if opts.if_name:
        try:
            poller.find_interface_id(opts.if_name)
        except MyError: pass
    if not hasattr(poller, 'if_id') or opts.verbose or opts.list:
        print 'Available interface list:'
        print '-' * columns
        print sorted(poller.ifnametable, key=poller._sort_natural)
        print '-' * columns
    if opts.list:
        from modules.mytable import formatTable
        print 'Detailed interface list:'
        iftable = poller.get_iftable()
        labels = ('ifIndex', 'ifName', 'ifAlias', 'ifDescr')
        table = []
        for i in iftable:
            table.append([i['ifid'], i['ifname'], i['ifalias'], i['ifdescr']])
        # autofit table width:
        for i in [0] + range(30, 1, -1):
            outTable = formatTable([labels] + table, separateRows=2, border='|',
                                            leftBorder='|', rightBorder='|', width=i)
            tablelen = outTable.find('\n')
            if columns-tablelen > 1:
                break
        print outTable
        sys.exit()
    if not hasattr(poller, 'if_id'):
        if opts.if_name: raise
        else: raise MyError('no interface specified')

    poller.get_sysname()
    print poller.sysname.center(columns)
    print poller.sysdescr.splitlines()[0][:columns].center(columns)
    print '-' * columns
    rs = snmpget(poller.address, OIDS['ifDescr'] + '.' + poller.if_id, poller.community, poller.snmpver)
    poller.ifdescr = rs['value']
    s = rs['value']
    rs = snmpget(poller.address, OIDS['ifAlias'] + '.' + poller.if_id, poller.community, poller.snmpver)
    poller.ifalias = rs['value']
    s += ': "' + rs['value'] + '"'
    print(s)
    try:
        rs = snmpget(poller.address, ('{0}.{1}'.format(OIDS['ifAdminStatus'], poller.if_id),
            '{0}.{1}'.format(OIDS['ifOperStatus'], poller.if_id)), poller.snmpver, exception=True)
    except SnmpError:
        poller.if_admin_status = None
        poller.if_op_status = None
    else:
        print rs
        poller.if_admin_status = rs['value'][0]
        poller.if_op_status = rs['value'][1]
        if not '1' in poller.if_admin_status or not '1' in poller.if_op_status:
            print 'Warning: ifAdminStatus:', poller.if_admin_status
            print 'Warning: ifOperStatus:', poller.if_op_status
    print('-' * columns)

    if not opts.maxspeed:
        poller.get_ifmaxspeed()
    else:
        poller.ifspeed_max = int(opts.maxspeed)

    speed, units = poller._convert_speed(poller.ifspeed_max)
    try:
        rs = snmpget(poller.address, OIDS['ifInErrors'] + '.' + poller.if_id,
                                            poller.community, poller.snmpver, exception=True)
    except SnmpError:
        poller.ifinerrors = '?'
    else:
        poller.ifinerrors = int(rs['value'])

    try:
        rs = snmpget(poller.address, OIDS['ifOutErrors'] + '.' + poller.if_id,
                                            poller.community, poller.snmpver, exception=True)
    except SnmpError:
        poller.ifouterrors = '?'
    else:
        poller.ifouterrors = int(rs['value'])
    
    if opts.use64bit:
        use64bit = True
    elif getattr(poller, 'ifspeed_max', 0) >= 1e9:  # try to use 64bit counters on gigabit interfaces
        use64bit = poller.if_check64()
    else:
        use64bit = False

    if use64bit:
        s = '64 |'
    else: s = ''
    print '| Spd:', speed, units + 'bit/s', '| iErr:', str(poller.ifinerrors), '| oErr:',\
                                str(poller.ifouterrors), '| Upd:', str(opts.updtime)+'s', '|', s
    
###############################################################################################################    
    #rs = poller.get_ifrate(req_delay=1, if_id = 1)
    #print rs
    #sys.exit()
###############################################################################################################    
    
    noprint = False
    stab_time = 1
    while 1:
        rows, columns = terminal_size()
        try:
            data = poller.get_ifrate(req_delay=opts.updtime, force64bit=use64bit)
        except SnmpError as ei:    # no data recieved
            # stop watching:
            #if stab_time > 600:
            #    print '\n', ei
            #    raise MyError('device is too busy or inaccessible')
            noprint = True  # wait for device to become stable
            sleep(stab_time * opts.updtime)
            if stab_time * opts.updtime < 600:
                stab_time *= 2
            #continue
        stab_time = 1
        
        in_speed = data['in_speed']
        out_speed = data['out_speed']

        if None in data:
            noprint = True
        
        if noprint is False:
            in_speed_str, in_units = poller._convert_speed(in_speed)
            out_speed_str, out_units = poller._convert_speed(out_speed)
            if round(in_speed_str, 1) < 10:
                in_speed_str = 'In:  ' + str(round(in_speed_str,1)).rjust(3) + ' ' + in_units + 'bit/s'
            else: # kick off unnecessary decimals
                in_speed_str = 'In:  ' + str(int(round(in_speed_str))).rjust(3) + ' ' + in_units + 'bit/s'
            if round(out_speed_str, 1) < 10:        
                out_speed_str = 'Out: ' + str(round(out_speed_str,1)).rjust(3) + ' ' + out_units + 'bit/s'
            else:
                out_speed_str = 'Out: ' + str(int(round(out_speed_str))).rjust(3) + ' ' + out_units + 'bit/s'
            # prepare timestamps
            if opts.histT:
                out = '|' + time.strftime('%H:%M:%S') + '|'
                i = (columns - len(in_speed_str + out_speed_str) - 4 - len(out)) // 2
            else:
                out = ''
                i = (columns - len(in_speed_str + out_speed_str) - 4) // 2

            out += in_speed_str + ' ' + progressbar(in_speed, max_val=poller.ifspeed_max, width=i)
            out += '  '
            out += out_speed_str + ' ' + progressbar(out_speed, max_val=poller.ifspeed_max, width=i)
        else:
            out = 'Collecting data...'

        # add endings for non-scrolling output
        if not (opts.hist or opts.histT):
            out += ' ' * (columns - len(out) - 1) + '\r'
        else: 
            out += ' ' * (columns - len(out) - 1) + '\n'
        sys.stdout.write(out)
        sys.stdout.flush()
        noprint = False
Ejemplo n.º 12
0
def ifrate_page(request):
    '''main ifrate page
    '''
    def js_timestamp_from_datetime(dt):
        return calendar.timegm(dt.timetuple()) * 1000

    errors = []
    warnings = []

    if request.is_ajax() and request.method == 'GET':
        # ajax requests from poller
        #
        format = 'json'  # output format switcher. you can use this parameter as fucntion parameter.
        if format == 'xml':
            mimetype = 'application/xml'
        if format == 'json':
            mimetype = 'application/javascript'

        host = request.GET['host']
        community = request.GET['community']
        snmpver = request.GET['snmpver']
        if_id = request.GET['if_id']
        upd_int = int(request.GET['upd_int'])
        # защита от самых умных
        if upd_int < 5:
            upd_int = 5
        elif upd_int > 3600:
            upd_int = 3600

        # online counter
        # may throw error while trying to change online_count simultaniosly
        # try:
        #     ip = get_client_ip(request)
        #     hosts = {}
        #     if ip in online_count:
        #         hosts = online_count[ip]
        #     hosts[host] = {'ts': datetime.datetime.now(), 'upd_int': upd_int}
        #     online_count[ip] = hosts
        # except RuntimeError: # dict size changed
        #     pass

        err_flag = True
        # важно чтобы этот паролик не попал в код страницы
        if not community:
            community = COMMUNITY
        try:
            poller = snmp_ifrate.SnmpIfInfo(address=host,
                                            community=community,
                                            snmpver=snmpver)
            rate = poller.get_ifrate_forced(if_id=if_id, req_delay=upd_int)
            #rate = poller.get_ifrate_forced(if_id=if_id, req_delay=upd_int, force64bit=use64bit)
            err_flag = False
        except mypysnmp.SnmpError as ei:
            errors.append(ei)
        except snmp_ifrate.MyError as ei:
            errors.append(ei)
        except:
            errors.append(u'Ошибка получения данных: {0}'.format(
                sys.exc_info()[1]))

        if err_flag:
            # return AjaxError
            errors.insert(0, u'Не могу подключиться к {0}!'.format(host))
            out = ''
            for i in errors:
                out += unicode(i) + u' '
            sleep(upd_int)
            return HttpResponse(out)
        else:
            jscript_data = rate
            jscript_data['timestamp'] = js_timestamp_from_datetime(
                datetime.datetime.utcnow())

            # DEBUG only: random error generator
            # import random, time
            # rnd = int(random.random() * 10)
            # if rnd > 6:
            #     jscript_data['in_errors'] = int(time.time())
            # if rnd > 8:
            #     jscript_data['out_errors'] = int(time.time())

            jscript_data = json.dumps(jscript_data)
            return HttpResponse(jscript_data, mimetype)

    if 'host' in request.GET:
        # заданы параметры хоста, но не задан интерфейс
        form_host_query = forms.HostQueryForm(request.GET)
        if form_host_query.is_valid():
            if 'interface' in request.GET:
                # заданы параметры хоста и выбран интерфейс
                # сначала собираем общие данные об интерфейсе

                ifdata = {}

                host = form_host_query.cleaned_data['host']
                community = form_host_query.cleaned_data['community']
                snmpver = form_host_query.cleaned_data['snmpver']
                if_id = form_host_query.data['interface']

                ifdata['host'] = host
                ifdata['community'] = community
                ifdata['snmpver'] = snmpver
                ifdata['if_id'] = if_id
                ifdata['ajax_url'] = reverse(
                    'ifrate')  # url of ajax request handler

                # важно чтобы этот паролик не попал в код страницы
                if not community:
                    community = COMMUNITY
                try:
                    # collect initial interface data:
                    poller = snmp_ifrate.SnmpIfInfo(host, community, snmpver)
                    ifdata['sysname'] = poller.get_sysname()
                    speed, units = poller._convert_speed(
                        poller.get_ifmaxspeed(if_id=if_id))
                    ifdata['ifmaxspeed'] = "{0} {1}bit/s".format(
                        str(speed), units)
                    rs = mypysnmp.snmpget(host, OIDS['ifDescr'] + '.' + if_id,
                                          community, snmpver)
                    ifdata['if_descr'] = rs['value']
                    rs = mypysnmp.snmpget(host, OIDS['ifAlias'] + '.' + if_id,
                                          community, snmpver)
                    ifdata['if_alias'] = rs['value'] if rs['value'] else ''
                    rs = mypysnmp.snmpget(host, OIDS['ifName'] + '.' + if_id,
                                          community, snmpver)
                    ifdata['if_name'] = rs['value']

                    try:
                        rs = mypysnmp.snmpget(
                            host, (OIDS['ifAdminStatus'] + '.' + if_id,
                                   OIDS['ifOperStatus'] + '.' + if_id),
                            community,
                            snmpver,
                            exception=True)
                    except mypysnmp.SnmpError:
                        ifdata['if_admst'] = None
                        ifdata['if_opst'] = None
                    else:
                        #if not rs['errorIndication']:
                        ifdata['if_admst'] = rs['value'][0]
                        ifdata['if_opst'] = rs['value'][1]
                        if not '1' in ifdata['if_admst'] or not '1' in ifdata[
                                'if_opst']:
                            warnings.append(
                                u'Внимание: интерфейс выключен администратором (ifAdminStatus: {0}).'
                                .format(ifdata['if_admst']))
                            warnings.append(
                                u'Внимание: нет линка (ifOperStatus: {0})'.
                                format(ifdata['if_opst']))

                    poller.if_id = if_id
                    poller.if_name = if_id
                    ifdata['if_maxspd'] = poller.get_ifmaxspeed()
                    speed, units = poller._convert_speed(ifdata['if_maxspd'])
                    ifdata['if_maxspd_str'] = '{0} {1}'.format(speed, units)

                    # rs = mypysnmp.snmpget(host, OIDS['ifInErrors'] + '.' + if_id, community, snmpver)
                    # if rs['value']:
                    #     poller.ifinerrors = int(rs['value'])
                    # else:
                    #     poller.ifinerrors = '?'
                    # rs = mypysnmp.snmpget(host, OIDS['ifOutErrors'] + '.' + if_id, community, snmpver, exception=True)
                    # if rs['value']:
                    #     poller.ifouterrors = int(rs['value'])
                    # else:
                    #     poller.ifouterrors = '?'
                    # ifdata['if_in_errors'] = poller.ifinerrors
                    # ifdata['if_out_errors'] = poller.ifouterrors
                    # if ifdata['if_in_errors'] > 0: warnings.append(u'Внимание: ненулевой счетчик ошибок на входе интерфейса: {0}.'.format(ifdata['if_in_errors']))
                    # if ifdata['if_out_errors'] > 0: warnings.append(u'Внимание: ненулевой счетчик ошибок на выходе интерфейса: {0}.'.format(ifdata['if_out_errors']))
                except mypysnmp.SnmpError as ei:
                    errors.append(ei)
                except snmp_ifrate.MyError as ei:
                    errors.append(ei)
                except ValueError as ei:
                    errors.append(
                        'Получены данные неизвестного формата: {}'.format(ei))
            else:
                host = form_host_query.cleaned_data['host']
                community = form_host_query.cleaned_data['community']
                snmpver = form_host_query.cleaned_data['snmpver']
                err_flag = True
                if not community:
                    community = COMMUNITY
                try:
                    poller = snmp_ifrate.SnmpIfInfo(host, community, snmpver)
                    poller.get_ifnametable()
                    err_flag = False
                except mypysnmp.SnmpError as ei:
                    errors.append(ei)
                except snmp_ifrate.MyError as ei:
                    errors.append(ei)
                except:
                    errors.append(
                        u'Ошибка при получении информации об интерфейсах: {0}'.
                        format(sys.exc_info()[1]))
                if err_flag:
                    errors.insert(0,
                                  u'Не могу подключиться к {0}!'.format(host))
                else:
                    interfaces = [
                        i for i in sorted(poller.ifnametable,
                                          key=poller._sort_natural)
                    ]
                    choices = []
                    for i in interfaces:
                        choices.append([poller.ifnametable[i], i])
                    form_host_query = forms.HostQueryForm(request.GET,
                                                          mychoices=choices)
        else:
            error = u'Правильно задайте имя (или адрес) устройства, строку community и версию протокола SNMP'
    else:
        # начальная страничка с формой:
        # counter
        # now = datetime.datetime.now()
        # ip_list = {}
        # for ip, v in online_count.items():
        #     for host, data in online_count[ip].items():
        #         if now > (data['ts'] + datetime.timedelta(seconds=2*data['upd_int'])):
        #             del online_count[ip][host]
        #         else:
        #             ip_list[ip] = [key for key, val in online_count[ip].items()]

        form_host_query = forms.HostQueryForm(None)

    return render_to_response('ifrate.html',
                              locals(),
                              context_instance=RequestContext(request))
Ejemplo n.º 13
0
def main():
    parser = optparse.OptionParser(usage=__doc__)
    parser.add_option("-c",
                      help="snmp agent's community",
                      default=COMMUNITY,
                      dest="community",
                      metavar="COMMUNITY")
    parser.add_option("-v",
                      help="snmp version: default is %default",
                      default=SNMPVER,
                      dest="snmpver",
                      metavar="VERSION")
    parser.add_option("-u",
                      help="update interval: default is %default",
                      dest="updtime",
                      default=UPDTIME,
                      metavar="SECONDS")
    parser.add_option("-m",
                      help="set maximum bandwidth manually",
                      dest="maxspeed",
                      default=None,
                      metavar="BITS/S")
    parser.add_option("--64",
                      help="force to use 64 bit counters",
                      action="store_true",
                      dest="use64bit",
                      default=False)
    parser.add_option("-g",
                      "--hist",
                      action="store_false",
                      dest="hist",
                      default=True,
                      help="histogram mode")
    parser.add_option("-t",
                      action="store_true",
                      dest="histT",
                      default=False,
                      help="histogram mode with timestamps")
    parser.add_option("-l",
                      action="store_true",
                      dest="list",
                      default=False,
                      help="list index of available interfaces")
    parser.add_option("-q",
                      action="store_true",
                      dest="verbose",
                      default=False,
                      help="verbose output")
    (opts, args) = parser.parse_args()
    if len(args) < 1:
        parser.error("no address specified")

    opts.address = args[0]
    opts.updtime = int(opts.updtime)
    if len(args) > 1:
        opts.if_name = args[1]
    else:
        opts.if_name = None
    if opts.address is None:
        parser.error("no address specified")
    elif opts.community is None:
        parser.error("no community specified")


#######################################################################################################################

    if opts.verbose: print('* Trying the host {0}...'.format(opts.address))
    poller = SnmpIfInfo(opts.address, opts.community, opts.snmpver)
    poller.get_sysdescr()
    if opts.verbose: print poller.sysdescr

    rows, columns = terminal_size()
    if opts.verbose: print '* Getting interface table...'
    poller.get_ifnametable()

    if opts.if_name:
        try:
            poller.find_interface_id(opts.if_name)
        except MyError:
            pass
    if not hasattr(poller, 'if_id') or opts.verbose or opts.list:
        print 'Available interface list:'
        print '-' * columns
        print sorted(poller.ifnametable, key=poller._sort_natural)
        print '-' * columns
    if opts.list:
        from modules.mytable import formatTable
        print 'Detailed interface list:'
        iftable = poller.get_iftable()
        labels = ('ifIndex', 'ifName', 'ifAlias', 'ifDescr')
        table = []
        for i in iftable:
            table.append([i['ifid'], i['ifname'], i['ifalias'], i['ifdescr']])
        # autofit table width:
        for i in [0] + range(30, 1, -1):
            outTable = formatTable([labels] + table,
                                   separateRows=2,
                                   border='|',
                                   leftBorder='|',
                                   rightBorder='|',
                                   width=i)
            tablelen = outTable.find('\n')
            if columns - tablelen > 1:
                break
        print outTable
        sys.exit()
    if not hasattr(poller, 'if_id'):
        if opts.if_name: raise
        else: raise MyError('no interface specified')

    poller.get_sysname()
    print poller.sysname.center(columns)
    print poller.sysdescr.splitlines()[0][:columns].center(columns)
    print '-' * columns
    rs = snmpget(poller.address, OIDS['ifDescr'] + '.' + poller.if_id,
                 poller.community, poller.snmpver)
    poller.ifdescr = rs['value']
    s = rs['value']
    rs = snmpget(poller.address, OIDS['ifAlias'] + '.' + poller.if_id,
                 poller.community, poller.snmpver)
    poller.ifalias = rs['value']
    s += ': "' + rs['value'] + '"'
    print(s)
    try:
        rs = snmpget(poller.address,
                     ('{0}.{1}'.format(OIDS['ifAdminStatus'], poller.if_id),
                      '{0}.{1}'.format(OIDS['ifOperStatus'], poller.if_id)),
                     poller.snmpver,
                     exception=True)
    except SnmpError:
        poller.if_admin_status = None
        poller.if_op_status = None
    else:
        print rs
        poller.if_admin_status = rs['value'][0]
        poller.if_op_status = rs['value'][1]
        if not '1' in poller.if_admin_status or not '1' in poller.if_op_status:
            print 'Warning: ifAdminStatus:', poller.if_admin_status
            print 'Warning: ifOperStatus:', poller.if_op_status
    print('-' * columns)

    if not opts.maxspeed:
        poller.get_ifmaxspeed()
    else:
        poller.ifspeed_max = int(opts.maxspeed)

    speed, units = poller._convert_speed(poller.ifspeed_max)
    try:
        rs = snmpget(poller.address,
                     OIDS['ifInErrors'] + '.' + poller.if_id,
                     poller.community,
                     poller.snmpver,
                     exception=True)
    except SnmpError:
        poller.ifinerrors = '?'
    else:
        poller.ifinerrors = int(rs['value'])

    try:
        rs = snmpget(poller.address,
                     OIDS['ifOutErrors'] + '.' + poller.if_id,
                     poller.community,
                     poller.snmpver,
                     exception=True)
    except SnmpError:
        poller.ifouterrors = '?'
    else:
        poller.ifouterrors = int(rs['value'])

    if opts.use64bit:
        use64bit = True
    elif getattr(poller, 'ifspeed_max',
                 0) >= 1e9:  # try to use 64bit counters on gigabit interfaces
        use64bit = poller.if_check64()
    else:
        use64bit = False

    if use64bit:
        s = '64 |'
    else:
        s = ''
    print '| Spd:', speed, units + 'bit/s', '| iErr:', str(poller.ifinerrors), '| oErr:',\
                                str(poller.ifouterrors), '| Upd:', str(opts.updtime)+'s', '|', s

    ###############################################################################################################
    #rs = poller.get_ifrate(req_delay=1, if_id = 1)
    #print rs
    #sys.exit()
    ###############################################################################################################

    noprint = False
    stab_time = 1
    while 1:
        rows, columns = terminal_size()
        try:
            data = poller.get_ifrate(req_delay=opts.updtime,
                                     force64bit=use64bit)
        except SnmpError as ei:  # no data recieved
            # stop watching:
            #if stab_time > 600:
            #    print '\n', ei
            #    raise MyError('device is too busy or inaccessible')
            noprint = True  # wait for device to become stable
            sleep(stab_time * opts.updtime)
            if stab_time * opts.updtime < 600:
                stab_time *= 2
            #continue
        stab_time = 1

        in_speed = data['in_speed']
        out_speed = data['out_speed']

        if None in data:
            noprint = True

        if noprint is False:
            in_speed_str, in_units = poller._convert_speed(in_speed)
            out_speed_str, out_units = poller._convert_speed(out_speed)
            if round(in_speed_str, 1) < 10:
                in_speed_str = 'In:  ' + str(round(
                    in_speed_str, 1)).rjust(3) + ' ' + in_units + 'bit/s'
            else:  # kick off unnecessary decimals
                in_speed_str = 'In:  ' + str(int(
                    round(in_speed_str))).rjust(3) + ' ' + in_units + 'bit/s'
            if round(out_speed_str, 1) < 10:
                out_speed_str = 'Out: ' + str(round(
                    out_speed_str, 1)).rjust(3) + ' ' + out_units + 'bit/s'
            else:
                out_speed_str = 'Out: ' + str(int(
                    round(out_speed_str))).rjust(3) + ' ' + out_units + 'bit/s'
            # prepare timestamps
            if opts.histT:
                out = '|' + time.strftime('%H:%M:%S') + '|'
                i = (columns - len(in_speed_str + out_speed_str) - 4 -
                     len(out)) // 2
            else:
                out = ''
                i = (columns - len(in_speed_str + out_speed_str) - 4) // 2

            out += in_speed_str + ' ' + progressbar(
                in_speed, max_val=poller.ifspeed_max, width=i)
            out += '  '
            out += out_speed_str + ' ' + progressbar(
                out_speed, max_val=poller.ifspeed_max, width=i)
        else:
            out = 'Collecting data...'

        # add endings for non-scrolling output
        if not (opts.hist or opts.histT):
            out += ' ' * (columns - len(out) - 1) + '\r'
        else:
            out += ' ' * (columns - len(out) - 1) + '\n'
        sys.stdout.write(out)
        sys.stdout.flush()
        noprint = False
Ejemplo n.º 14
0
def ifrate_page(request):
    '''main ifrate page
    '''
    def js_timestamp_from_datetime(dt):
        return calendar.timegm(dt.timetuple()) * 1000

    errors = []
    warnings = []

    if request.is_ajax() and request.method == 'GET':
        # ajax requests from poller
        #
        format = 'json' # output format switcher. you can use this parameter as fucntion parameter.
        if format == 'xml':
            mimetype = 'application/xml'
        if format == 'json':
            mimetype = 'application/javascript'

        host = request.GET['host']
        community = request.GET['community']
        snmpver = request.GET['snmpver']
        if_id = request.GET['if_id']
        upd_int = int(request.GET['upd_int'])
        # защита от самых умных
        if upd_int < 5:
          upd_int = 5
        elif upd_int > 3600:
          upd_int = 3600

        # online counter
        # may throw error while trying to change online_count simultaniosly
        # try:
        #     ip = get_client_ip(request)
        #     hosts = {}
        #     if ip in online_count:
        #         hosts = online_count[ip]
        #     hosts[host] = {'ts': datetime.datetime.now(), 'upd_int': upd_int}
        #     online_count[ip] = hosts
        # except RuntimeError: # dict size changed
        #     pass

        err_flag = True
        # важно чтобы этот паролик не попал в код страницы
        if not community:
            community = COMMUNITY
        try:
            poller = snmp_ifrate.SnmpIfInfo(address=host, community=community, snmpver=snmpver)
            rate = poller.get_ifrate_forced(if_id=if_id, req_delay=upd_int)
            #rate = poller.get_ifrate_forced(if_id=if_id, req_delay=upd_int, force64bit=use64bit)
            err_flag = False
        except mypysnmp.SnmpError as ei:
            errors.append(ei)
        except snmp_ifrate.MyError as ei:
            errors.append(ei)
        except:
            errors.append(u'Ошибка получения данных: {0}'.format(sys.exc_info()[1]))
        
        if err_flag:
            # return AjaxError
            errors.insert(0, u'Не могу подключиться к {0}!'.format(host))
            out = ''
            for i in errors:
                out += unicode(i) + u' '
            sleep(upd_int)
            return HttpResponse(out)
        else:
            jscript_data = rate
            jscript_data['timestamp'] = js_timestamp_from_datetime(datetime.datetime.utcnow())

            # DEBUG only: random error generator
            # import random, time
            # rnd = int(random.random() * 10)
            # if rnd > 6:
            #     jscript_data['in_errors'] = int(time.time())
            # if rnd > 8:
            #     jscript_data['out_errors'] = int(time.time())

            jscript_data = json.dumps(jscript_data)
            return HttpResponse(jscript_data, mimetype)

    if 'host' in request.GET:
        # заданы параметры хоста, но не задан интерфейс
        form_host_query = forms.HostQueryForm(request.GET)
        if form_host_query.is_valid():
            if 'interface' in request.GET:
                # заданы параметры хоста и выбран интерфейс
                # сначала собираем общие данные об интерфейсе

                ifdata = {}
                
                host = form_host_query.cleaned_data['host']
                community = form_host_query.cleaned_data['community']
                snmpver = form_host_query.cleaned_data['snmpver']
                if_id = form_host_query.data['interface']

                ifdata['host'] = host
                ifdata['community'] = community
                ifdata['snmpver'] = snmpver
                ifdata['if_id'] = if_id
                ifdata['ajax_url'] = reverse('ifrate')  # url of ajax request handler
                
                # важно чтобы этот паролик не попал в код страницы
                if not community:
                    community = COMMUNITY
                try:
                    # collect initial interface data:
                    poller = snmp_ifrate.SnmpIfInfo(host, community, snmpver)
                    ifdata['sysname'] = poller.get_sysname()
                    speed, units = poller._convert_speed(poller.get_ifmaxspeed(if_id=if_id))
                    ifdata['ifmaxspeed'] = "{0} {1}bit/s".format(str(speed), units)
                    rs = mypysnmp.snmpget(host, OIDS['ifDescr'] + '.' + if_id, community, snmpver)
                    ifdata['if_descr'] = rs['value']
                    rs = mypysnmp.snmpget(host, OIDS['ifAlias'] + '.' + if_id, community, snmpver)
                    ifdata['if_alias'] = rs['value'] if rs['value'] else ''
                    rs = mypysnmp.snmpget(host, OIDS['ifName'] + '.' + if_id, community, snmpver)
                    ifdata['if_name'] = rs['value']
                    
                    try:
                        rs = mypysnmp.snmpget(host, (OIDS['ifAdminStatus'] + '.' + if_id, 
                                OIDS['ifOperStatus'] + '.' + if_id), community, snmpver, exception=True)
                    except mypysnmp.SnmpError:
                        ifdata['if_admst'] = None
                        ifdata['if_opst'] = None
                    else:
                        #if not rs['errorIndication']:
                        ifdata['if_admst'] = rs['value'][0]
                        ifdata['if_opst'] = rs['value'][1]
                        if not '1' in ifdata['if_admst'] or not '1' in ifdata['if_opst']:
                            warnings.append(u'Внимание: интерфейс выключен администратором (ifAdminStatus: {0}).'.format(ifdata['if_admst']))
                            warnings.append(u'Внимание: нет линка (ifOperStatus: {0})'.format(ifdata['if_opst']))
                    
                    poller.if_id = if_id
                    poller.if_name = if_id
                    ifdata['if_maxspd'] = poller.get_ifmaxspeed()
                    speed, units = poller._convert_speed(ifdata['if_maxspd'])
                    ifdata['if_maxspd_str'] = '{0} {1}'.format(speed, units)
                    
                    # rs = mypysnmp.snmpget(host, OIDS['ifInErrors'] + '.' + if_id, community, snmpver)
                    # if rs['value']:
                    #     poller.ifinerrors = int(rs['value'])
                    # else:
                    #     poller.ifinerrors = '?'
                    # rs = mypysnmp.snmpget(host, OIDS['ifOutErrors'] + '.' + if_id, community, snmpver, exception=True)
                    # if rs['value']:
                    #     poller.ifouterrors = int(rs['value'])
                    # else:
                    #     poller.ifouterrors = '?'
                    # ifdata['if_in_errors'] = poller.ifinerrors
                    # ifdata['if_out_errors'] = poller.ifouterrors
                    # if ifdata['if_in_errors'] > 0: warnings.append(u'Внимание: ненулевой счетчик ошибок на входе интерфейса: {0}.'.format(ifdata['if_in_errors']))
                    # if ifdata['if_out_errors'] > 0: warnings.append(u'Внимание: ненулевой счетчик ошибок на выходе интерфейса: {0}.'.format(ifdata['if_out_errors']))
                except mypysnmp.SnmpError as ei:
                    errors.append(ei)
                except snmp_ifrate.MyError as ei:
                    errors.append(ei)
                except ValueError as ei:
                    errors.append('Получены данные неизвестного формата: {}'.format(ei))
            else:
                host = form_host_query.cleaned_data['host']
                community = form_host_query.cleaned_data['community']
                snmpver = form_host_query.cleaned_data['snmpver']
                err_flag = True
                if not community:
                    community = COMMUNITY
                try:
                    poller = snmp_ifrate.SnmpIfInfo(host, community, snmpver)
                    poller.get_ifnametable()
                    err_flag = False
                except mypysnmp.SnmpError as ei:
                    errors.append(ei)
                except snmp_ifrate.MyError as ei:
                    errors.append(ei)
                except:
                    errors.append(u'Ошибка при получении информации об интерфейсах: {0}'.format(sys.exc_info()[1]))
                if err_flag:
                    errors.insert(0, u'Не могу подключиться к {0}!'.format(host))
                else:
                    interfaces = [i for i in sorted(poller.ifnametable, key=poller._sort_natural)]
                    choices = []
                    for i in interfaces:
                        choices.append([poller.ifnametable[i], i])
                    form_host_query = forms.HostQueryForm(request.GET, mychoices=choices)
        else:
            error = u'Правильно задайте имя (или адрес) устройства, строку community и версию протокола SNMP'
    else:
        # начальная страничка с формой:
        # counter
        # now = datetime.datetime.now()
        # ip_list = {}
        # for ip, v in online_count.items():
        #     for host, data in online_count[ip].items():
        #         if now > (data['ts'] + datetime.timedelta(seconds=2*data['upd_int'])):
        #             del online_count[ip][host]
        #         else:
        #             ip_list[ip] = [key for key, val in online_count[ip].items()]

        form_host_query = forms.HostQueryForm(None)
    
    return render_to_response('ifrate.html', locals(), context_instance=RequestContext(request))