(function (Icinga) { function colorMarker(worstState, icon) { var markerColor = 'awesome-marker'; // TODO: Different marker icon for not-OK states // if(worstState > 0) { // markerColor = markerColor + ' awesome-marker-square'; // } var marker = L.AwesomeMarkers.icon({ icon: icon, markerColor: state2color(worstState), className: markerColor }); return marker } function state2color(state) { switch (parseInt(state)) { case 0: return "green"; case 1: return "orange"; case 2: return "red"; case 3: return "purple"; default: return "blue"; } } function isFilterParameter(parameter) { return (parameter.charAt(0) === '(' || parameter.match('^[_]{0,1}(host|service)') || parameter.match('^(object|state)Type') || parameter.match('^problems')); } function getParameters(id) { var params = decodeURIComponent($('#map-' + id).closest('.module-map').data('icingaUrl')).split('&'); // remove module path from url parameters if (params.length > 0) { params[0] = params[0].replace(/^.*\?/, '') } return params } function unique(list) { var result = []; $.each(list, function (i, e) { if ($.inArray(e, result) == -1) result.push(e); }); return result; } function filterParams(id, extra) { var sURLVariables = getParameters(id); var params = [], i; if (extra !== undefined) { sURLVariables = $.merge(extra.split('&'), sURLVariables); sURLVariables = unique(sURLVariables); } for (i = 0; i < sURLVariables.length; i++) { // Protect Icinga filter syntax if (isFilterParameter(sURLVariables[i])) { params.push(sURLVariables[i]); continue; } } return params.join("&") } function showDefaultView() { if (map_default_lat !== null && map_default_long !== null) { if (map_default_zoom !== null) { cache[id].map.setView([map_default_lat, map_default_long], map_default_zoom); } else { cache[id].map.setView([map_default_lat, map_default_long]); } } else { cache[id].map.fitWorld() } } function toggleFullscreen() { icinga.ui.toggleFullscreen(); cache[id].map.invalidateSize(); cache[id].fullscreen = !cache[id].fullscreen; if (cache[id].fullscreen) { $('.controls').hide(); } else { $('.controls').show(); } } // TODO: Allow update of multiple parameters function updateUrl(pkey, pvalue) { // Don't update URL if in dashlet mode if (dashlet) { return; } var $target = $('.module-map'); var $currentUrl = $target.data('icingaUrl'); var basePath = $currentUrl.replace(/\?.*$/, ''); var searchPath = $currentUrl.replace(/^.*\?/, ''); var sURLVariables = (searchPath === basePath ? [] : searchPath.split('&')); var updated = false; for (var i = 0; i < sURLVariables.length; i++) { // Don't replace Icinga filters if (isFilterParameter(sURLVariables[i])) { continue; } var tmp = sURLVariables[i].split('='); if (tmp[0] == pkey) { sURLVariables[i] = tmp[0] + '=' + pvalue; updated = true; break; } } // Parameter is to be added if (!updated) { sURLVariables.push(pkey + "=" + pvalue); } $target.data('icingaUrl', basePath + '?' + sURLVariables.join('&')); icinga.history.pushCurrentState(); } function getWorstState(states) { var worstState = 0; var allPending = -1; var allUnknown = -1; var last = -1; if (states.length == 1) { return states[0]; } for (var i = 0, len = states.length; i < len; i++) { var state = states[i]; if (state < 3) { if (allPending == 1) { allPending = 0; } else if (allUnknown == 1) { allUnknown = 0; } } if (state > 2) { // PENDING if (state == 99) { if (allPending < 0 && last < 0) { allPending = 1; } // OK -> PENDING -> UNKNOWN -> WARNING -> CRITICAL state = 0.25; } // UNKNOWN if (state == 3) { if (allUnknown < 0 && last < 0) { allUnknown = 1; } // OK -> PENDING -> UNKNOWN -> WARNING -> CRITICAL state = 0.5; } } if (state > worstState) { worstState = state; } last = state; } if (allPending == 1) { worstState = 99; } if (allUnknown == 1) { worstState = 3; } // Restore PENDING and UNKNOWN if (worstState == 0.25) { worstState = 99; } else if (worstState == 0.5) { worstState = 3; } return worstState; } function mapCenter(hostname) { if (cache[id].hostMarkers[hostname]) { var el = cache[id].hostMarkers[hostname]; cache[id].map.panTo(cache[id].hostMarkers[hostname].getLatLng()) } } var cache = {}; var Map = function (module) { this.module = module; this.initialize(); this.timer; this.module.icinga.logger.debug('Map module loaded'); }; Map.prototype = { initialize: function () { this.timer = {}; this.module.on('rendered', this.onRenderedContainer); this.registerTimer() }, registerTimer: function (id) { this.timer = this.module.icinga.timer.register( this.updateAllMapData, this, 10000 ); return this; }, removeTimer: function (id) { this.module.icinga.timer.unregister(this.timer); return this }, onPopupOpen: function (evt) { $('.detail-link').on("click", function (ievt) { mapCenter(evt.popup._source.options.id); cache[id].map.invalidateSize(); }); }, updateAllMapData: function () { var _this = this; if (cache.length == 0) { this.removeTimer(id) return this } $.each(cache, function (id) { if (!$('#map-' + id).length) { delete cache[id] } else { _this.updateMapData({id: id}) } }); }, updateMapData: function (parameters) { var id = parameters.id; var show_host = parameters.show_host; var $that = this; function showHost(hostname) { if (cache[id].hostMarkers[hostname]) { var el = cache[id].hostMarkers[hostname]; cache[id].markers.zoomToShowLayer(el, function () { el.openPopup(); }) } } function removeOldMarkers(id, data) { // remove old markers $.each(cache[id].hostMarkers, function (identifier, d) { if ((data['hosts'] && !data['hosts'][identifier]) && (data['services'] && !data['services'][identifier])) { cache[id].markers.removeLayer(d); delete cache[id].hostMarkers[identifier]; } }); } function errorMessage(msg) { cache[id].map.spin(false); $map = cache[id].map; $map.openModal({ content: "
Could not fetch data from API:
" + msg + "", onShow: function (evt) { $that.removeTimer(id) }, onHide: function (evt) { $that.registerTimer(id); } }); } function processData(json) { if (json['message']) { errorMessage(json['message']); return; } removeOldMarkers(id, json); $.each(json, function (type, element) { $.each(element, function (identifier, data) { if (data.length < 1 || data['coordinates'] == "") { console.log('found empty coordinates: ' + data) return true } var states = []; var icon; var services; var worstState; var display_name = (data['host_display_name'] ? data['host_display_name'] : hostname); if (type === 'hosts') { states.push((data['host_state'] == 1 ? 2 : data['host_state'])) } services = '
';
services += ' ';
services += service_status[service['service_state']][0];
services += ' ';
services += ' | ';
services += '';
services += ' ';
services += '';
services += service_display_name;
services += ''
services += ' '
services += ' | ';
services += '
To use this location with your host(s) or service(s), just add the following config to your object definition:
" + "" + coord + ""; var marker; marker = L.marker(e.latlng, {icon: colorMarker(99, 'globe')}); marker.bindPopup(popup); marker.addTo(cache[id].markers); marker.on('popupclose', function (evt) { cache[id].markers.removeLayer(marker); }); cache[id].markers.zoomToShowLayer(marker, function () { marker.openPopup(); }) } }); } cache[id].markers.addTo(cache[id].map); cache[id].map.spin(true); this.updateMapData({id: id, show_host: map_show_host}) } }; Icinga.availableModules.map = Map; }(Icinga));