Commit dcd4d754 authored by Daniele Venzano's avatar Daniele Venzano

Merge branch 'ext/devel/webui-fixes'

# Conflicts:
#	zoe_api/web/executions.py
#	zoe_api/web/static/zoe.css
#	zoe_api/web/templates/execution_inspect.html
parents 2be788f2 86469ea5
......@@ -142,7 +142,7 @@ class ExecutionCollectionAPI(RequestHandler):
All timestamps should be passed as number of seconds since the epoch (UTC timezone).
example: curl -u 'username:password' -X GET http://bf5:8080/api/0.6/execution?limit=1\&status=terminated
example: curl -u 'username:password' -X GET 'http://bf5:8080/api/0.6/execution?limit=1&status=terminated'
:return:
"""
......
......@@ -22,7 +22,7 @@
import json
import datetime
from jinja2 import Environment, FileSystemLoader, Markup
from jinja2 import Environment, FileSystemLoader, Markup, TemplateSyntaxError
from tornado.escape import squeeze, linkify, url_escape, xhtml_escape
import tornado.web
......@@ -120,8 +120,11 @@ class ZoeRequestHandler(tornado.web.RequestHandler):
template = self._jinja_env.get_template(template_name)
try:
html = self._render(template, **kwargs)
except Exception:
zoe_api.web.utils.error_page(self, 'Jinja2 template exception', 500)
except TemplateSyntaxError as e:
zoe_api.web.utils.error_page(self, 'Template syntax error at {}:{}:<br> {}'.format(e.name, e.lineno, e.message), 500)
return
except Exception as e:
zoe_api.web.utils.error_page(self, 'Jinja2 template exception: {}'.format(e), 500)
return
self.finish(html)
......
......@@ -33,7 +33,9 @@ class ExecutionDefineWeb(ZoeRequestHandler):
@catch_exceptions
def get(self):
"""Define a new execution."""
get_auth(self)
uid, role_ = get_auth(self)
if uid is None:
return self.redirect(self.get_argument('next', u'/login'))
self.render('execution_new.html')
......@@ -49,6 +51,8 @@ class ExecutionStartWeb(ZoeRequestHandler):
def post(self):
"""Start an execution."""
uid, role = get_auth(self)
if uid is None:
return self.redirect(self.get_argument('next', u'/login'))
app_descr_json = self.request.files['file'][0]['body'].decode('utf-8')
app_descr = json.loads(app_descr_json)
......@@ -70,6 +74,8 @@ class ExecutionRestartWeb(ZoeRequestHandler):
def get(self, execution_id: int):
"""Restart an already defined (and not running) execution."""
uid, role = get_auth(self)
if uid is None:
return self.redirect(self.get_argument('next', u'/login'))
e = self.api_endpoint.execution_by_id(uid, role, execution_id)
new_id = self.api_endpoint.execution_start(uid, role, e.name, e.description)
......@@ -88,6 +94,8 @@ class ExecutionTerminateWeb(ZoeRequestHandler):
def get(self, execution_id: int):
"""Terminate an execution."""
uid, role = get_auth(self)
if uid is None:
return self.redirect(self.get_argument('next', u'/login'))
success, message = self.api_endpoint.execution_terminate(uid, role, execution_id)
if not success:
......@@ -107,6 +115,8 @@ class ExecutionDeleteWeb(ZoeRequestHandler):
def get(self, execution_id: int):
"""Delete an execution."""
uid, role = get_auth(self)
if uid is None:
return self.redirect(self.get_argument('next', u'/login'))
success, message = self.api_endpoint.execution_delete(uid, role, execution_id)
if not success:
......@@ -126,14 +136,18 @@ class ExecutionInspectWeb(ZoeRequestHandler):
def get(self, execution_id):
"""Gather details about an execution."""
uid, role = get_auth(self)
if uid is None:
return self.redirect(self.get_argument('next', u'/login'))
e = self.api_endpoint.execution_by_id(uid, role, execution_id)
services_info, endpoints = self.api_endpoint.execution_endpoints(uid, role, e)
endpoints = self.api_endpoint.execution_endpoints(uid, role, e)[1]
template_vars = {
"e": e,
"services_info": services_info,
"endpoints": endpoints,
"services_info": services_info
}
self.render('execution_inspect.html', **template_vars)
......@@ -30,7 +30,7 @@ class RootWeb(ZoeRequestHandler):
@catch_exceptions
def get(self):
"""Home page without authentication."""
self.render('index.html')
self.redirect("/user")
class LoginWeb(ZoeRequestHandler):
......@@ -69,6 +69,8 @@ class HomeWeb(ZoeRequestHandler):
def get(self):
"""Home page with authentication."""
uid, role = get_auth(self)
if uid is None:
return self.redirect(self.get_argument('next', u'/login'))
if role == 'guest':
return self._aml_homepage(uid)
......
This diff is collapsed.
......@@ -32,6 +32,10 @@ table.app_list td {
padding-right: 1.5em;
}
table.app_list tr.even {
background-color: #F3FEEA;
}
div.status_line {
float: left;
}
......@@ -143,3 +147,17 @@ input {
section {
padding-bottom: 10px;
}
#loginbox {
width: 25em;
margin: 0 auto;
text-align: center;
}
#loginbox img {
width: 100%;
}
fieldset {
border: 0;
}
......@@ -49,7 +49,6 @@
document.write((bytes / Math.pow(k, i)).toPrecision(dm) + ' ' + sizes[i]);
}
</script>
<h1>Zoe - Analytics on demand</h1>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
......
{% extends "base.html" %}
{% block content %}
{{ super() }}
{% endblock %}
{% block footer %}
<p><a href="{{ reverse_url("home_user") }}">Home</a></p>
{{ super() }}
......
{% extends "base_user.html" %}
{% block title %}Inspect execution {{ e.name }}{% endblock %}
{% block content %}
<h1>Zoe - Analytics on demand</h1>
<h2>Detailed information for execution {{ e.name }}</h2>
<div id="contents">
<ul>
......@@ -24,14 +25,16 @@
{% endif %}
<div id="endpoints">
<h3>Endpoints</h3>
{% if endpoints|length > 0 %}
<h3>Endpoints:</h3>
{% endif %}
<ul>
{% for e in endpoints %}
<li><a href="{{ e[1] }}">{{ e[0] }}</a></li>
{% for endp in endpoints|sort %}
<li><a href="{{ endp[1] }}">{{ endp[0] }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>This execution does not have any active endpoint</p>
{% endif %}
</div>
<div id="container_list">
......@@ -43,15 +46,10 @@
<li class="container_name" id="{{ s['id'] }}">{{ s['name'] }}</li>
<ul>
<li>Zoe status: {{ s['status'] }}</li>
<li>Docker status: {{ s['backend_status'] }}</li>
<li>Backend status: {{ s['backend_status'] }}</li>
{% if s['error_message'] is not none %}
<li>Error: {{ s['error_message'] }}</li>
{% endif %}
{% if s['backend_status'] == 'started' %}
{% for p in s['description']['ports'] %}
<li><a> {{ p['name'] }} IP: {{ s['ip_address'] }}</a></li>
{% endfor %}
{% endif %}
</ul>
{% endfor %}
</ul>
......
{% extends "base_user.html" %}
{% block title %}New execution definition{% endblock %}
{% block content %}
<h1>Zoe - Analytics on demand</h1>
<h1>New execution</h1>
<h2>New execution</h2>
<form method="post" action="{{ reverse_url('execution_start') }}" enctype="multipart/form-data">
<label>Execution name: <input type="text" name="exec_name"></label><br>
<label>Application description: <input type="file" name="file"></label><br>
......
{% extends "base.html" %}
{% extends "base_user.html" %}
{% block title %}Home{% endblock %}
{% block content %}
<h1>Zoe - Analytics on demand</h1>
<div id="my_executions">
<h3>Executions</h3>
......@@ -40,7 +41,7 @@
{% else %}
<td><script>format_timestamp("{{ e.time_end }}")</script></td>
{% endif %}
{% if e.status == "running" or e.status == "submitted" or e.status == "scheduled" %}
{% if e.is_active %}
<td><a href="/executions/terminate/{{ e.id }}">Terminate</a></td>
{% else %}
<td><a href="/executions/restart/{{ e.id }}">Restart</a>,
......
<div id="main-container">
<div id="main">
<h1>
<img alt="zoe dummy login page" src="{{ static_url("img/logo.png") }}">
</h1>
<div id="login-form">
<form action="/login" method="post" id="login_form">
<fieldset>
<label for="username">Username</label>
<input autocapitalize="off" autocorrect="off" class="text-input" id="username" name="username" tabindex="1" type="text" value="">
</fieldset>
{% extends "base.html" %}
{% block title %}Login{% endblock %}
{% block content %}
<fieldset>
<label for="password">Password</label>
<input class="text-input" id="password" name="password" tabindex="2" type="password" value="">
</fieldset>
<fieldset>
<span class="errormessage">{{errormessage}}</span>
</fieldset>
<div id="loginbox">
<img alt="ZOE logo" src="{{ static_url("logo.svg") }}">
<div id="login-form">
<form action="/login" method="post" id="login_form">
<fieldset>
<label for="username">Username:</label>
<input autocapitalize="off" autocorrect="off" class="text-input" id="username" name="username" tabindex="1" type="text" value=""><br>
<div id="form_btn">
<input id="signin-btn" class="btn btn-blue" type="submit" value="Sign In" tabindex="3">
</div>
</form>
</div>
<label for="password">Password:</label>
<input class="text-input" id="password" name="password" tabindex="2" type="password" value="">
</fieldset>
<div id="form_btn">
<input id="signin-btn" class="btn btn-blue" type="submit" value="Login" tabindex="3">
</div>
</div>
</form>
</div>
</div>
{% endblock %}
......@@ -92,7 +92,7 @@ def get_auth(handler: ZoeRequestHandler):
log.info('Authentication done using cookie')
return uid, role
else:
handler.redirect(handler.get_argument('next', u'/login'))
return None, None
def error_page(handler: ZoeRequestHandler, error_message: str, status: int):
......
......@@ -22,7 +22,7 @@ from zoe_master.backends.kubernetes.api_client import KubernetesClient
from zoe_master.exceptions import ZoeStartExecutionRetryException, ZoeStartExecutionFatalException, ZoeException, ZoeNotEnoughResourcesException
from zoe_master.backends.service_instance import ServiceInstance
import zoe_master.backends.base
from zoe_master.backends.kubernetes.threads import KubernetesMonitor, KubernetesStateSynchronizer
from zoe_master.backends.kubernetes.threads import KubernetesMonitor
from zoe_master.stats import NodeStats, ClusterStats # pylint: disable=unused-import
log = logging.getLogger(__name__)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment