You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.0 KiB
Python

8 years ago
from datetime import timedelta, datetime
import lcoreapi
from django.conf import settings
from django.core.mail import mail_admins
import logging
cluster_messages = settings.LAMBDAINST_CLUSTER_MESSAGES
lcore_settings = settings.LCORE
LCORE_BASE_URL = lcore_settings.get('BASE_URL')
LCORE_API_KEY = lcore_settings['API_KEY']
LCORE_API_SECRET = lcore_settings['API_SECRET']
LCORE_SOURCE_ADDR = lcore_settings.get('SOURCE_ADDRESS')
LCORE_INST_SECRET = lcore_settings['INST_SECRET']
# The default is to log the exception and only raise it if we cannot show
# the previous value or a default value instead.
LCORE_RAISE_ERRORS = bool(lcore_settings.get('RAISE_ERRORS', False))
LCORE_CACHE_TTL = lcore_settings.get('CACHE_TTL', 60)
if isinstance(LCORE_CACHE_TTL, int):
LCORE_CACHE_TTL = timedelta(seconds=LCORE_CACHE_TTL)
assert isinstance(LCORE_CACHE_TTL, timedelta)
core_api = lcoreapi.API(LCORE_API_KEY, LCORE_API_SECRET, LCORE_BASE_URL)
class APICache:
""" Cache data for a time, try to update and silence errors.
Outdated data is not a problem.
"""
def __init__(self, ttl=None, initial=None):
self.cache_date = datetime.fromtimestamp(0)
self.ttl = ttl or LCORE_CACHE_TTL
self.has_cached_value = initial is not None
self.cached = initial() if initial else None
def query(self, wrapped, *args, **kwargs):
try:
return wrapped(*args, **kwargs)
except lcoreapi.APIError:
logger = logging.getLogger('django.request')
logger.exception("core api error")
if LCORE_RAISE_ERRORS:
raise
if not self.has_cached_value:
# We only return a default value if we were given one.
# Prevents returning an unexpected None.
raise
# Return previous value
return self.cached
def __call__(self, wrapped):
def wrapper(*args, **kwargs):
if self.cache_date > (datetime.now() - self.ttl):
return self.cached
self.cached = self.query(wrapped, *args, **kwargs)
# New results *and* errors are cached
self.cache_date = datetime.now()
return self.cached
return wrapper
@APICache(initial=lambda: 0)
def current_active_sessions():
return core_api.get(core_api.info['current_instance'] + '/sessions', active=True)['total_count']
@APICache(initial=lambda: [])
def get_locations():
gateways = core_api.get('/gateways/')
locations = {}
for gw in gateways.list_iter():
cc = gw['cluster_name']
if cc not in locations:
locations[cc] = dict(
servers=0,
bandwidth=0,
hostname='gw.' + cc + '.204vpn.net',
country_code=cc,
message=cluster_messages.get(cc),
)
locations[cc]['servers'] += 1
locations[cc]['bandwidth'] += gw['bandwidth']
locations = sorted(locations.items(), key=lambda x: x[1]['country_code'])
return locations