mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-29 07:29:32 +00:00
270 lines
9 KiB
Text
270 lines
9 KiB
Text
{#
|
|
(C) 2021 - ntop.org
|
|
Each widget contained inside the widgets folder has this following field:
|
|
* widget
|
|
#}
|
|
<div class="widget geomap-widget" id="widget-{{ widget_name }}" style="{* css_styles *}">
|
|
{% if not isEmptyString(displaying_label) then %}
|
|
<h3 class="widget-name mb-2">{{ displaying_label }}</h3>
|
|
{% end %}
|
|
<div class="widget-error text-center text-danger" style="display: none; height: 100%; margin-top: 2rem">
|
|
Something went wrong when loading this chart.
|
|
</div>
|
|
|
|
<div id='geomap-alert' style="display: none" role="alert" class='alert alert-danger'>
|
|
<span id='error-message'></span>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
<div class="d-flex justify-content-center align-items-center" style="{{ css_styles }}" id="map-canvas"></div>
|
|
<div id="canvas-widget-{{widget_name}}"></div>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
const zoomIP = undefined;
|
|
|
|
const display_localized_error = (error_code) => {
|
|
$('#geomap-alert #error-message').html(`<b>{* i18n("geo_map.geolocation_warning") *}</b>: {* i18n("geo_map.using_default_location") *}`);
|
|
$('#geomap-alert').removeClass('alert-danger').addClass('alert-warning').show();
|
|
}
|
|
|
|
const display_localized_no_geolocation_msg = () => {
|
|
$('#geomap-alert p').html(`{* i18n("geo_map.unavailable_geolocation") .. ' ' .. i18n("geo_map.using_default_location") *}`);
|
|
$('#geomap-alert').addClass('alert-info').removeClass('alert-danger').show();
|
|
}
|
|
|
|
const red_marker = L.icon({
|
|
iconUrl: `${http_prefix}/leaflet/images/marker-icon-red.png`,
|
|
shadowUrl: '${http_prefix}/leaflet/images/marker-shadow.png',
|
|
iconSize: [25, 41],
|
|
popupAnchor: [1, -34],
|
|
tooltipAnchor: [16, -28]
|
|
});
|
|
|
|
const info_key_names = {
|
|
"score": i18n_ext.score,
|
|
"asname": i18n_ext.as,
|
|
"html": i18n_ext.nation,
|
|
"active_alerted_flows": i18n_ext.alerted_flows,
|
|
"num_blacklisted_flows": i18n_ext.blacklisted_flows,
|
|
"bytes.sent": i18n_ext.traffic_sent,
|
|
"bytes.rcvd": i18n_ext.traffic_rcvd,
|
|
"total_flows": i18n_ext.flows,
|
|
};
|
|
|
|
const formatters = {
|
|
"bytes.sent": NtopUtils.bytesToSize,
|
|
"bytes.rcvd": NtopUtils.bytesToSize,
|
|
}
|
|
|
|
const default_coords = [41.9, 12.4833333];
|
|
const zoom_level = 4;
|
|
let addRefToHost = true;
|
|
let endpoint = http_prefix + "/lua/rest/v2/get/geo_map/hosts.lua?";
|
|
let baseEndpoint = "";
|
|
|
|
const create_marker = (h) => {
|
|
h = JSON.parse(JSON.stringify(h));
|
|
const settings = { title: h.name };
|
|
if (h.isRoot) settings.icon = red_marker;
|
|
|
|
let ip = h.ip
|
|
const lat = h.lat;
|
|
const lng = h.lng;
|
|
const name = h.name;
|
|
let name_ip = ip;
|
|
let extra_info = '';
|
|
|
|
h.ip = null;
|
|
h.lat = null;
|
|
h.lng = null;
|
|
h.name = null;
|
|
h.isRoot = null;
|
|
|
|
// Formatting the extra info to print into the Geo Map
|
|
for (const key in h) {
|
|
if(formatters[key])
|
|
h[key] = formatters[key](h[key])
|
|
|
|
if(h[key] && info_key_names[key])
|
|
extra_info = extra_info + info_key_names[key] + ": <b>" + h[key] + "</b></br>";
|
|
}
|
|
|
|
if(h["flow_status"]) {
|
|
let flow_status = i18n_ext.flow_status + ":</br>";
|
|
for (const prop in h["flow_status"]) {
|
|
flow_status = flow_status + "<b>" + h["flow_status"][prop]["num_flows"] + " Flows, " + h["flow_status"][prop]["label"] + "</b></br>";
|
|
}
|
|
extra_info = extra_info + flow_status;
|
|
}
|
|
|
|
if(name)
|
|
name_ip = name + "</br>" + name_ip;
|
|
|
|
analysisPage = new URLSearchParams(window.location.search)
|
|
let alreadyFilteredIp = analysisPage.get('ip')
|
|
|
|
if(alreadyFilteredIp) ip = alreadyFilteredIp + "," + ip
|
|
|
|
analysisPage.set('ip', ip + ";eq")
|
|
|
|
let hostDetails = ""
|
|
|
|
h.host_in_memory ? hostDetails = `<a href='${http_prefix}/lua/host_details.lua?host=${ip}'> <i class="fas fa-laptop"></i></a>` : ``
|
|
|
|
const marker = `<div class='infowin'>
|
|
<a href='${http_prefix}/lua/pro/db_search.lua?${analysisPage.toString()}'>${name_ip}</a>
|
|
${hostDetails}
|
|
<hr>
|
|
${extra_info}
|
|
</div>`
|
|
|
|
return L.marker(L.latLng(lat, lng), settings).bindPopup(marker);
|
|
}
|
|
|
|
// return true if the status code is different from 200
|
|
const check_status_code = (status_code, status_text, $error_label) => {
|
|
|
|
const is_different = (status_code != 200);
|
|
|
|
if (is_different && $error_label != null) {
|
|
$error_label.find('p').text(`${i18n_ext.request_failed_message}: ${status_code} - ${status_text}`).show();
|
|
}
|
|
else if (is_different && $error_label == null) {
|
|
alert(`${i18n_ext.request_failed_message}: ${status_code} - ${status_text}`);
|
|
}
|
|
|
|
return is_different;
|
|
}
|
|
|
|
const display_errors = (errors) => {
|
|
const error_messages = {
|
|
1: 'Permission denied',
|
|
2: 'Position unavailable',
|
|
3: 'Request timeout'
|
|
};
|
|
const error_code = error_messages[errors.code];
|
|
|
|
show_positions({ coords: { latitude: 0, longitude: 0 }});
|
|
|
|
if (errors.code != 1) {
|
|
display_localized_error(error_code);
|
|
}
|
|
}
|
|
|
|
const init_map = (newEndpoint = null, _baseEndpoint = null) => {
|
|
endpoint = newEndpoint || endpoint;
|
|
baseEndpoint = _baseEndpoint;
|
|
|
|
if (navigator.geolocation) {
|
|
navigator.geolocation.getCurrentPosition(show_positions, display_errors,
|
|
{
|
|
enableHighAccuracy: true,
|
|
timeout: 10000,
|
|
maximumAge: 0
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
const draw_markers = (hosts, map_markers, map) => {
|
|
hosts.forEach(h => {
|
|
map_markers.addLayer(
|
|
create_marker(h)
|
|
);
|
|
|
|
// make a transitions to the root host
|
|
if (h.isRoot) {
|
|
map.flyTo([h.lat, h.lng], zoom_level);
|
|
}
|
|
});
|
|
map.addLayer(map_markers);
|
|
}
|
|
|
|
let hosts = null;
|
|
let map = null;
|
|
let markers = null;
|
|
|
|
const redraw_hosts = (show_only_alert_hosts, redo_query = false, extra_endpoint_params = null) => {
|
|
if (markers == null || map == null || hosts == null) {
|
|
console.error("map isn't initialized!");
|
|
return;
|
|
}
|
|
markers.clearLayers();
|
|
|
|
if(redo_query == true) {
|
|
$.get(`${baseEndpoint}?${extra_endpoint_params}&ifid=${interfaceID}&${zoomIP || ''}`)
|
|
.then((data) => {
|
|
hosts = data.rsp;
|
|
draw_markers(data.rsp, markers, map);
|
|
})
|
|
.fail(({ status, statusText }) => {
|
|
NtopUtils.check_status_code(status, statusText, $("#geomap-alert"));
|
|
});
|
|
} else {
|
|
//map.removeLayer(markers);
|
|
let temp_hosts = hosts.filter((h) => h.isAlert == true || !show_only_alert_hosts);
|
|
draw_markers(temp_hosts, markers, map);
|
|
}
|
|
}
|
|
|
|
const show_positions = (current_user_position) => {
|
|
// these are two map providers provided by: https://leaflet-extras.github.io/leaflet-providers/preview/
|
|
const layers = {
|
|
light: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
// dark: "https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png"
|
|
};
|
|
// select the right layer
|
|
const layer = layers.light;
|
|
const user_coords = [current_user_position.coords.latitude, current_user_position.coords.longitude];
|
|
|
|
if (user_coords[0] == 0 && user_coords[1] == 0) {
|
|
/* Do not even report the info/error to the user, this is
|
|
* not relevant as the map functionality is not impacted */
|
|
//display_localized_no_geolocation_msg();
|
|
console.log("Geolocation unavailable, using default location");
|
|
|
|
user_coords[0] = default_coords[0], user_coords[1] = default_coords[1];
|
|
}
|
|
//document.getElementById('map-canvas').innerHTML = "<div id='map' style='width: 100%; height: 100%;'></div>";
|
|
const hosts_map = L.map('map-canvas').setView(user_coords || default_coords, zoom_level);
|
|
map = hosts_map;
|
|
const map_markers = L.markerClusterGroup({
|
|
maxClusterRadius: 100,
|
|
spiderLegPolylineOptions: {
|
|
opacity: 0
|
|
}
|
|
});
|
|
markers = map_markers;
|
|
map = hosts_map;
|
|
|
|
L.tileLayer(layer, {
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
}).addTo(hosts_map);
|
|
|
|
if (hosts != null) {
|
|
draw_markers(hosts, map_markers, hosts_map);
|
|
return;
|
|
}
|
|
|
|
$.get(`${endpoint}&ifid=${interfaceID}&${zoomIP || ''}`)
|
|
.then((data) => {
|
|
hosts = data.rsp;
|
|
draw_markers(data.rsp, map_markers, hosts_map);
|
|
})
|
|
.fail(({ status, statusText }) => {
|
|
NtopUtils.check_status_code(status, statusText, $("#geomap-alert"));
|
|
});
|
|
|
|
}
|
|
|
|
$(document).ready(async function() {
|
|
const datasource = {* json.encode(widget.datasources) *};
|
|
const additionalParams = {* json.encode(widget.additional_params) *};
|
|
const $error = $(`#widget-{{ widget_name }} .widget-error`);
|
|
const endpoint = "{* ntop.getHttpPrefix() *}" + datasource[0]["endpoint"];
|
|
const base_endpoint = "{* ntop.getHttpPrefix() *}" + datasource[0]["name"];
|
|
const hostEndpoint = ""
|
|
|
|
init_map(endpoint, base_endpoint, true);
|
|
});
|
|
</script>
|