Compare commits

..

No commits in common. "main" and "kunsi-mako-templating" have entirely different histories.

4 changed files with 22 additions and 110 deletions

View file

@ -1,41 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>${title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bootstrap.min.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🔥</text></svg>">
</head>
<body>
<div class="container">
<div class="page-header my-5" id="banner">
<div class="row">
<div class="col-lg-8">
<h1>Status: 🔥</h1>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="card text-white border-primary mb-3">
<div class="card-header d-flex justify-content-between align-items-center">
<h4>Something went wrong</h4>
</div>
<div class="card-body">
<p>
There was an error rendering the status page.
Admins have been notified.
</p>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
window.setTimeout(function() {
window.location.reload();
}, 10000);
</script>
</body>
</html>

View file

@ -1,3 +1,2 @@
Mako Mako
tomlkit tomlkit
requests

View file

@ -1,39 +1,29 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import logging import requests
import shutil import urllib3
import sys
from datetime import datetime
from os import environ from os import environ
import requests
import tomlkit import tomlkit
import urllib3
from mako.template import Template from mako.template import Template
urllib3.disable_warnings() urllib3.disable_warnings()
CONFIGFILE = environ.get('STATUSPAGE_CONFIG', 'config.toml') CONFIGFILE = environ.get('STATUSPAGE_CONFIG', 'config.toml')
class StatusPage: class StatusPage:
def get_api_result(self): def get_api_result(self):
if self.services: if self.services:
log.debug('services already exist, returning early')
return self.services return self.services
headers = {'Accept': 'application/json', 'X-HTTP-Method-Override': 'GET'} headers = {
'Accept': 'application/json',
'X-HTTP-Method-Override': 'GET'
}
requestbody = { requestbody = {
"attrs": [ "attrs": [ "name", "state", "last_check_result", "host_name", "display_name" ],
"name", "joins": [ "host.name", "host.state", "host.last_check_result", "host.vars" ],
"state",
"last_check_result",
"host_name",
"display_name",
],
"joins": ["host", "host.state", "host.last_check_result", "host.vars"],
"filter": self.config['filters']['services'], "filter": self.config['filters']['services'],
} }
@ -41,31 +31,25 @@ class StatusPage:
'{}/v1/objects/services'.format(self.config['icinga2_api']['baseurl']), '{}/v1/objects/services'.format(self.config['icinga2_api']['baseurl']),
headers=headers, headers=headers,
json=requestbody, json=requestbody,
auth=( auth=(self.config['icinga2_api']['username'], self.config['icinga2_api']['password']),
self.config['icinga2_api']['username'], verify=False
self.config['icinga2_api']['password'],
),
verify=False,
) )
self.logger.info(f'got http status code {r.status_code}') if (r.status_code == 200):
self.logger.debug(r.text)
if r.status_code == 200:
self.services = r.json()['results'] self.services = r.json()['results']
else: else:
r.raise_for_status() r.raise_for_status()
self.logger.info(f'got {len(self.services)} services from api')
return self.services return self.services
def prettify(self, text): def prettify(self, text):
for search, replace in self.config.get('prettify', {}).items(): for search, replace in self.config.get('prettify', {}).items():
text = text.replace(search, replace) text = text.replace(search, replace)
return text return text
def get_services_per_host(self): def get_services_per_host(self):
state_to_design_mapping = [ state_to_design_mapping = [
('success', 'OK'), ('success', 'OK'),
@ -76,11 +60,6 @@ class StatusPage:
result = {} result = {}
for service in self.get_api_result(): for service in self.get_api_result():
self.logger.info(
f'now processing {service["attrs"]["host_name"]} "{service["attrs"]["display_name"]}"'
)
self.logger.debug(service)
host = service['joins']['host']['vars']['pretty_name'] host = service['joins']['host']['vars']['pretty_name']
if host not in result: if host not in result:
@ -101,16 +80,14 @@ class StatusPage:
if state in (1, 2): if state in (1, 2):
self.ragecounter += state self.ragecounter += state
result[host]['services'][ result[host]['services'][self.prettify(service['attrs']['display_name'])] = {
self.prettify(service['attrs']['display_name'])
] = {
'badge': state_to_design_mapping[state][0], 'badge': state_to_design_mapping[state][0],
'state': state_to_design_mapping[state][1], 'state': state_to_design_mapping[state][1],
} }
self.logger.info(f'ragecounter is now {self.ragecounter}')
return result return result
def render_html(self, service_details): def render_html(self, service_details):
if self.ragecounter == 0: if self.ragecounter == 0:
mood = '🆗' mood = '🆗'
@ -119,45 +96,27 @@ class StatusPage:
else: else:
mood = '🔥' mood = '🔥'
self.logger.info('rendering output html') template = Template(filename=self.config['output'].get('template', 'template.html'))
start = datetime.now()
template = Template(
filename=self.config['output'].get('template', 'template.html')
)
output = template.render( output = template.render(
title=self.config['output'].get('page_title', 'Status Page'), title=self.config['output'].get('page_title', 'Status Page'),
mood=mood, mood=mood,
hosts=service_details, hosts=service_details,
) )
end = datetime.now()
self.logger.info(f'rendered in {(end-start).total_seconds():.09f}s')
with open(self.config['output']['filename'], 'w') as f: with open(self.config['output']['filename'], 'w') as f:
f.write(output) f.write(output)
def __init__(self): def __init__(self):
self.config = tomlkit.loads(open(CONFIGFILE).read()) self.config = tomlkit.loads(open(CONFIGFILE).read())
self.services = {} self.services = {}
self.ragecounter = 0 self.ragecounter = 0
self.logger = logging.getLogger('StatusPage')
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter(
'%(levelname)s {%(filename)s:%(lineno)d} %(message)s'
)
handler.setFormatter(formatter)
self.logger.addHandler(handler)
self.logger.setLevel(self.config.get('loglevel', 'INFO'))
if __name__ == "__main__": if __name__ == "__main__":
page = StatusPage() page = StatusPage()
service_details = page.get_services_per_host()
try: from pprint import pprint
service_details = page.get_services_per_host() pprint(service_details)
page.render_html(service_details)
except Exception as e: page.render_html(service_details)
shutil.copyfile('error.html', page.config['output']['filename'])
raise e

View file

@ -39,10 +39,5 @@
</div> </div>
% endfor % endfor
</div> </div>
<script type="text/javascript">
window.setTimeout(function() {
window.location.reload();
}, 30000);
</script>
</body> </body>
</html> </html>