monitoring/ffmap/web/templates/router.html

369 lines
14 KiB
HTML

{% extends "bootstrap.html" %}
{% block title %}{{super()}} :: {{ router.hostname }}{% endblock %}
{% block head %}{{super()}}
<link rel="stylesheet" href="{{ url_for('static', filename='leaflet/leaflet.css') }}" />
<script src="{{ url_for('static', filename='leaflet/leaflet.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph/date.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph/jquery.flot.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph/jquery.flot.time.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph/jquery.flot.byte.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph/jquery.flot.selection.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph/jquery.flot.downsample.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph/jquery.flot.resize.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph/jquery.flot.hiddengraphs.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph.js') }}"></script>
<style type="text/css">
#map {
height: 405px;
width: 100%;
}
.navbar, .table-condensed {
margin-bottom: 0;
}
.table-condensed tr:last-child td, th {
border-bottom: 1px solid #ddd;
}
li.list-group-item:hover {
background-color: #f5f5f5;
}
/* hack to remove flex css on small single-column layout */
@media(max-width:991px) {
.row {
display: block !important;
}
}
</style>
{% endblock %}
{% block content %}
<div class="row" style="margin-top: 5px; margin-bottom: 5px;">
<div class="col-xs-12 col-sm-10">
<h2 style="margin-top: 10px;">Router: {{ router.hostname }}</h2>
{%- if mac %}
<h4 style="margin-top: 10px;margin-bottom: 20px">Perma-Link: <a href="{{ url_for('router_mac', mac=mac, _external=True) }}">{{ url_for('router_mac', mac=mac, _external=True) }}</a></h4>
{%- endif %}
</div>
<div class="col-xs-12 col-sm-2 text-right" style="margin-top: 10px; margin-bottom: 10px;">
<form method="post" id="actform">
<input type="hidden" name="act" id="act" value="" />
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Actions
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
{%- if authuser %}
<li><a href="#" onclick="$('#act').val('delete'); $('#actform').submit()">Delete Router</a></li>
{%- endif %}
{%- if authadmin %}
<li><a href="#" onclick="$('#act').val('ban'); $('#actform').submit()">Ban Router</a></li>
{%- endif %}
<li><a href="#" onclick="$('#act').val('report'); $('#actform').submit()">Report Router</a></li>
</ul>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-6">
<div class="panel panel-default">
<div class="panel-body" style="padding: 0;">
<div id="map"></div>
<script type="text/javascript">
var url_get_nearest_router = "{{ url_for('api.get_nearest_router') }}";
var url_router_info = "{{ url_for('router_info', dbid='') }}";
var tileurls = {{ tileurls|tojson|safe }};
</script>
<script src="{{ url_for('static', filename='js/map.js') }}"></script>
<script type="text/javascript">
{%- if router.lng and router.lat %}
var router_pos = [{{ router.lat }}, {{ router.lng }}];
map.setView(router_pos, 18);
var marker = L.marker(router_pos, {
icon: L.icon({
iconUrl: "{{ url_for('static', filename='img/router_blue.svg') }}",
iconSize: [14, 14]
}),
clickable: false
}).addTo(map);
{%- else %}
map.setView([49.45, 11.1], 10);
{%- endif %}
</script>
</div>
</div>
</div>
<div class="col-xs-12 col-md-6">
<div class="panel panel-default">
<div class="panel-heading">System</div>
<div class="panel-body">
<table class="table table-condensed">
<tr><th>Hostname</th><td>
{{ router.hostname }}
{%- if router.netifs|webui_addr %}
(<a href="http://[{{ router.netifs|webui_addr }}]">WebUI</a>)
{%- endif %}
</td></tr>
<tr><th>Status</th><td><span class="{{ router.status|status2css }}">{{ router.status }}</span>
{%- if router.status == "online" %}
({{ router.sys_uptime|format_ts_diff }} up)
{%- endif -%}
</td></tr>
<tr><th>Created</th><td>
{{ router.created|utc2local|format_dt }}
</td></tr>
<tr><th class="text-nowrap">Last contact</th><td>
{{ router.last_contact|utc2local|format_dt }}
({{ router.last_contact|utc2local|format_dt_ago }}){{- "" -}}
</td></tr>
{%- if router.status_text %}
<tr><th>Status Text</th><td>{{ router.status_text }}</td></tr>
{%- endif %}
{%- if router.description %}
<tr><th>Description</th><td>{{ router.description }}</td></tr>
{%- endif %}
{%- if router.position_comment %}
<tr><th>Position</th><td>{{ router.position_comment }}</td></tr>
{%- endif %}
{%- if router.hood %}
<tr><th>Hood</th><td><a href="{{ url_for('router_list', q='hood:^%s$' % router.hood) }}">{{ router.hood }}</a>
{%- if router.community %}
({{ router.community }})
{%- endif -%}
{%- if router.reset %}
<span style="color:#d90000">- Router has lost its position!</span>
{%- endif -%}
</td></tr>
{%- endif %}
{%- if router.user or router.contact %}
<tr><th>User</th><td>
{%- if router.user -%}
<a href="{{ url_for('user_info', nickname=router.user) }}">{{ router.user }}</a>
{%- if router.contact %}
(<a href="{{ url_for('router_list', q='contact:%s' % router.contact|anon_email_regex) }}">{{ router.contact|anon_email }}</a>)
{%- endif -%}
{%- else -%}
<a href="{{ url_for('router_list', q='contact:%s' % router.contact|anon_email_regex) }}">{{ router.contact|anon_email }}</a>
{%- endif -%}
</td></tr>
{%- endif %}
<tr><th>Hardware</th><td><span title="{{ router.chipset }}">{{ router.hardware }}</span></td></tr>
<tr><th>WAN Uplink</th><td><span class="{{ "glyphicon glyphicon-ok" if router.wan_uplink else "glyphicon glyphicon-remove" }}"></span></td></tr>
<tr><th>Clients</th><td>{{ router.clients }}</td></tr>
</table>
</div>
</div>
</div>
</div>
<div class="row" style="display: flex;">
<div class="col-xs-12 col-md-6" style="display: flex; flex-flow: column;">
<div class="panel panel-default">
<div class="panel-heading">Software</div>
<div class="panel-body">
<table class="table table-condensed">
<tr><th>Firmware</th><td><span title="{{ router.firmware_rev }}">{{ router.firmware }}</span></td></tr>
<tr><th>Operating&nbsp;System</th><td>{{ router.os }}</td></tr>
<tr><th>Kernel</th><td>{{ router.kernel }}</td></tr>
<tr><th>B.A.T.M.A.N. adv</th><td>{{ router.batman }}</td></tr>
<tr><th>Nodewatcher</th><td>{{ router.nodewatcher }}</td></tr>
</table>
</div>
</div>
{%- if not router.neighbours|length > 0 %}
</div>
<div class="col-xs-12 col-md-6" style="display: flex; flex-flow: column;">
{%- endif %}
<div class="panel panel-default" style="flex: 1 1 auto;">
<div class="panel-heading">Events</div>
<div class="panel-body">
<table class="table table-condensed">
{%- for event in router.events[-5:] %}
<tr>
<td style="width: 11em;">{{ event.time|utc2local|format_dt|nbsp|safe }}</td>
<td style="width: 1em;"><span class="{{ event.type|status2css }}">{{ event.type }}</span></td>
<td>{{ event.comment }}</td>
</tr>
{%- endfor %}
</table>
</div>
</div>
</div>
{%- if router.neighbours|length > 0 %}
<div class="col-xs-12 col-md-6" style="display: flex; flex-flow: column;">
<div class="panel panel-default" style="flex: 1 1 auto;">
<div class="panel-heading">Neighbours</div>
<div class="panel-body" style="height: 100%;">
<div class="table-responsive">
<table class="neighbours" style="width: 100%; margin-bottom: 6px;">
<tr>
<th>Hostname</th>
<th>MAC Address</th>
<th>Quality</th>
<th>Interface</th>
</tr>
{%- for neighbour in router.neighbours %}
<tr style="background-color: {{ neighbour.quality|neighbour_color }};">
<td>{%- if neighbour.hostname -%}<a href="{{ url_for('router_info', dbid=neighbour.id) }}">{{ neighbour.hostname }}</a>{%- else -%}---{%- endif -%}</td>
<td>{{ neighbour.mac }}</td>
<td>{{ neighbour.quality }}</td>
<td>{{ neighbour.netif }}</td>
</tr>
{%- endfor %}
</table>
</div>
{# hack for graph vertical align #}
{%- if router.neighbours|length < 3 %}
{%- for n in range(3- router.neighbours|length) %}
<br />
{%- endfor %}
{%- endif %}
<div id="meshstat" class="graph" style="height: 300px;"></div>
</div>
</div>
</div>
{%- endif %}
</div>
<div class="row">
<div class="col-xs-12 col-md-6">
<div class="panel panel-default">
<div class="panel-heading">Network Interfaces</div>
<div class="panel-body">
<div id="netstat" class="graph"></div>
</div>
<ul class="list-group" id="netif-list">
{# make sure that br-mesh is on top of the list #}
{%- for netif in router.netifs if netif.netif == 'br-mesh' %}
<li class="list-group-item active" data-name="{{ netif.netif|replace('.', '')|replace('$', '') }}">
<div class="row">
<div class="col-xs-6 col-sm-6"><h4 class="list-group-item-heading">{{ netif.netif }}</h4></div>
<div class="col-xs-6 col-sm-6 text-right" style="text-transform: uppercase;"><h4 class="list-group-item-heading">{{ netif.mac }}</h4></div>
</div>
<div class="row">
<div class="col-xs-5 col-sm-5">
{%- if netif.ipv6_fe80_addr -%}
{{ netif.ipv6_fe80_addr }}
{%- else -%}
<em title="Calculated from MAC Address">{{ netif.mac|mac2fe80 }}</em>
{%- endif -%}
{%- if netif.ipv4_addr -%}
<br />{{ netif.ipv4_addr }}
{%- endif -%}
{%- for ipv6_addr in netif.ipv6_addrs -%}
<br />{{ ipv6_addr }}
{%- endfor -%}
</div>
{%- if netif.rx is defined %}
<div class="col-xs-7 col-sm-7 text-right">
<span class="glyphicon glyphicon-arrow-down"></span>{{ netif.rx|humanize_bytes }}/s
<span class="glyphicon glyphicon-arrow-up"></span>{{ netif.tx|humanize_bytes }}/s
</div>
{%- endif %}
</div>
</li>
{%- endfor %}
{%- for netif in router.netifs if netif.netif != 'br-mesh' %}
<li class="list-group-item" data-name="{{ netif.netif|replace('.', '')|replace('$', '') }}">
<div class="row">
<div class="col-xs-6 col-sm-6"><h4 class="list-group-item-heading">{{ netif.netif }}</h4></div>
<div class="col-xs-6 col-sm-6 text-right" style="text-transform: uppercase;"><h4 class="list-group-item-heading">{{ netif.mac }}</h4></div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12" style="padding-bottom:6px;font-size:14px">
{%- if netif.wlan_type -%}
{{netif.wlan_type}},&nbsp;
{%- endif -%}
{%- if netif.wlan_channel -%}
Channel: {{netif.wlan_channel}},&nbsp;
{%- endif -%}
{%- if netif.wlan_ssid -%}
SSID: {{netif.wlan_ssid}},&nbsp;
{%- endif -%}
{%- if netif.wlan_txpower -%}
Tx-Power: {{netif.wlan_txpower}}
{%- endif -%}
</div>
</div>
<div class="row">
<div class="col-xs-5 col-sm-5">
{%- if netif.ipv6_fe80_addr -%}
{{ netif.ipv6_fe80_addr }}
{%- else -%}
<em title="Calculated from MAC Address">{{ netif.mac|mac2fe80 }}</em>
{%- endif -%}
{%- if netif.ipv4_addr -%}
<br />{{ netif.ipv4_addr }}
{%- endif -%}
{%- for ipv6_addr in netif.ipv6_addrs -%}
<br />{{ ipv6_addr }}
{%- endfor -%}
</div>
{%- if netif.rx is defined %}
<div class="col-xs-7 col-sm-7 text-right">
<span class="glyphicon glyphicon-arrow-down"></span>{{ netif.rx|humanize_bytes }}/s
<span class="glyphicon glyphicon-arrow-up"></span>{{ netif.tx|humanize_bytes }}/s
</div>
{%- endif %}
</div>
</li>
{%- endfor %}
</ul>
</div>
</div>
<div class="col-xs-12 col-md-6">
<div class="panel panel-default">
<div class="panel-heading">Clients</div>
<div class="panel-body">
<div id="clientstat" class="graph"></div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Average Load</div>
<div class="panel-body">
<div id="loadstat" class="graph"></div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Memory</div>
<div class="panel-body">
<div id="memstat" class="graph"></div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Processes</div>
<div class="panel-body">
<div id="procstat" class="graph"></div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var router_stats = {{ router.stats|statbson2json|safe }};
var netif_stats = {{ netifstats|statbson2json|safe }};
var neigh_stats = {{ neighstats|statbson2json|safe }};
var neighbours = [
{%- for neighbour in router.neighbours %}
{"name": "{{ neighbour.hostname or neighbour.mac }}", "mac": "{{ neighbour.mac }}", "netif": "{{ neighbour.netif }}"},
{%- endfor %}
];
$(document).ready(function() {
{%- if router.neighbours|length > 0 %}
neighbour_graph(neighbours);
{%- endif %}
memory_graph();
process_graph();
client_graph();
loadavg_graph();
$("#netif-list li").on("click", function() {
$("#netif-list li").removeClass("active");
var netif = this.getAttribute("data-name");
network_graph(netif);
$(this).addClass("active");
});
network_graph("br-mesh");
});
</script>
{% endblock %}