Skip to content
Snippets Groups Projects
Commit 9b4be12a authored by Tim Fechner's avatar Tim Fechner
Browse files

Implement basic event stream functionality

parent ae4e0228
Branches
No related tags found
No related merge requests found
Pipeline #
$(function() {
// ATTENTION: set the token before importing this script
var socket = new WebSocket('ws://localhost:8002/all_events/' + token);
// Get Salt's "real time" event stream.
socket.onopen = function() {
socket.send('websocket client ready');
console.log('Connected!');
$('#conn_status').html('<i class="fa fa-fw fa-check"></i> Connected!');
};
// Other handlers
socket.onerror = function(e) {
console.debug('Error!', e);
$('#conn_status').html('<i class="fa fa-fw fa-times"></i> Connection failed!');
};
// e.data represents Salt's "real time" event data as serialized JSON.
socket.onmessage = function(e) {
console.log(e);
//var data = $.parseJSON(e.data.substring(6));
var data = JSON.parse(e.data.substring(6));
if (data.tag.startsWith('salt/job/')) {
addJob(data);
} else {
addEvent(data);
};
};
function addEvent(event) {
var tpl = $('#event-template').clone();
tpl.removeAttr('id');
tpl.find('.icon').html('<i class="fa fa-fw fa-2x fa-bug"></i>')
tpl.find('.title').text(event.data.id);
tpl.find('.message').html('<pre>' + JSON.stringify(event.data) + '</pre>');
tpl.find('.tag').text(event.tag);
tpl.find('.minion-id').text(event.data.id);
$('#eventholder').prepend(tpl);
setTimeout(function() {
tpl.remove();
}, 300000);
};
function addJob(data) {
var tpl = $('#job-template').clone();
tpl.removeAttr('id');
tpl.find('.timestamp').text(data.data._stamp);
tpl.find('.tag').text(data.tag);
$('#jobholder').prepend(tpl);
setTimeout(function() {
tpl.remove()
}, 60000);
};
});
......@@ -12,3 +12,4 @@
@import "dashboard.less";
@import "docs.less";
@import "events.less";
.event {
position: relative;
border-width: 2px;
border-radius: 2px;
border-style: solid;
border-color: #ddd;
padding: 15px;
margin-bottom: 25px;
span.tag {
position: absolute;
top: 0px;
right: 0px;
padding: 0px 3px;
background-color: #ddd;
border-bottom-left-radius: 2px;
font-size: 0.9em;
}
.message {
pre {
white-space: pre-wrap;
}
}
span.minion-id {
position: absolute;
bottom: 0px;
right: 0px;
padding: 0px 3px;
background-color: #ddd;
border-top-left-radius: 2px;
font-size: 0.9em;
}
p.title {
font-weight: bold;
font-size: 1.3em;
}
}
#event-template, #job-template {
display: none;
}
Source diff could not be displayed: it is too large. Options to address this: view the blob.
......@@ -26,7 +26,11 @@
<li {% block nav-domains %}{% endblock %}><a href="{% url 'domain-list' %}"><i class="fa fa-fw fa-2x fa-link"></i> Domains</a></li>
<li {% block nav-minions %}{% endblock %}><a href="{% url 'minion-list' %}"><i class="fa fa-fw fa-2x fa-server"></i> Minions</a></li>
<li {% block nav-networks %}{% endblock %}><a href="{% url 'network-list' %}"><i class="fa fa-fw fa-2x fa-plug"></i> Networks</a></li>
<li {% block nav-commands %}{% endblock %}><a href="#"><i class="fa fa-fw fa-2x fa-terminal"></i> Commands</a></li>
</ul>
<ul class="nav nav-sidebar">
<li {% block nav-events %}{% endblock %}><a href="{% url 'events' %}"><i class="fa fa-fw fa-2x fa-star-o"></i> Events</a></li>
<!--<li><a href="#"><i class="fa fa-fw fa-2x fa-rocket"></i> Jobs</a></li>-->
</ul>
{% endblock %}
</div>
......
{% extends '_layout/navbar.html' %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{% block nav-events %}class="active"{% endblock %}
{% block title-extra %}Events{% endblock %}
{% block post-script %}
<script>
var token = "{{ request.session.salt_tornado_token }}";
</script>
<script src="{% static 'js/events.min.js' %}"></script>
{% endblock %}
{% block content %}
<div class="page-header">
<h1>Event streams <small id="conn_status"><i class="fa fa-fw fa-spin fa-circle-o-notch"></i> Connecting ...</small></h1>
</div>
<div class="row">
<div class="col-md-6">
<h2>Events</h2>
<div id="eventholder">
<!-- provide an template to copy events from -->
<div id="event-template" class="event">
<div class="media">
<div class="media-left icon">
<!-- font awesome icon here please -->
</div>
<div class="media-body">
<p class="title"></p>
<div class="message"></div>
</div>
</div>
<span class="tag"></span>
<span class="minion-id"></span>
</div>
<!-- end template -->
</div>
</div>
<div class="col-md-6">
<h2>Jobs</h2>
<div id="jobholder">
<!-- provide an template to copy jobs from -->
<div id="job-template" class="job">
<p>
<strong class="timestamp"></strong>: <span class="tag"></span>
</p>
</div>
<!-- end template -->
</div>
</div>
</div>
{% endblock %}
......@@ -7,7 +7,8 @@ from .views import (
Dashboard, VisualNetwork,
MinionList, MinionDetail, MinionEdit,
NetworkList, NetworkDetail, NetworkEdit,
DomainList, DomainDetail, DomainEdit
DomainList, DomainDetail, DomainEdit,
EventView
)
......@@ -36,4 +37,6 @@ urlpatterns = [
auth_url(r'^domains/$', DomainList.as_view(), name='domain-list'),
auth_url(r'^domains/(?P<slug>[a-zA-Z0-9\.\-]+)/$', DomainDetail.as_view(), name='domain-detail'),
auth_url(r'^domains/(?P<slug>[a-zA-Z0-9\.\-]+)/edit/$', DomainEdit.as_view(), name='domain-edit'),
auth_url(r'^events/$', EventView.as_view(), name='events'),
]
......@@ -154,3 +154,7 @@ class DomainEdit(MarkdownEditMixin, UpdateView, DomainDetail):
template_name = 'domain/edit.html'
form_class = DomainEditForm
success_url_name = 'domain-detail'
class EventView(TemplateView):
template_name = 'events.html'
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment