def count_both_users(self): """Count both normal and site-to-site users at the same time. This is useful for e.g. Ajax code to minimize RDF impact. """ licinfo = helpers.get_license_info() limit = licinfo.getS(ns_ui.maxNormalConnections, rdf.Integer) limit_leeway = self._add_leeway(limit) s2s_limit = licinfo.getS(ns_ui.maxSiteToSiteConnections, rdf.Integer) s2s_limit_leeway = self._add_leeway(s2s_limit) count, s2s_count = 0, 0 for dev in helpers.get_ppp_devices(): try: # XXX: we'd ideally want to ignore inactive devices, but that did not # seem reliable enough if dev.getS(ns.connectionType).hasType(ns.NormalUser): if not dev.getS(ns.restrictedConnection, rdf.Boolean): count += 1 else: # XXX: assume it is site-to-site, minimize rdf impact if not dev.getS(ns.restrictedConnection, rdf.Boolean): s2s_count += 1 except: _log.exception('count_both_users: failed') return count, limit, limit_leeway, s2s_count, s2s_limit, s2s_limit_leeway
def check_license_validity(self): """Check that license is valid at this time. License validity is only checked when the connection is being formed. If the license expires after that, connections are not severed. Note that validity here is a limited period, even for continuous subscriptions. The server is expected to reidentify periodically to extend the license validity time. """ try: licinfo = helpers.get_license_info() val_start = licinfo.getS(ns_ui.validityStart, rdf.Datetime) val_end = licinfo.getS(ns_ui.validityEnd, rdf.Datetime) now = datetime.datetime.utcnow() if (now >= val_start) and (now <= val_end): return True _log.warning('license is not valid: validity_start=%s, validity_end=%s, now=%s' % (val_start, val_end, now)) return False except: _log.exception('cannot check license validity, assuming invalid') return False return False # just in case
def check_license_validity(self): """Check that license is valid at this time. License validity is only checked when the connection is being formed. If the license expires after that, connections are not severed. Note that validity here is a limited period, even for continuous subscriptions. The server is expected to reidentify periodically to extend the license validity time. """ try: licinfo = helpers.get_license_info() val_start = licinfo.getS(ns_ui.validityStart, rdf.Datetime) val_end = licinfo.getS(ns_ui.validityEnd, rdf.Datetime) now = datetime.datetime.utcnow() if (now >= val_start) and (now <= val_end): return True _log.warning( 'license is not valid: validity_start=%s, validity_end=%s, now=%s' % (val_start, val_end, now)) return False except: _log.exception('cannot check license validity, assuming invalid') return False return False # just in case
def invalidate_license_status(self): """Set current license state as close to 'invalid' as possible. This is called whenever license is not deemed valid, and will disable connectivity. """ _log.info("invalidate_license_status() called, invalidating license") lic = helpers.get_license_info() # XXX: recheck from protocol is currently for valid licenses only; # what value to use here? change protocol? now = datetime.datetime.utcnow() recheck = now + datetime.timedelta(0, 60 * 60, 0) # 1 hour lic.setS(ns_ui.maxNormalConnections, rdf.Integer, 0) lic.setS(ns_ui.maxSiteToSiteConnections, rdf.Integer, 0) lic.setS(ns_ui.validityStart, rdf.Datetime, now) lic.setS(ns_ui.validityEnd, rdf.Datetime, now) lic.setS(ns_ui.validityRecheckLatest, rdf.Datetime, recheck) lic.setS(ns_ui.licenseString, rdf.String, "") lic.setS(ns_ui.licenseKey, rdf.String, "") lic.setS(ns_ui.isDemoLicense, rdf.Boolean, False) lic.setS(ns_ui.demoValidityStart, rdf.Datetime, now) lic.setS(ns_ui.demoValidityEnd, rdf.Datetime, now)
def _get_license_info(): # XXX: count both kinds of users at the same time lm = licensemanager.LicenseMonitor() count, limit, limit_leeway, count_s2s, limit_s2s, limit_leeway_s2s = lm.count_both_users() license_name = None try: license_name = helpers.get_license_info().getS(ns_ui.licenseString, rdf.String) except: _log.exception("cannot get license name") lic_valid = None try: lm = licensemanager.LicenseMonitor() lic_valid = lm.check_license_validity() except: _log.exception("cannot determine license validity, ignoring") have_connection = None try: # XXX: not the same as being actually connected in the sense of # sending Version + Identify, but a fair approximation for now have_connection = self.master.managementconnection.is_active() except: _log.exception("cannot determine whether we have management connection, ignoring") return [count, limit, count_s2s, limit_s2s, license_name, lic_valid, have_connection]
def _webui_get_round_limit(self, nsname): try: limit = helpers.get_license_info().getS(nsname, rdf.Integer) except: _log.exception('cannot get limit') limit = 0 limit_round = (limit + 4) / 5 * 5 # round up to nearest 5 if limit_round < 5: limit_round = 5 return limit, limit_round
def check_demo_license(self): """Check whether license is a demo license and return demo parameters if so.""" try: licinfo = helpers.get_license_info() is_demo = licinfo.getS(ns_ui.isDemoLicense, rdf.Boolean) if not is_demo: return False, None, None else: demo_expiry = licinfo.getS(ns_ui.demoValidityEnd, rdf.Datetime) demo_left = demo_expiry - datetime.datetime.utcnow() if demo_left < datetime.timedelta(0, 0, 0): demo_left = datetime.timedelta(0, 0, 0) return True, demo_expiry, demo_left except: _log.exception('cannot check demo license') return False, None, None
def update_license_info(self, res): _log.debug("identify response dict: %s" % res) lic = helpers.get_license_info() # get old license parameters first got_old = True try: old_max_normal = lic.getS(ns_ui.maxNormalConnections, rdf.Integer) old_max_s2s = lic.getS(ns_ui.maxSiteToSiteConnections, rdf.Integer) old_val_start = lic.getS(ns_ui.validityStart, rdf.Datetime) old_val_end = lic.getS(ns_ui.validityEnd, rdf.Datetime) old_recheck = lic.getS(ns_ui.validityRecheckLatest, rdf.Datetime) old_lic_string = lic.getS(ns_ui.licenseString, rdf.String) old_is_demo = lic.getS(ns_ui.isDemoLicense, rdf.Boolean) old_demo_val_start = lic.getS(ns_ui.demoValidityStart, rdf.Datetime) old_demo_val_end = lic.getS(ns_ui.demoValidityEnd, rdf.Datetime) _log.debug( "old license parameters: normal=%s, s2s=%s, valstart=%s, valend=%s, recheck=%s, string=%s, isdemo=%s, demostart=%s, demoend=%s" % ( old_max_normal, old_max_s2s, old_val_start, old_val_end, old_recheck, old_lic_string, old_is_demo, old_demo_val_start, old_demo_val_end, ) ) except: _log.exception("cannot get old license parameters") got_old = False # get new license parameters from the result got_new = True try: new_max_normal = res["licenseMaxRemoteAccessConnections"] new_max_s2s = res["licenseMaxSiteToSiteConnections"] new_val_start = res["licenseValidityStart"] new_val_end = res["licenseValidityEnd"] new_recheck = res["licenseRecheckLatestAt"] new_lic_string = res["licenseString"] new_lic_key = helpers.get_ui_config().getS( ns_ui.licenseKey, rdf.String ) # XXX: there is a slight race here, but we don't have the license key present in the request message here new_is_demo = res["isDemoLicense"] new_demo_val_start = res["demoValidityStart"] new_demo_val_end = res["demoValidityEnd"] _log.debug( "new license parameters: normal=%s, s2s=%s, valstart=%s, valend=%s, recheck=%s, string=%s, isdemo=%s, demostart=%s, demoend=%s" % ( new_max_normal, new_max_s2s, new_val_start, new_val_end, new_recheck, new_lic_string, new_is_demo, new_demo_val_start, new_demo_val_end, ) ) except: _log.exception("cannot get new license parameters") got_new = False # get licenseStatus from protocol: it governs our basic actions license_status = None try: license_status = res["licenseStatus"] except: _log.exception("cannot get licenseStatus from identify result") if got_new: # check licenseStatus values and act accordingly if license_status == "VALID": _log.info("license status is valid (key '%s')" % new_lic_key) lic.setS(ns_ui.maxNormalConnections, rdf.Integer, new_max_normal) lic.setS(ns_ui.maxSiteToSiteConnections, rdf.Integer, new_max_s2s) lic.setS(ns_ui.validityStart, rdf.Datetime, new_val_start) lic.setS(ns_ui.validityEnd, rdf.Datetime, new_val_end) lic.setS(ns_ui.validityRecheckLatest, rdf.Datetime, new_recheck) lic.setS(ns_ui.licenseString, rdf.String, new_lic_string) lic.setS(ns_ui.licenseKey, rdf.String, new_lic_key) lic.setS(ns_ui.isDemoLicense, rdf.Boolean, new_is_demo) lic.setS(ns_ui.demoValidityStart, rdf.Datetime, new_demo_val_start) lic.setS(ns_ui.demoValidityEnd, rdf.Datetime, new_demo_val_end) elif license_status == "DISABLED": _log.info("license status is disabled (key '%s')" % new_lic_key) self.invalidate_license_status() elif license_status == "UNKNOWN": _log.info("license status is unknown (key '%s')" % new_lic_key) self.invalidate_license_status() else: _log.warning("license status is unexpected: %s (key '%s')" % (license_status, new_lic_key)) self.invalidate_license_status() else: _log.warning("cannot find new license parameters") self.invalidate_license_status()
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