Open textbook opened 7 years ago
Draft service to fetch status of all apps in a space (note need to update HeaderMixin
to not mangle any Authorization
token):
"""Defines the Cloud Foundry service integration."""
import logging
import requests
from .auth import HeaderMixin
from .core import CustomRootMixin, Service
from .utils import naturaldelta
logger = logging.getLogger(__name__)
class CloudFoundry(CustomRootMixin, HeaderMixin, Service):
AUTH_HEADER = 'Authorization'
FRIENDLY_NAME = 'CF Space'
REQUIRED = {'space_id'}
TEMPLATE = 'cf-status-section'
def __init__(self, *, space_id, api_token, **kwargs):
kwargs['api_token'] = 'bearer {}'.format(api_token)
super().__init__(**kwargs)
self.space_id = space_id
def update(self):
logger.debug('fetching Cloud Foundry space data')
response = requests.get(
self.url_builder(
'/v2/spaces/{space}/summary',
params={'space': self.space_id},
),
verify=False,
headers=self.headers,
)
if response.status_code == 200:
return self.format_data(response.json())
logger.error('failed to update Cloud Foundry space data')
return {}
def format_data(self, data):
apps = [self.app_status(app) for app in data.get('apps', [])]
while len(apps) < 4:
apps.append(dict(name='', outcome='cancelled', uptime=None))
return dict(
name=data.get('name', '<no name>'),
apps=apps[:4],
health='error' if any(app['outcome'] == 'crashed' for app in apps) else 'ok'
)
def app_status(self, app):
guid = app['guid']
name = app['name']
state = app['state']
if state == 'STARTED':
return self.detailed_app_status(guid, name)
return dict(
outcome='crashed',
name=name,
uptime=None,
)
def detailed_app_status(self, guid, name):
logger.debug('fetching status of %r', name)
response = requests.get(
self.url_builder(
'/v2/apps/{app}/stats',
params={'app': guid},
),
headers=self.headers,
verify=False,
)
if response.status_code == 200:
return self.format_app(response.json())
logger.error('failed to update status of %r', name)
return dict(name=name, outcome='cancelled', uptime=None)
def format_app(self, data):
first_key = list(data.keys())[0]
stats = data[first_key]['stats']
return dict(
outcome='passed',
name=stats['name'],
uptime='up for {}'.format(naturaldelta(stats['uptime'])),
)
<section class="pane short-pane kudos-pane">
{% for _ in range(4) %}
<div class="pane-item build-outcome">
<span class="item-title name"></span>
<br/>
<span class="uptime"></span>
</div>
{% endfor %}
</section>
function cloud_foundry(pane, data) {
if (data.apps) {
updateItems(pane, data.apps, '.build-outcome', function (element, data) {
element.removeClass('passed failed crashed cancelled working');
element.addClass(data.outcome);
['name', 'uptime'].forEach(function (attr) {
element.children('.' + attr).text(data[attr]);
});
});
}
}
It seems like the OAuth token you can get from the CLI will expire and you'll end up with 503s. Perhaps the token can be periodically refreshed. Also it should be more obvious from the frontend that the data is now out of date (textbook/flash#34).
Give information on the health and metrics (if available) of any CF apps