Example #1
0
    def _check_runner_alive(self):
        """Watchdog check: if runner is supposed to be running, is it alive and updating status?"""

        _log.debug('_check_runner_alive')

        if self.master.l2tpmanager is not None:
            if self.master.l2tpmanager.isRunning():
                _log.debug(
                    '_check_runner_alive: runner is active and should be updating rdf statistics'
                )

                st_root = helpers.get_status()
                polltime = st_root.getS(ns.lastPollTime, rdf.Datetime)
                pollage = datetime.datetime.utcnow() - polltime
                _log.debug('_check_runner_alive: poll age: %s' % pollage)
                if pollage > constants.WEBUI_WATCHDOG_POLL_AGE_THRESHOLD:
                    _log.error(
                        '_check_runner_alive: poll age (%s) is too large, runner seems to be stuck'
                        % pollage)
                    return False
                if pollage < datetime.timedelta(0, 0,
                                                0):  # some timezone problem
                    _log.error(
                        '_check_runner_alive: poll age (%s) is negative, considering this a failure'
                        % pollage)
                    return False
            elif self.master.l2tpmanager.isStarting():
                runner_starttime = self.master.l2tpmanager.startTime()
                if runner_starttime is None:
                    _log.error(
                        '_check_runner_alive: runner is starting and runner start time not available, assuming runner stuck in starting state and considering this as a failure'
                    )
                    return False

                runner_in_starting_state = datetime.datetime.utcnow(
                ) - runner_starttime
                if runner_in_starting_state > constants.WEBUI_WATCHDOG_RUNNER_STARTING_TIME_LIMIT:
                    _log.error(
                        '_check_runner_alive: runner is starting and runner start time stamp is too old (%s), assuming runner stuck in starting state and considering this as a failure'
                        % runner_in_starting_state)
                    return False
                if runner_in_starting_state < datetime.timedelta(
                        0, 0, 0):  # may be timezone problem
                    _log.error(
                        '_check_runner_alive: runner is starting and runner start time stamp age (%s) is negative, considering this a failure'
                        % runner_in_starting_state)
                    return False

            else:
                _log.debug(
                    '_check_runner_alive: runner is inactive, or active but not (yet) updating rdf statistics'
                )
        return True
Example #2
0
    def _check_runner_watchdog_status(self):
        """Watchdog check: runner watchdog status, and whether watchdog failures are indicated.

        Only process failures are considered actual problems here.

        Note that a separate runner restart check is made elsewhere; sometimes the recovery
        action is not to reboot (watchdog) but to e.g. restart runner (not watchdog directly).
        This function only checks for the watchdog part.
        """
        
        _log.debug('_check_runner_watchdog_status')

        st_root = helpers.get_status()  # may fail in rare occasions, does not matter
        if st_root.hasS(ns.processHealthCheck):
            if not st_root.getS(ns.processHealthCheck, rdf.Boolean):
                _log.error('_check_runner_watchdog_status: process health check failed, considering this a failure') 
                return False
        return True
Example #3
0
    def measure_network(self):
        st = helpers.get_status()
        
        if st.hasS(ns.publicInterface):
            pub_if_st = st.getS(ns.publicInterface, rdf.Type(ns.NetworkInterface))
            net_pubrx = pub_if_st.getS(ns.rxRateCurrent, rdf.Float)
            net_pubtx = pub_if_st.getS(ns.txRateCurrent, rdf.Float)
        else:
            net_pubrx, net_pubtx = 'U', 'U'

        if st.hasS(ns.privateInterface):
            priv_if_st = st.getS(ns.privateInterface, rdf.Type(ns.NetworkInterface))
            net_privrx = priv_if_st.getS(ns.rxRateCurrent, rdf.Float)
            net_privtx = priv_if_st.getS(ns.txRateCurrent, rdf.Float)
        else:
            net_privrx, net_privtx = 'U', 'U'

        return net_pubrx, net_pubtx, net_privrx, net_privtx
Example #4
0
    def _check_runner_watchdog_status(self):
        """Watchdog check: runner watchdog status, and whether watchdog failures are indicated.

        Only process failures are considered actual problems here.

        Note that a separate runner restart check is made elsewhere; sometimes the recovery
        action is not to reboot (watchdog) but to e.g. restart runner (not watchdog directly).
        This function only checks for the watchdog part.
        """

        _log.debug('_check_runner_watchdog_status')

        st_root = helpers.get_status(
        )  # may fail in rare occasions, does not matter
        if st_root.hasS(ns.processHealthCheck):
            if not st_root.getS(ns.processHealthCheck, rdf.Boolean):
                _log.error(
                    '_check_runner_watchdog_status: process health check failed, considering this a failure'
                )
                return False
        return True
Example #5
0
    def _check_runner_alive(self):
        """Watchdog check: if runner is supposed to be running, is it alive and updating status?"""

        _log.debug('_check_runner_alive')

        if self.master.l2tpmanager is not None:
            if self.master.l2tpmanager.isRunning():
                _log.debug('_check_runner_alive: runner is active and should be updating rdf statistics')

                st_root = helpers.get_status()
                polltime = st_root.getS(ns.lastPollTime, rdf.Datetime)
                pollage = datetime.datetime.utcnow() - polltime
                _log.debug('_check_runner_alive: poll age: %s' % pollage)
                if pollage > constants.WEBUI_WATCHDOG_POLL_AGE_THRESHOLD:
                    _log.error('_check_runner_alive: poll age (%s) is too large, runner seems to be stuck' % pollage)
                    return False
                if pollage < datetime.timedelta(0, 0, 0):   # some timezone problem
                    _log.error('_check_runner_alive: poll age (%s) is negative, considering this a failure' % pollage)
                    return False
            elif self.master.l2tpmanager.isStarting():
                runner_starttime = self.master.l2tpmanager.startTime()
                if runner_starttime is None:
                    _log.error('_check_runner_alive: runner is starting and runner start time not available, assuming runner stuck in starting state and considering this as a failure')
                    return False

                runner_in_starting_state = datetime.datetime.utcnow() - runner_starttime
                if runner_in_starting_state > constants.WEBUI_WATCHDOG_RUNNER_STARTING_TIME_LIMIT:
                    _log.error('_check_runner_alive: runner is starting and runner start time stamp is too old (%s), assuming runner stuck in starting state and considering this as a failure' % runner_in_starting_state)
                    return False
                if runner_in_starting_state < datetime.timedelta(0, 0, 0): # may be timezone problem
                    _log.error('_check_runner_alive: runner is starting and runner start time stamp age (%s) is negative, considering this a failure' % runner_in_starting_state)
                    return False

            else:
                _log.debug('_check_runner_alive: runner is inactive, or active but not (yet) updating rdf statistics')
        return True
Example #6
0
        def _get_health_info():
            state = None
            last_health_check = None
            failed_servers = None
            watchdog_action = None
            periodic_reboot = None
            try:
                st_root = helpers.get_status()

                mgr = self.master.l2tpmanager
                if mgr is None:
                    state = "inactive"
                else:
                    state = mgr.getState()

                # XXX: this is a bit inaccurate; we'd ideally want to list all interesting
                # parts of status like public address and mac, router and dns/wins health
                # status etc; but since this changes about once a minute, this will do.
                last_health_check = st_root.getS(ns.lastPollTime, rdf.Datetime)

                failed_servers = []
                if st_root.hasS(ns.serverStatuses):
                    for x in st_root.getS(ns.serverStatuses, rdf.Bag(rdf.Type(ns.ServerStatus))):
                        if x.hasS(ns.serverHealthCheck) and (not x.getS(ns.serverHealthCheck, rdf.Boolean)):
                            failed_servers.append(x.getUri())
                if st_root.hasS(ns.routerStatuses):
                    for x in st_root.getS(ns.routerStatuses, rdf.Bag(rdf.Type(ns.RouterStatus))):
                        if x.hasS(ns.routerHealthCheck) and (not x.getS(ns.routerHealthCheck, rdf.Boolean)):
                            failed_servers.append(x.getUri())

                watchdog_action = self.master.watchdog_action_is_pending()
                periodic_reboot = self.master.periodic_reboot_is_pending()
            except:
                _log.exception("cannot get status related info to poll state")

            return [state, last_health_check, failed_servers, watchdog_action, periodic_reboot]
Example #7
0
    def _do_runner(self):
        """Handle runner command line commands."""

        if len(sys.argv) == 1:
            self.usage_and_exit()
        cmd = sys.argv[1]

        opt = optparse.OptionParser(usage='%prog', version='%prog')
        opt.add_option('-r', '--rdf-file', help='RDF file instead of default database',
                       action='store', dest='rdf_file', type='string', metavar='<file>')
        opt.add_option('-m', '--mode', help='Mode for start',
                       action='store', dest='mode', type='string', metavar='<string>')
        opt.add_option('-i', '--import-path', dest='importpath')
        opt.add_option('-n', '--no-distro-restart', help='Prevent distro networking restart on runner stop',
                       action='store_true', dest='no_distro_restart', default=False)

        opt.set_defaults(rdf_file=None,
                         mode=None,
                         importpath='system')

        (opts, args) = opt.parse_args(sys.argv[2:])
        
        print 'Command = %s, Options: %s' % (cmd, str(opts))

        if opts.rdf_file is not None:
            print 'runner using database file: %s' % opts.rdf_file
            db.replace_database_with_file(opts.rdf_file, constants.RUNNER_TEMPORARY_SQLITE_DATABASE)

        if opts.mode is not None:
            mode = opts.mode
        else:
            mode = 'FULL'
            print 'no mode given, using %s' % mode

        importpath = 'system'
        if opts.importpath is not None:
            importpath = opts.importpath

        nodistrorestart = False
        if opts.no_distro_restart is not None and opts.no_distro_restart:
            nodistrorestart = True

        # XXX: these need rethinking, currently ripped from startstop.py.
        
        # XXX: this should probably be some command name => lambda system, to make command help etc easier

        # XXX: also need transactions here to make things reasonably fast (e.g. for rdf dumps)
        try:
            if mode == 'FULL':
                runner_mode = startstop._mode_full
            elif mode == 'NETWORK-ONLY':
                runner_mode = startstop._mode_network_only
            else:
                raise Exception('unknown mode: %s' % mode)

            _log.debug('starting runner in mode: %s' % runner_mode)
            r = startstop.L2tpRunner(mode=runner_mode, nodistrorestart=nodistrorestart, importpath=importpath)

            if cmd == 'run':
                r.create_pidfile()
                r.run()

            elif cmd == 'resetstate':
                # Set to a fresh node - this orphans all previous state
                return db.get_db().getRoot().setS(ns.l2tpDeviceStatus, rdf.Type(ns.L2tpDeviceStatus))

            elif cmd == 'dumpall':
                rd = rdfdumper.RdfDumper()
                print rd.dump_resource(db.get_db().getRoot(), escaped=True)
            
            elif cmd == 'dumpstatus':
                rd = rdfdumper.RdfDumper()
                print rd.dump_resource(db.get_db().getRoot().getS(ns.l2tpDeviceStatus), escaped=True)

            elif cmd == 'dumpconfig':
                rd = rdfdumper.RdfDumper()
                print rd.dump_resource(db.get_db().getRoot().getS(ns.l2tpDeviceConfig), escaped=True)
            
            elif cmd == 'status':
                st_root = helpers.get_status()

                st_last_str = 'unknown'
                if st_root.hasS(ns.lastStateUpdate):
                    st_last_str = st_root.getS(ns.lastStateUpdate, rdf.Datetime).isoformat()
                
                st_start_str = 'unknown'
                if st_root.hasS(ns.startTime):
                    st_start_str = st_root.getS(ns.startTime, rdf.Datetime).isoformat()

                st_stop_str = 'unknown'
                if st_root.hasS(ns.stopTime):
                    st_stop_str = st_root.getS(ns.stopTime, rdf.Datetime).isoformat()

                st_str = 'unknown'
                st = st_root.getS(ns.state)
                if st.hasType(ns.StateStarting):
                    st_str = 'starting'
                    subst = st.getS(ns.subState)
                    if subst.hasType(ns.StateStartingPreparing):
                        st_str += ' - preparing'
                    if subst.hasType(ns.StateStartingWaitingForDhcp):
                        st_str += ' - waiting for dhcp'
                    if subst.hasType(ns.StateStartingNetwork):
                        st_str += ' - starting network'
                    if subst.hasType(ns.StateStartingDaemons):
                        st_str += ' - starting daemons'
                elif st.hasType(ns.StateRunning):
                    st_str = 'running'
                elif st.hasType(ns.StateStopping):
                    st_str = 'stopping'
                elif st.hasType(ns.StateStopped):
                    st_str = 'stopped'

                st_ppp = 'unknown'
                if st_root.hasS(ns.pppDevices):
                    st_ppp = '%s' % len(helpers.get_ppp_devices())
            
                print 'STATUS: start=%s, stop=%s, last_update=%s, devs=%s, state: %s' % (st_start_str, st_stop_str, st_last_str, st_ppp, st_str)

            elif cmd == 'start':
                r.start()

            elif cmd == 'public-interface-test':
                # XXX
                pass

            elif cmd == 'private-interface-test':
                # XXX
                pass

            elif cmd == 'route-test':
                # XXX
                pass

            elif cmd == 'stop':
                r.stop()

            else:
                raise Exception('unknown command: %s' % cmd)

        except:
            _log.exception('l2tpgw-runner command "%s" failed.' % cmd)
            raise
Example #8
0
    def _update_public_private_ifaces(self, now, ifaces, pub_di, priv_di, first_time):
        def _update_iface(di, st):
            orxtime = st.getS(ns.rxLastChange, rdf.Datetime)
            nrxtime = now
            st.setS(ns.rxLastChange, rdf.Datetime, nrxtime)

            otxtime = st.getS(ns.txLastChange, rdf.Datetime)
            ntxtime = now
            st.setS(ns.txLastChange, rdf.Datetime, ntxtime)

            orxbytes = st.getS(ns.rxBytesCounter, rdf.Integer)
            nrxbytes = di.rxbytes
            nrxbytes = _wrap_check(orxbytes, nrxbytes)  # handle 4GiB wrap
            st.setS(ns.rxBytesCounter, rdf.Integer, nrxbytes)

            otxbytes = st.getS(ns.txBytesCounter, rdf.Integer)
            ntxbytes = di.txbytes
            ntxbytes = _wrap_check(otxbytes, ntxbytes)  # handle 4GiB wrap
            st.setS(ns.txBytesCounter, rdf.Integer, ntxbytes)

            orxpackets = st.getS(ns.rxPacketsCounter, rdf.Integer)
            nrxpackets = di.rxpackets
            st.setS(ns.rxPacketsCounter, rdf.Integer, nrxpackets)

            otxpackets = st.getS(ns.txPacketsCounter, rdf.Integer)
            ntxpackets = di.txpackets
            st.setS(ns.txPacketsCounter, rdf.Integer, ntxpackets)

            if first_time:
                st.setS(ns.rxRateCurrent, rdf.Float, 0.0)
                st.setS(ns.rxRateMaximum, rdf.Float, 0.0)
                st.setS(ns.txRateCurrent, rdf.Float, 0.0)
                st.setS(ns.txRateMaximum, rdf.Float, 0.0)
            else:
                rx_time = nrxtime - orxtime
                rx_secs = float(rx_time.seconds) + float(rx_time.microseconds / 1000000.0)
                if rx_secs > 0.0:
                    rx_rate = float(nrxbytes - orxbytes) / rx_secs
                else:
                    rx_rate = 0.0
                if rx_rate > st.getS(ns.rxRateMaximum, rdf.Float):
                    st.setS(ns.rxRateMaximum, rdf.Float, rx_rate)
                st.setS(ns.rxRateCurrent, rdf.Float, rx_rate)

                tx_time = ntxtime - otxtime
                tx_secs = float(tx_time.seconds) + float(tx_time.microseconds / 1000000.0)
                if tx_secs > 0.0:
                    tx_rate = float(ntxbytes - otxbytes) / tx_secs
                else:
                    tx_rate = 0.0
                if tx_rate > st.getS(ns.txRateMaximum, rdf.Float):
                    st.setS(ns.txRateMaximum, rdf.Float, tx_rate)
                st.setS(ns.txRateCurrent, rdf.Float, tx_rate)

            # NB: link and IP info are updated on every round; this benefits
            # very little but also costs very little...

            # update link info
            st.setS(ns.mtu, rdf.Integer, di.mtu)
            st.setS(ns.macAddress, rdf.String, di.mac)
            
            # update ip level info
            iface = ifaces.get_interface_by_name(di.devname)
            addrsub = iface.get_current_ipv4_address_info()
            if addrsub is None:
                _log.info('could not get address of interface %s, ignoring' % di.devname)
            else:
                st.setS(ns.ipAddress, rdf.IPv4AddressSubnet, addrsub)

        if pub_di is not None:
            pub_if_st = helpers.get_status().getS(ns.publicInterface, rdf.Type(ns.NetworkInterface))
            _update_iface(pub_di, pub_if_st)

        if priv_di is not None:
            priv_if_st = helpers.get_status().getS(ns.privateInterface, rdf.Type(ns.NetworkInterface))
            _update_iface(priv_di, priv_if_st)
Example #9
0
    def _update_public_private_ifaces(self, now, ifaces, pub_di, priv_di,
                                      first_time):
        def _update_iface(di, st):
            orxtime = st.getS(ns.rxLastChange, rdf.Datetime)
            nrxtime = now
            st.setS(ns.rxLastChange, rdf.Datetime, nrxtime)

            otxtime = st.getS(ns.txLastChange, rdf.Datetime)
            ntxtime = now
            st.setS(ns.txLastChange, rdf.Datetime, ntxtime)

            orxbytes = st.getS(ns.rxBytesCounter, rdf.Integer)
            nrxbytes = di.rxbytes
            nrxbytes = _wrap_check(orxbytes, nrxbytes)  # handle 4GiB wrap
            st.setS(ns.rxBytesCounter, rdf.Integer, nrxbytes)

            otxbytes = st.getS(ns.txBytesCounter, rdf.Integer)
            ntxbytes = di.txbytes
            ntxbytes = _wrap_check(otxbytes, ntxbytes)  # handle 4GiB wrap
            st.setS(ns.txBytesCounter, rdf.Integer, ntxbytes)

            orxpackets = st.getS(ns.rxPacketsCounter, rdf.Integer)
            nrxpackets = di.rxpackets
            st.setS(ns.rxPacketsCounter, rdf.Integer, nrxpackets)

            otxpackets = st.getS(ns.txPacketsCounter, rdf.Integer)
            ntxpackets = di.txpackets
            st.setS(ns.txPacketsCounter, rdf.Integer, ntxpackets)

            if first_time:
                st.setS(ns.rxRateCurrent, rdf.Float, 0.0)
                st.setS(ns.rxRateMaximum, rdf.Float, 0.0)
                st.setS(ns.txRateCurrent, rdf.Float, 0.0)
                st.setS(ns.txRateMaximum, rdf.Float, 0.0)
            else:
                rx_time = nrxtime - orxtime
                rx_secs = float(rx_time.seconds) + float(
                    rx_time.microseconds / 1000000.0)
                if rx_secs > 0.0:
                    rx_rate = float(nrxbytes - orxbytes) / rx_secs
                else:
                    rx_rate = 0.0
                if rx_rate > st.getS(ns.rxRateMaximum, rdf.Float):
                    st.setS(ns.rxRateMaximum, rdf.Float, rx_rate)
                st.setS(ns.rxRateCurrent, rdf.Float, rx_rate)

                tx_time = ntxtime - otxtime
                tx_secs = float(tx_time.seconds) + float(
                    tx_time.microseconds / 1000000.0)
                if tx_secs > 0.0:
                    tx_rate = float(ntxbytes - otxbytes) / tx_secs
                else:
                    tx_rate = 0.0
                if tx_rate > st.getS(ns.txRateMaximum, rdf.Float):
                    st.setS(ns.txRateMaximum, rdf.Float, tx_rate)
                st.setS(ns.txRateCurrent, rdf.Float, tx_rate)

            # NB: link and IP info are updated on every round; this benefits
            # very little but also costs very little...

            # update link info
            st.setS(ns.mtu, rdf.Integer, di.mtu)
            st.setS(ns.macAddress, rdf.String, di.mac)

            # update ip level info
            iface = ifaces.get_interface_by_name(di.devname)
            addrsub = iface.get_current_ipv4_address_info()
            if addrsub is None:
                _log.info('could not get address of interface %s, ignoring' %
                          di.devname)
            else:
                st.setS(ns.ipAddress, rdf.IPv4AddressSubnet, addrsub)

        if pub_di is not None:
            pub_if_st = helpers.get_status().getS(
                ns.publicInterface, rdf.Type(ns.NetworkInterface))
            _update_iface(pub_di, pub_if_st)

        if priv_di is not None:
            priv_if_st = helpers.get_status().getS(
                ns.privateInterface, rdf.Type(ns.NetworkInterface))
            _update_iface(priv_di, priv_if_st)
Example #10
0
    def measure_and_update(self, update_rrd=True, update_rdf=True, quick=False):
        """Update all measurements.

        To minimize rrd load on the system, it is preferable to update all measurements
        in one go.  Further, if asynchronous updating is desired, separate rrd files
        need to be used anyway.

        We also update some statistics to a RDF status branch for statistics that are not
        protocol related (e.g. CPU usage).  This is so that the web UI can get access to
        this sort of information even when the runner is not active.  Admittedly this is
        not a very clean thing to do.
        """
    
        # It is important to run time-consuming system checks inside @untransact to
        # minimize the time RDF database access is locked.
        
        timestamp = datetime.datetime.utcnow()
        timeval = int(time.mktime(timestamp.timetuple()))  # XXX: round?

        # these values can be extracted regardless of l2tp-runner state
        cpu_load = self.measure_cpuload()
        if quick:
            # quick is used in boot to minimize postinit time
            cpu_usage = 0
        else:
            cpu_usage = self.measure_vmstat()
        cpu_count = self.measure_cpuinfo()
        disk_total, disk_avail = self.measure_diskstats()
        mem_total, mem_free, swap_total, swap_free = self.measure_meminfo()
        mem_used = mem_total - mem_free
        swap_used = swap_total - swap_free
        net_pubrx, net_pubtx, net_privrx, net_privtx = self.measure_network()

        def _nusr_filter(dev):
            if dev.hasS(ns.restrictedConnection) and dev.getS(ns.restrictedConnection, rdf.Boolean):
                return False
            # XXX: We'd like to ignore inactive devices, but this wasn't reliable enough
            #if dev.hasS(ns.deviceActive) and not dev.getS(ns.deviceActive, rdf.Boolean):
            #    return False
            if dev.hasS(ns.connectionType):
                if dev.getS(ns.connectionType).hasType(ns.NormalUser):
                    return True
            return False

        def _susr_filter(dev):
            if dev.hasS(ns.restrictedConnection) and dev.getS(ns.restrictedConnection, rdf.Boolean):
                return False
            # XXX: We'd like to ignore inactive devices, but this wasn't reliable enough
            #if dev.hasS(ns.deviceActive) and not dev.getS(ns.deviceActive, rdf.Boolean):
            #    return False
            if dev.hasS(ns.connectionType):
                conntype = dev.getS(ns.connectionType)
                if conntype.hasType(ns.SiteToSiteClient) or conntype.hasType(ns.SiteToSiteServer):
                    return True
            return False

        # user related data is only reliable if l2tp-runner is in state "running"
        try:
            st = helpers.get_status().getS(ns.state)
            if not st.hasType(ns.StateRunning):
                raise Exception('State not running')

            nusr_count, \
                        nusr_rxtotal, nusr_txtotal, \
                        nusr_rxavg, nusr_txavg, \
                        nusr_rxmax, nusr_txmax = self.measure_ppp_devs(_nusr_filter)

            susr_count, \
                        susr_rxtotal, susr_txtotal, \
                        susr_rxavg, susr_txavg, \
                        susr_rxmax, susr_txmax = self.measure_ppp_devs(_susr_filter)
        except:
            nusr_count, \
                        nusr_rxtotal, nusr_txtotal, \
                        nusr_rxavg, nusr_txavg, \
                        nusr_rxmax, nusr_txmax = ['U']*7
            
            susr_count, \
                        susr_rxtotal, susr_txtotal, \
                        susr_rxavg, susr_txavg, \
                        susr_rxmax, susr_txmax = ['U']*7

        vals = [ timeval,
                 cpu_load,
                 cpu_usage,
                 cpu_count,
                 disk_total,
                 disk_avail,
                 mem_total,
                 mem_used,
                 swap_total,
                 swap_used,
                 net_pubrx,
                 net_pubtx,
                 net_privrx,
                 net_privtx,
                 nusr_count,
                 nusr_rxtotal,
                 nusr_txtotal,
                 nusr_rxavg,
                 nusr_txavg,
                 nusr_rxmax,
                 nusr_txmax,
                 susr_count,
                 susr_rxtotal,
                 susr_txtotal,
                 susr_rxavg,
                 susr_txavg,
                 susr_rxmax,
                 susr_txmax ]
                 
        valstr = map(lambda x: str(x), vals)

        @db.untransact()
        def _run_rrd():
            # update rrd
            run_command([
                constants.CMD_RRDTOOL,
                'update', self.filename,
                ':'.join(valstr)
                ], retval=runcommand.FAIL)

        if update_rrd:
            _run_rrd()

        if update_rdf:
            st = helpers.get_global_status()
            st.setS(ns.cpuUsage, rdf.Float, float(cpu_usage))  # percents
            st.setS(ns.cpuCount, rdf.Integer, int(cpu_count))  # count
            st.setS(ns.diskUsage, rdf.Float, (float(disk_total) - float(disk_avail)) / float(disk_total) * 100.0)  # percents
            st.setS(ns.diskTotal, rdf.Float, float(disk_total))  # fake megs
            st.setS(ns.memoryUsage, rdf.Float, float(mem_used) / float(mem_total) * 100.0)  # percents
            st.setS(ns.memoryTotal, rdf.Integer, int(mem_total))  # kilobytes
            if swap_total > 0:
                st.setS(ns.swapUsage, rdf.Float, float(swap_used) / float(swap_total) * 100.0)  # percents
            else:
                st.setS(ns.swapUsage, rdf.Float, 0.0)
            st.setS(ns.swapTotal, rdf.Integer, int(swap_total))  # kilobytes
Example #11
0
def _update_snmp():
    """Update SNMP data."""

    from codebay.l2tpserver import licensemanager
    from codebay.l2tpserver import helpers
    from codebay.l2tpserver.webui import uihelpers

    now = datetime.datetime.utcnow()
    st = helpers.get_status()
    global_st = helpers.get_global_status()
    license_info = helpers.get_license_info()

    def _timeticks(td):
        return int(helpers.timedelta_to_seconds(td) * 100.0)

    def _timestamp(dt):
        return datatypes.encode_datetime_to_iso8601_subset(dt)

    def _get_management_conn():
        # XXX: not the best place for this
        if global_st.hasS(ns.managementServerConnection):
            if global_st.getS(ns.managementServerConnection, rdf.Boolean):
                return 1
        return 0
        
    vals = {}

    lm = licensemanager.LicenseMonitor()
    usr_count, usr_limit, usr_limit_leeway, s2s_count, s2s_limit, s2s_limit_leeway = None, None, None, None, None, None
    try:
        usr_count, usr_limit, usr_limit_leeway, s2s_count, s2s_limit, s2s_limit_leeway = lm.count_both_users()
    except:
        _log.exception('cannot get ppp counts for snmp')

    # XXX: this sharing of status code is quite unclean; see uihelpers.get_status_and_substatus() for suggestions
    health_errors = 0
    try:
        status_class, status_text, substatus_class, substatus_text, status_ok = uihelpers.get_status_and_substatus()
        if status_ok:
            health_errors = 0
        else:
            health_errors = 1
    except:
        _log.exception('cannot determine health errors')
    
    for k, l in [ ('vpneaseHealthCheckErrors',       lambda: health_errors),
                  ('vpneaseUserCount',               lambda: usr_count),
                  ('vpneaseSiteToSiteCount',         lambda: s2s_count),
                  ('vpneaseLastMaintenanceReboot',   lambda: _timestamp(helpers.read_datetime_marker_file(constants.LAST_AUTOMATIC_REBOOT_MARKER_FILE))),
                  ('vpneaseNextMaintenanceReboot',   lambda: _timestamp(uihelpers.compute_periodic_reboot_time())),
                  ('vpneaseLastSoftwareUpdate',      lambda: _timestamp(helpers.read_datetime_marker_file(constants.LAST_SUCCESSFUL_UPDATE_MARKER_FILE))),
                  ('vpneaseSoftwareVersion',         lambda: helpers.get_product_version(cache=True, filecache=True)),
                  ('vpneaseCpuUsage',                lambda: int(global_st.getS(ns.cpuUsage, rdf.Float))),
                  ('vpneaseMemoryUsage',             lambda: int(global_st.getS(ns.memoryUsage, rdf.Float))),
                  ('vpneaseVirtualMemoryUsage',      lambda: int(global_st.getS(ns.swapUsage, rdf.Float))),
                  ('vpneaseServiceUptime',           lambda: _timeticks(now - st.getS(ns.startTime, rdf.Datetime))),
                  ('vpneaseHostUptime',              lambda: _timeticks(datetime.timedelta(0, helpers.get_uptime(), 0))),
                  ('vpneasePublicAddress',           lambda: st.getS(ns.publicInterface, rdf.Type(ns.NetworkInterface)).getS(ns.ipAddress, rdf.IPv4AddressSubnet).getAddress().toString()),
                  ('vpneasePublicSubnet',            lambda: st.getS(ns.publicInterface, rdf.Type(ns.NetworkInterface)).getS(ns.ipAddress, rdf.IPv4AddressSubnet).getMask().toString()),
                  ('vpneasePublicMac',               lambda: st.getS(ns.publicInterface, rdf.Type(ns.NetworkInterface)).getS(ns.macAddress, rdf.String)),
                  ('vpneasePrivateAddress',          lambda: st.getS(ns.privateInterface, rdf.Type(ns.NetworkInterface)).getS(ns.ipAddress, rdf.IPv4AddressSubnet).getAddress().toString()),
                  ('vpneasePrivateSubnet',           lambda: st.getS(ns.privateInterface, rdf.Type(ns.NetworkInterface)).getS(ns.ipAddress, rdf.IPv4AddressSubnet).getMask().toString()),
                  ('vpneasePrivateMac',              lambda: st.getS(ns.privateInterface, rdf.Type(ns.NetworkInterface)).getS(ns.macAddress, rdf.String)),
                  ('vpneaseLicenseKey',              lambda: license_info.getS(ns_ui.licenseKey, rdf.String)),
                  ('vpneaseLicenseString',           lambda: license_info.getS(ns_ui.licenseString, rdf.String)),
                  ('vpneaseLicenseUserLimit',        lambda: usr_limit),
                  ('vpneaseLicenseSiteToSiteLimit',  lambda: s2s_limit),
                  ('vpneaseMaintenanceReboots',      lambda: global_st.getS(ns.periodicReboots, rdf.Integer)),
                  ('vpneaseWatchdogReboots',         lambda: global_st.getS(ns.watchdogReboots, rdf.Integer)),
                  ('vpneaseLicenseServerConnection', _get_management_conn),
                  ]:
        try:
            val = l()
            if val is not None:
                vals[k] = val
        except:
            # these are expected in several cases, so don't spew too much log about them
            # XXX: it would be better if the checkers would figure these out for themselves
            # (when a value is expected and when not)
            _log.info('failed to get snmp value for key %s' % k)
            #_log.exception('failed to get snmp value for key %s' % k)
                  
    keys = vals.keys()
    keys.sort()
    res = ''
    for k in keys:
        res += '%s=%s\n' % (k, vals[k])

    # to ASCII, escaping any non-ASCII chars with XML escapes
    res = res.encode('US-ASCII', 'xmlcharrefreplace')

    f = None
    try:
        f = open(constants.SNMP_DATA_FILE, 'wb')
        f.write(res)
    finally:
        if f:
            f.close()
        f = None