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
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
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
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
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
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]
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
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)
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)
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
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