Files
librenms-librenms/html/includes/print-menubar.php

866 lines
38 KiB
PHP
Raw Normal View History

<?php
// FIXME - this could do with some performance improvements, i think. possible rearranging some tables and setting flags at poller time (nothing changes outside of then anyways)
use LibreNMS\Authentication\LegacyAuth;
feature: Wireless Sensors Overhaul (#6471) * feature: Wireless Sensors Includes client counts for ios and unifi Graphing could use some improvement. Alerting and threshold ui not implemented WIP: starting OO based wireless sensors. Class based functionality working remove old functional files add schema file discovery needs to be enabled, not polling fix up schema fix Unifi discovery not returning an array Add some debug when discovering a sensor. Fix style. Add missing semicolin Add a null object (Generic) for OS. Fill out some phpdocs Re-organized code Each sensor type now has it's own discovery and polling interface Custom polling tested with Unifi CCQ Left to do: Implement UI (Graphs and Custom thresholds) Alerting Testing Fix event message text Remove runDiscovery and runPolling from OS, they are unused and don't belong there. Cleanups/docs Missed this file. Remove the requirement to fetch the current value to check validity. Do that automatically if current is not specified A few cleanups here and there First pass at graphing. device_ and wireless_ graphs added. Add RouterOS support Singleton OS instance isn't required right now. Remove that to allow some memory to be freed. Add wireless to the device list metrics. Make all metrics clickable Tweak graphs a bit Implement limit configuration page. Use sensors page as common code instead of duplicating. Clean up some javascript interactions: Allow enter on values to save. Cancel if update is not needed. Enable the clear custom button after setting a custom value. Add some wireless alert rules to the library. Add documentation. Add unifi client counts by ssid in addition to radio. Optimize Sensor polling a bit. Add HP MSM clients support (for full controller) Fix function accessibility Formalize the discovery and poller interfaces. Add Xirrus clients and noise floor move module interfaces to a more appropriate place. push caching code up to os, unsure about this do to the limitations No point in selectively enabling wireless discovery. We only discover if the device supports something. Add RSSI, Power, and Rate. Add these sensors for Ubnt Airos. Clean up some copyrights. Reduce the amount of files need to add new types. Leave graph files for consistency and to allow customization. Remove the old wifi clients graph completely. ciscowlc should have improved counts (total and per-ssid) Schema didn't get added. Impelement the rest of the AirOS sensors Reformat and re-organize the Airos.php class. Add several UBNT AirFiber sensors A few fixes add links to the section headers Add HP MSM mibs. * Schema file got dropped in rebase. * Add wireless menu to view sensors across all devices. Icons in the menu need help :/ * Add HeliOS, Mimosa, and Siklu support Sensors added SNR + Noise * Add power and utilization to Unifi * Update polling to prefetch all sensor data in a few snmp requests as possible * Add Extendair: tx+rx power, aggregate rate, frequency * Add a check for duplicate sensors in discovery. Just print an error for now. * Add Bit Error Ratio (named error-ratio to allow for bit error rate to be added if needed) Fix an incorrect link in the wireless sensors table * Add error rate and change all bps and Hz to use si units * Fixes to limits and frequency display * Fix overview graph frequency display A few decimal place tweaks * Don't allow switching sensor and wireless-sensor graphs, it doesn't work. Change individual distance graphs to use si units * Go through the OS and make sure I got all the sensors I can (probably missed some still) Because pollWirelessChannelAsFrequency() is generic and a little complex, so pull it up to OS. Message to help developers adding supports that don't return an array from discover functions. * Fix some issues * Remove noise and signal for now at least A couple more fixes Add a notification * Oopsie * Bonus AirFiber sensors
2017-05-01 23:49:11 -05:00
use LibreNMS\Device\WirelessSensor;
use LibreNMS\ObjectCache;
$service_status = get_service_status();
$typeahead_limit = $config['webui']['global_search_result_limit'];
$if_alerts = dbFetchCell("SELECT COUNT(port_id) FROM `ports` WHERE `ifOperStatus` = 'down' AND `ifAdminStatus` = 'up' AND `ignore` = '0'");
if (Auth::user()->hasGlobalRead()) {
$links['count'] = dbFetchCell("SELECT COUNT(*) FROM `links`");
} else {
$links['count'] = dbFetchCell("SELECT COUNT(*) FROM `links` AS `L`, `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` AND `L`.`local_device_id` = `D`.`device_id`", array(Auth::id()));
}
2015-07-13 20:10:26 +02:00
if (isset($config['enable_bgp']) && $config['enable_bgp']) {
$bgp_alerts = dbFetchCell("SELECT COUNT(bgpPeer_id) FROM bgpPeers AS B where (bgpPeerAdminStatus = 'start' OR bgpPeerAdminStatus = 'running') AND bgpPeerState != 'established'");
}
if (isset($config['site_style']) && ($config['site_style'] == 'dark' || $config['site_style'] == 'mono')) {
2015-03-26 23:51:13 +00:00
$navbar = 'navbar-inverse';
} else {
$navbar = '';
2015-03-26 23:51:13 +00:00
}
?>
2015-03-26 23:51:13 +00:00
<nav class="navbar navbar-default <?php echo $navbar; ?> navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navHeaderCollapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
2014-01-14 19:40:59 +00:00
<?php
2015-07-13 20:10:26 +02:00
if ($config['title_image']) {
echo('<a class="hidden-md hidden-sm navbar-brand" href=""><img src="' . $config['title_image'] . '" /></a>');
} else {
echo('<a class="hidden-md hidden-sm navbar-brand" href="">'.$config['project_name'].'</a>');
2015-07-13 20:10:26 +02:00
}
2014-01-14 19:40:59 +00:00
?>
</div>
<div class="collapse navbar-collapse" id="navHeaderCollapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="<?php echo(generate_url(array('page'=>'overview'))); ?>" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-home fa-fw fa-lg fa-nav-icons hidden-md" aria-hidden="true"></i> <span class="hidden-sm">Overview</span></a>
2016-03-03 16:43:13 -07:00
<ul class="dropdown-menu multi-level" role="menu">
<li><a href="<?php echo(generate_url(array('page'=>'overview'))); ?>"><i class="fa fa-tv fa-fw fa-lg" aria-hidden="true"></i> Dashboard</a></li>
<li class="dropdown-submenu">
<a href="<?php echo(generate_url(array('page'=>'overview'))); ?>"><i class="fa fa-map fa-fw fa-lg" aria-hidden="true"></i> Maps</a>
<ul class="dropdown-menu">
2016-09-23 08:24:36 -04:00
<li><a href="<?php echo(generate_url(array('page'=>'availability-map'))); ?>"><i class="fa fa-arrow-circle-up fa-fw fa-lg" aria-hidden="true"></i> Availability</a></li>
<li><a href="<?php echo(generate_url(array('page'=>'map'))); ?>"><i class="fa fa-sitemap fa-fw fa-lg" aria-hidden="true"></i> Network</a></li>
2016-03-03 16:43:13 -07:00
<?php
require_once '../includes/device-groups.inc.php';
$devices_groups = GetDeviceGroups();
if (count($devices_groups) > 0) {
2016-09-23 08:24:36 -04:00
echo '<li class="dropdown-submenu"><a href="#"><i class="fa fa-th fa-fw fa-lg" aria-hidden="true"></i> Device Groups Maps</a><ul class="dropdown-menu scrollable-menu">';
foreach ($devices_groups as $group) {
2016-09-23 08:24:36 -04:00
echo '<li><a href="'.generate_url(array('page'=>'map','group'=>$group['id'])).'" title="'.$group['desc'].'"><i class="fa fa-th fa-fw fa-lg" aria-hidden="true"></i> '.ucfirst($group['name']).'</a></li>';
2016-03-03 16:43:13 -07:00
}
unset($group);
echo '</ul></li>';
}
2016-03-03 16:43:13 -07:00
?>
Borderless fullscreen geographical map, with just the nodes. (#8337) * Added a variant of map.php which allows for a borderless fullscreen geographical map, with just the nodes. * Signed my work. * Removed a space. * delete whitespace * remove whitespace * hack to fix some tiles not loading found the fix here: https://stackoverflow.com/questions/36246815/data-toggle-tab-does-not-download-leaflet-map/36257493#36257493 https://gis.stackexchange.com/questions/224932/problem-with-map-tiles-loading-with-leaflet-and-bootstrap You might be able to do something more elegant. * added menu entry This removes the need for setting it as a front-page. Now it can be accessed from the menu and LibreNMS can be accessed by navigating back. * Create fullscreenmap.inc.php Notice the line: $pagetitle[] = 'Fullscreen Map'; * REmoved the original fullscreenmap.php * Revert "REmoved the original fullscreenmap.php" This reverts commit 570953c5f5902cfdc8eabfc246393e4ab9667f9b. * addded the resize event to html/pages/fullscreenmap.inc.php for proper leaflet rendering * Removed old file * Adjusted CSS and javascript. * Reverting to original javascript. * change Leaflet container CSS to white background * Made the Geographical Map not hide the menu when not in fullscreen mode. * Cleaned up the CSS-file a bit. * Added a variant of map.php which allows for a borderless fullscreen geographical map, with just the nodes. * Signed my work. * Removed a space. * delete whitespace * remove whitespace * hack to fix some tiles not loading found the fix here: https://stackoverflow.com/questions/36246815/data-toggle-tab-does-not-download-leaflet-map/36257493#36257493 https://gis.stackexchange.com/questions/224932/problem-with-map-tiles-loading-with-leaflet-and-bootstrap You might be able to do something more elegant. * added menu entry This removes the need for setting it as a front-page. Now it can be accessed from the menu and LibreNMS can be accessed by navigating back. * Create fullscreenmap.inc.php Notice the line: $pagetitle[] = 'Fullscreen Map'; * REmoved the original fullscreenmap.php * Revert "REmoved the original fullscreenmap.php" This reverts commit 570953c5f5902cfdc8eabfc246393e4ab9667f9b. * addded the resize event to html/pages/fullscreenmap.inc.php for proper leaflet rendering * Removed old file * Adjusted CSS and javascript. * Reverting to original javascript. * change Leaflet container CSS to white background * Made the Geographical Map not hide the menu when not in fullscreen mode. * Cleaned up the CSS-file a bit.
2018-03-19 04:47:06 +01:00
<li><a href="<?php echo(generate_url(array('page'=>'fullscreenmap'))); ?>"><i class="fa fa-expand fa-fw fa-lg" aria-hidden="true"></i> Geographical</a></li>
</ul>
</li>
<li class="dropdown-submenu">
2016-09-23 08:24:36 -04:00
<a><i class="fa fa-plug fa-fw fa-lg" aria-hidden="true"></i> Plugins</a>
<ul class="dropdown-menu">
<?php
\LibreNMS\Plugins::call('menu');
if (Auth::user()->hasGlobalAdmin()) {
if (dbFetchCell("SELECT COUNT(*) from `plugins` WHERE plugin_active = '1'") > 0) {
echo('<li role="presentation" class="divider"></li>');
}
2016-09-23 08:24:36 -04:00
echo('<li><a href="plugin/view=admin"> <i class="fa fa-lock fa-fw fa-lg" aria-hidden="true"></i>Plugin Admin</a></li>');
}
?>
</ul>
</li>
<li class="dropdown-submenu">
2016-09-23 08:24:36 -04:00
<a href="<?php echo(generate_url(array('page'=>'overview'))); ?>"><i class="fa fa-wrench fa-fw fa-lg" aria-hidden="true"></i> Tools</a>
<ul class="dropdown-menu scrollable-menu">
<li><a href="<?php echo(generate_url(array('page'=>'ripenccapi'))); ?>"><i class="fa fa-star fa-fw fa-lg" aria-hidden="true"></i> RIPE NCC API</a></li>
<?php
if ($config['oxidized']['enabled'] === true && isset($config['oxidized']['url'])) {
echo '<li><a href="'.generate_url(array('page'=>'oxidized')).'"><i class="fa fa-stack-overflow fa-fw fa-lg" aria-hidden="true"></i> Oxidized</a></li>';
}
?>
</ul>
</li>
<li role="presentation" class="divider"></li>
<li><a href="<?php echo(generate_url(array('page'=>'eventlog'))); ?>"><i class="fa fa-bookmark fa-fw fa-lg" aria-hidden="true"></i> Eventlog</a></li>
2015-08-10 13:36:55 -07:00
<?php
if (isset($config['enable_syslog']) && $config['enable_syslog']) {
echo ' <li><a href="'.generate_url(array('page'=>'syslog')).'"><i class="fa fa-clone fa-fw fa-lg" aria-hidden="true"></i> Syslog</a></li>';
2015-08-10 13:36:55 -07:00
}
if (isset($config['graylog']['server']) && isset($config['graylog']['port'])) {
echo ' <li><a href="'.generate_url(array('page'=>'graylog')).'"><i class="fa fa-clone fa-fw fa-lg" aria-hidden="true"></i> Graylog</a></li>';
2015-08-10 13:36:55 -07:00
}
?>
2016-09-23 08:24:36 -04:00
<li><a href="<?php echo(generate_url(array('page'=>'inventory'))); ?>"><i class="fa fa-cube fa-fw fa-lg" aria-hidden="true"></i> Inventory</a></li>
2015-08-30 17:59:05 +01:00
<?php
if (dbFetchCell("SELECT 1 from `packages` LIMIT 1")) {
2015-08-30 17:59:05 +01:00
?>
<li>
2016-09-23 08:24:36 -04:00
<a href="<?php echo(generate_url(array('page'=>'search','search'=>'packages'))); ?>"><i class="fa fa-archive fa-fw fa-lg" aria-hidden="true"></i> Packages</a>
2015-08-30 17:59:05 +01:00
</li>
<?php
} # if ($packages)
?>
<li role="presentation" class="divider"></li>
<li><a href="<?php echo(generate_url(array('page'=>'search','search'=>'ipv4'))); ?>"><i class="fa fa-search fa-fw fa-lg" aria-hidden="true"></i> IPv4 Address</a></li>
<li><a href="<?php echo(generate_url(array('page'=>'search','search'=>'ipv6'))); ?>"><i class="fa fa-search fa-fw fa-lg" aria-hidden="true"></i> IPv6 Address</a></li>
<li><a href="<?php echo(generate_url(array('page'=>'search','search'=>'mac'))); ?>"><i class="fa fa-search fa-fw fa-lg" aria-hidden="true"></i> MAC Address</a></li>
2016-09-23 08:24:36 -04:00
<li><a href="<?php echo(generate_url(array('page'=>'search','search'=>'arp'))); ?>"><i class="fa fa-search fa-fw fa-lg" aria-hidden="true"></i> ARP Tables</a></li>
<li><a href="<?php echo(generate_url(array('page'=>'search','search'=>'fdb'))); ?>"><i class="fa fa-search fa-fw fa-lg" aria-hidden="true"></i> FDB Tables</a></li>
<?php
if (is_module_enabled('poller', 'mib')) {
?>
2015-07-17 13:48:22 +10:00
<li role="presentation" class="divider"></li>
2016-09-23 08:24:36 -04:00
<li><a href="<?php echo(generate_url(array('page'=>'mibs'))); ?>"><i class="fa fa-file-text-o fa-fw fa-lg" aria-hidden="true"></i> MIB definitions</a></li>
<?php
}
?>
</ul>
</li>
<li class="dropdown">
2016-09-23 08:24:36 -04:00
<a href="devices/" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-server fa-fw fa-lg fa-nav-icons hidden-md" aria-hidden="true"></i> <span class="hidden-sm">Devices</span></a>
<ul class="dropdown-menu">
<?php
$param = array();
if (Auth::user()->hasGlobalRead()) {
2015-04-22 21:11:18 +01:00
$sql = "SELECT `type`,COUNT(`type`) AS total_type FROM `devices` AS D WHERE 1 GROUP BY `type` ORDER BY `type`";
} else {
2015-04-22 21:11:18 +01:00
$sql = "SELECT `type`,COUNT(`type`) AS total_type FROM `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` GROUP BY `type` ORDER BY `type`";
$param[] = Auth::id();
2015-04-22 21:11:18 +01:00
}
2015-07-13 20:10:26 +02:00
$device_types = dbFetchRows($sql, $param);
if (count($device_types) > 0) {
?>
<li class="dropdown-submenu">
<a href="devices/"><i class="fa fa-server fa-fw fa-lg" aria-hidden="true"></i> All Devices</a>
<ul class="dropdown-menu scrollable-menu">
<?php
foreach ($device_types as $devtype) {
if (empty($devtype['type'])) {
$devtype['type'] = 'generic';
}
echo(' <li><a href="devices/type=' . $devtype['type'] . '/"><i class="fa fa-angle-double-right fa-fw fa-lg" aria-hidden="true"></i> ' . ucfirst($devtype['type']) . '</a></li>');
}
echo ('</ul></li>');
} else {
echo '<li class="dropdown-submenu"><a href="#">No devices</a></li>';
}
2015-04-03 18:22:29 +00:00
if (count($devices_groups) > 0) {
2016-09-23 08:24:36 -04:00
echo '<li class="dropdown-submenu"><a href="#"><i class="fa fa-th fa-fw fa-lg" aria-hidden="true"></i> Device Groups</a><ul class="dropdown-menu scrollable-menu">';
foreach ($devices_groups as $group) {
2016-09-23 08:24:36 -04:00
echo '<li><a href="'.generate_url(array('page'=>'devices','group'=>$group['id'])).'" title="'.$group['desc'].'"><i class="fa fa-th fa-fw fa-lg" aria-hidden="true"></i> '.ucfirst($group['name']).'</a></li>';
}
unset($group);
echo '</ul></li>';
}
if ($config['show_locations']) {
if ($config['show_locations_dropdown']) {
$locations = getlocations();
if (count($locations) > 0) {
echo('
<li role="presentation" class="divider"></li>
<li class="dropdown-submenu">
<a href="#"><i class="fa fa-map-marker fa-fw fa-lg" aria-hidden="true"></i> Geo Locations</a>
<ul class="dropdown-menu scrollable-menu">
Refactored and update Location Geocoding (#9359) - Fix location so it is a regular database relation (this allows multiple devices to be accurately linked to one location and saves api calls) - Parse coordinates from the location more consistently - Add settings to webui - ~~Used [PHP Geocoder](http://geocoder-php.org/), which has lots of backends and is well tested. (also includes reverse and geoip)~~ - Google Maps, Bing, Mapquest, and OpenStreetMap supported initially. - Default to OpenStreetMap, which doesn't require a key. They will liberally hand out bans if you exceed 1 query per second though. - All other Geocoding APIs require an API key. (Google requires a credit card on file, but seems to be the most accurate) - Update all (I think) sql queries to handle the new structure - Remove final vestiges of override_sysLocation as a device attribute - Update existing device groups and rules in DB - Tested all APIs with good/bad location, no/bad/good key, and no connection. - Cannot fix advanced queries that use location This blocks #8868 DO NOT DELETE THIS TEXT #### Please note > Please read this information carefully. You can run `./scripts/pre-commit.php` to check your code before submitting. - [x] Have you followed our [code guidelines?](http://docs.librenms.org/Developing/Code-Guidelines/) #### Testers If you would like to test this pull request then please run: `./scripts/github-apply <pr_id>`, i.e `./scripts/github-apply 5926` After you are done testing, you can remove the changes with `./scripts/github-remove`. If there are schema changes, you can ask on discord how to revert.
2018-11-28 16:49:18 -06:00
<li><a href="locations"><i class="fa fa-map-marker fa-fw fa-lg" aria-hidden="true"></i> All Locations</a></li>
');
foreach ($locations as $location) {
echo(' <li><a href="devices/location=' . $location['id'] . '/"><i class="fa fa-building fa-fw fa-lg" aria-hidden="true"></i> ' . htmlentities($location['location']) . ' </a></li>');
}
echo('
</ul>
</li>
');
2015-07-13 20:10:26 +02:00
}
}
}
if (Auth::user()->hasGlobalAdmin()) {
echo '
<li role="presentation" class="divider"></li>';
if (is_module_enabled('poller', 'mib')) {
echo '
2016-09-23 08:24:36 -04:00
<li><a href='.generate_url(array('page'=>'mib_assoc')).'><i class="fa fa-file-text-o fa-fw fa-lg" aria-hidden="true"></i> MIB associations</a></li>
2015-12-06 19:25:24 +10:00
<li role="presentation" class="divider"></li>
';
}
if ($config['navbar']['manage_groups']['hide'] === 0) {
2016-09-23 08:24:36 -04:00
echo '<li><a href="'.generate_url(array('page'=>'device-groups')).'"><i class="fa fa-th fa-fw fa-lg" aria-hidden="true"></i> Manage Groups</a></li>';
}
feature: Added support for Host dependencies (#7332) * First draft of the modals and the config interfaces * GUI part done * Backend code and db schema addition * Documentation added, fixed alerting bug * Fix typos * Do not try to push an older db_schame.yaml * Small db fix * More db fixes * Travis CI fixes * missed a line in the travis error * Fixed dependency clearing bug, Manage Host dependencies button now shows current selections * Removed unnecessary index * Correct faulty query * Fixed sql query as requested, and renamed sql file * Added requested changes * Removed debug code * Renamed sql file * More fixes as requested * Trying to fix db_schema.yaml * adding laf's diff * Corrected a small bug * Try to resolve scrutinizer issue * Main page bootgrid ajax modifications * Also corrected travis ci errors * Added select2 for pull downs, removed a redundant debug output. Changed parent_id to text * Add missing class in the device settings page * Fix bug where a link wasn't added after save * Better parent down detection * Add missing comma * Behold the multi-parent code * Added lookup table * Ready for testing * Trying to fix documentation conflicts * Fix copy paste errors, and possible sql injection * indentation problems * Modified db_schema.yaml as well * Typos, typos * This should correct alerts * Try to fix travis ci error * Fix the typo in index.php * Changed to Tony's query * function explanation text changed * Updated db_schema.yaml * Trying to make automated tests happy * Changes as requested * Added acknowledgment for select2 * Added laf's patch * dbBulkInsert when adding parents
2017-12-20 17:17:52 +03:00
echo '<li><a href="'.generate_url(array('page'=>'device-dependencies')).'"><i class="fa fa-group fa-fw fa-lg"></i> Device Dependencies</a></li>';
$vm_count = dbFetchCell('SELECT COUNT(id) from `vminfo`');
if ($vm_count > 0) {
echo '<li><a href="'.generate_url(array('page'=>'vminfo')).'"><i class="fa fa-cog fa-fw fa-lg"></i> Virtual Machines</a></li>';
}
echo '
<li role="presentation" class="divider"></li>
<li><a href="addhost/"><i class="fa fa-plus fa-fw fa-lg" aria-hidden="true"></i> Add Device</a></li>
<li><a href="delhost/"><i class="fa fa-trash fa-fw fa-lg" aria-hidden="true"></i> Delete Device</a></li>';
}
?>
</ul>
</li>
<?php
2015-07-13 20:10:26 +02:00
if ($config['show_services']) {
?>
<li class="dropdown">
2016-09-23 08:24:36 -04:00
<a href="services/" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-cogs fa-fw fa-lg fa-nav-icons hidden-md" aria-hidden="true"></i> <span class="hidden-sm">Services</span></a>
<ul class="dropdown-menu">
2016-09-23 08:24:36 -04:00
<li><a href="services/"><i class="fa fa-cogs fa-fw fa-lg" aria-hidden="true"></i> All Services </a></li>
<?php
if (($service_status[1] > 0) || ($service_status[2] > 0)) {
echo ' <li role="presentation" class="divider"></li>';
if ($service_status[1] > 0) {
echo ' <li><a href="services/state=warning/"><i class="fa fa-bell fa-col-warning fa-fw fa-lg" aria-hidden="true"></i> Warning ('.$service_status[1].')</a></li>';
}
if ($service_status[2] > 0) {
echo ' <li><a href="services/state=critical/"><i class="fa fa-bell fa-col-danger fa-fw fa-lg" aria-hidden="true"></i> Critical ('.$service_status[2].')</a></li>';
}
}
if (Auth::user()->hasGlobalAdmin()) {
2015-07-13 20:10:26 +02:00
echo('
<li role="presentation" class="divider"></li>
<li><a href="addsrv/"><i class="fa fa-plus fa-fw fa-lg" aria-hidden="true"></i> Add Service</a></li>');
}
?>
</ul>
</li>
<?php
}
?>
<!-- PORTS -->
<li class="dropdown">
2016-09-23 08:24:36 -04:00
<a href="ports/" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-link fa-fw fa-lg fa-nav-icons hidden-md" aria-hidden="true"></i> <span class="hidden-sm">Ports</span></a>
<ul class="dropdown-menu">
2016-09-23 08:24:36 -04:00
<li><a href="ports/"><i class="fa fa-link fa-fw fa-lg" aria-hidden="true"></i> All Ports</a></li>
<?php
$ports = new ObjectCache('ports');
2015-07-13 20:10:26 +02:00
if ($ports['errored'] > 0) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="ports/errors=1/"><i class="fa fa-exclamation-circle fa-fw fa-lg" aria-hidden="true"></i> Errored ('.$ports['errored'].')</a></li>');
}
2015-07-13 20:10:26 +02:00
if ($ports['ignored'] > 0) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="ports/ignore=1/"><i class="fa fa-question-circle fa-fw fa-lg" aria-hidden="true"></i> Ignored ('.$ports['ignored'].')</a></li>');
}
if ($config['enable_billing']) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="bills/"><i class="fa fa-money fa-fw fa-lg" aria-hidden="true"></i> Traffic Bills</a></li>');
2015-07-13 20:10:26 +02:00
$ifbreak = 1;
}
if ($config['enable_pseudowires']) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="pseudowires/"><i class="fa fa-arrows-alt fa-fw fa-lg" aria-hidden="true"></i> Pseudowires</a></li>');
2015-07-13 20:10:26 +02:00
$ifbreak = 1;
}
?>
<?php
if (Auth::user()->hasGlobalRead()) {
2015-07-13 20:10:26 +02:00
echo(' <li role="presentation" class="divider"></li>');
if ($config['int_customers']) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="customers/"><i class="fa fa-users fa-fw fa-lg" aria-hidden="true"></i> Customers</a></li>');
2015-07-13 20:10:26 +02:00
$ifbreak = 1;
}
if ($config['int_l2tp']) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="iftype/type=l2tp/"><i class="fa fa-link fa-fw fa-lg" aria-hidden="true"></i> L2TP</a></li>');
2015-07-13 20:10:26 +02:00
$ifbreak = 1;
}
if ($config['int_transit']) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="iftype/type=transit/"><i class="fa fa-truck fa-fw fa-lg" aria-hidden="true"></i> Transit</a></li>');
2015-07-13 20:10:26 +02:00
$ifbreak = 1;
}
if ($config['int_peering']) {
echo(' <li><a href="iftype/type=peering/"><i class="fa fa-handshake-o fa-fw fa-lg" aria-hidden="true"></i> Peering</a></li>');
2015-07-13 20:10:26 +02:00
$ifbreak = 1;
}
if ($config['int_peering'] && $config['int_transit']) {
echo(' <li><a href="iftype/type=peering,transit/"><i class="fa fa-rocket fa-fw fa-lg" aria-hidden="true"></i> Peering + Transit</a></li>');
2015-07-13 20:10:26 +02:00
$ifbreak = 1;
}
if ($config['int_core']) {
echo(' <li><a href="iftype/type=core/"><i class="fa fa-code-fork fa-fw fa-lg" aria-hidden="true"></i> Core</a></li>');
2015-07-13 20:10:26 +02:00
$ifbreak = 1;
}
if (is_array($config['custom_descr']) === false) {
$config['custom_descr'] = array($config['custom_descr']);
}
foreach ($config['custom_descr'] as $custom_type) {
if (!empty($custom_type)) {
2016-09-23 08:24:36 -04:00
echo ' <li><a href="iftype/type=' . urlencode(strtolower($custom_type)) . '"><i class="fa fa-connectdevelop fa-fw fa-lg" aria-hidden="true"></i> ' . ucfirst($custom_type) . '</a></li>';
$ifbreak = 1;
}
}
}
if ($ifbreak) {
2015-07-13 20:10:26 +02:00
echo(' <li role="presentation" class="divider"></li>');
}
2015-07-13 20:10:26 +02:00
if (isset($interface_alerts)) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="ports/alerted=yes/"><i class="fa fa-exclamation-circle fa-fw fa-lg" aria-hidden="true"></i> Alerts ('.$interface_alerts.')</a></li>');
}
$deleted_ports = 0;
2015-07-13 20:10:26 +02:00
foreach (dbFetchRows("SELECT * FROM `ports` AS P, `devices` as D WHERE P.`deleted` = '1' AND D.device_id = P.device_id") as $interface) {
if (port_permitted($interface['port_id'], $interface['device_id'])) {
2015-07-13 20:10:26 +02:00
$deleted_ports++;
}
}
?>
<li><a href="ports/state=down/"><i class="fa fa-arrow-circle-down fa-fw fa-lg" aria-hidden="true"></i> Down</a></li>
<li><a href="ports/state=admindown/"><i class="fa fa-arrow-circle-o-down fa-fw fa-lg" aria-hidden="true"></i> Disabled</a></li>
<?php
2015-07-13 20:10:26 +02:00
if ($deleted_ports) {
echo(' <li><a href="ports/deleted=yes/"><i class="fa fa-minus-circle fa-fw fa-lg" aria-hidden="true"></i> Deleted ('.$deleted_ports.')</a></li>');
2015-07-13 20:10:26 +02:00
}
?>
</ul>
</li>
<?php
// FIXME does not check user permissions...
2015-07-13 20:10:26 +02:00
foreach (dbFetchRows("SELECT sensor_class,COUNT(sensor_id) AS c FROM sensors GROUP BY sensor_class ORDER BY sensor_class ") as $row) {
$used_sensors[$row['sensor_class']] = $row['c'];
}
# Copy the variable so we can use $used_sensors later in other parts of the code
$menu_sensors = $used_sensors;
?>
<li class="dropdown">
2016-09-23 08:24:36 -04:00
<a href="health/" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-heartbeat fa-fw fa-lg fa-nav-icons hidden-md" aria-hidden="true"></i> <span class="hidden-sm">Health</span></a>
<ul class="dropdown-menu">
<li><a href="health/metric=mempool/"><i class="fa fa-braille fa-fw fa-lg" aria-hidden="true"></i> Memory</a></li>
<li><a href="health/metric=processor/"><i class="fa fa-microchip fa-fw fa-lg" aria-hidden="true"></i> Processor</a></li>
2016-09-23 08:24:36 -04:00
<li><a href="health/metric=storage/"><i class="fa fa-database fa-fw fa-lg" aria-hidden="true"></i> Storage</a></li>
<?php
2015-07-13 20:10:26 +02:00
if ($menu_sensors) {
$sep = 0;
echo(' <li role="presentation" class="divider"></li>');
}
$icons = array(
'fanspeed' => 'tachometer',
'humidity' => 'tint',
'temperature' => 'thermometer-full',
'current' => 'bolt',
'frequency' => 'line-chart',
'power' => 'power-off',
'voltage' => 'bolt',
'charge' => 'battery-half',
'dbm' => 'sun-o',
'load' => 'percent',
'runtime' => 'hourglass-half',
'state' => 'bullseye',
'signal' => 'wifi',
'snr' => 'signal',
'pressure' => 'thermometer-empty',
'cooling' => 'thermometer-full',
'airflow' => 'angle-double-right',
'delay' => 'clock-o',
'chromatic_dispersion' => 'indent',
'ber' => 'sort-amount-desc',
'quality_factor' => 'arrows',
'eer' => 'snowflake-o',
'waterflow' => 'tint',
);
2016-03-22 10:37:07 -04:00
foreach (array('fanspeed','humidity','temperature','signal') as $item) {
2015-07-13 20:10:26 +02:00
if (isset($menu_sensors[$item])) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="health/metric='.$item.'/"><i class="fa fa-'.$icons[$item].' fa-fw fa-lg" aria-hidden="true"></i> '.nicecase($item).'</a></li>');
unset($menu_sensors[$item]);
$sep++;
2015-07-13 20:10:26 +02:00
}
}
2015-07-13 20:10:26 +02:00
if ($sep && array_keys($menu_sensors)) {
echo(' <li role="presentation" class="divider"></li>');
$sep = 0;
}
2015-07-13 20:10:26 +02:00
foreach (array('current','frequency','power','voltage') as $item) {
if (isset($menu_sensors[$item])) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="health/metric='.$item.'/"><i class="fa fa-'.$icons[$item].' fa-fw fa-lg" aria-hidden="true"></i> '.nicecase($item).'</a></li>');
unset($menu_sensors[$item]);
$sep++;
2015-07-13 20:10:26 +02:00
}
}
2015-07-13 20:10:26 +02:00
if ($sep && array_keys($menu_sensors)) {
echo(' <li role="presentation" class="divider"></li>');
$sep = 0;
}
2015-07-13 20:10:26 +02:00
foreach (array_keys($menu_sensors) as $item) {
2016-09-23 08:24:36 -04:00
echo(' <li><a href="health/metric='.$item.'/"><i class="fa fa-'.$icons[$item].' fa-fw fa-lg" aria-hidden="true"></i> '.nicecase($item).'</a></li>');
unset($menu_sensors[$item]);
$sep++;
}
$toner = new ObjectCache('toner');
if ($toner) {
echo '<li role="presentation" class="divider"></li>';
echo '<li><a href="health/metric=toner/"><i class="fa fa-print fa-fw fa-lg"></i> Toner</a></li>';
$used_sensors['toner'] = $toner;
}
?>
</ul>
</li>
<?php
feature: Wireless Sensors Overhaul (#6471) * feature: Wireless Sensors Includes client counts for ios and unifi Graphing could use some improvement. Alerting and threshold ui not implemented WIP: starting OO based wireless sensors. Class based functionality working remove old functional files add schema file discovery needs to be enabled, not polling fix up schema fix Unifi discovery not returning an array Add some debug when discovering a sensor. Fix style. Add missing semicolin Add a null object (Generic) for OS. Fill out some phpdocs Re-organized code Each sensor type now has it's own discovery and polling interface Custom polling tested with Unifi CCQ Left to do: Implement UI (Graphs and Custom thresholds) Alerting Testing Fix event message text Remove runDiscovery and runPolling from OS, they are unused and don't belong there. Cleanups/docs Missed this file. Remove the requirement to fetch the current value to check validity. Do that automatically if current is not specified A few cleanups here and there First pass at graphing. device_ and wireless_ graphs added. Add RouterOS support Singleton OS instance isn't required right now. Remove that to allow some memory to be freed. Add wireless to the device list metrics. Make all metrics clickable Tweak graphs a bit Implement limit configuration page. Use sensors page as common code instead of duplicating. Clean up some javascript interactions: Allow enter on values to save. Cancel if update is not needed. Enable the clear custom button after setting a custom value. Add some wireless alert rules to the library. Add documentation. Add unifi client counts by ssid in addition to radio. Optimize Sensor polling a bit. Add HP MSM clients support (for full controller) Fix function accessibility Formalize the discovery and poller interfaces. Add Xirrus clients and noise floor move module interfaces to a more appropriate place. push caching code up to os, unsure about this do to the limitations No point in selectively enabling wireless discovery. We only discover if the device supports something. Add RSSI, Power, and Rate. Add these sensors for Ubnt Airos. Clean up some copyrights. Reduce the amount of files need to add new types. Leave graph files for consistency and to allow customization. Remove the old wifi clients graph completely. ciscowlc should have improved counts (total and per-ssid) Schema didn't get added. Impelement the rest of the AirOS sensors Reformat and re-organize the Airos.php class. Add several UBNT AirFiber sensors A few fixes add links to the section headers Add HP MSM mibs. * Schema file got dropped in rebase. * Add wireless menu to view sensors across all devices. Icons in the menu need help :/ * Add HeliOS, Mimosa, and Siklu support Sensors added SNR + Noise * Add power and utilization to Unifi * Update polling to prefetch all sensor data in a few snmp requests as possible * Add Extendair: tx+rx power, aggregate rate, frequency * Add a check for duplicate sensors in discovery. Just print an error for now. * Add Bit Error Ratio (named error-ratio to allow for bit error rate to be added if needed) Fix an incorrect link in the wireless sensors table * Add error rate and change all bps and Hz to use si units * Fixes to limits and frequency display * Fix overview graph frequency display A few decimal place tweaks * Don't allow switching sensor and wireless-sensor graphs, it doesn't work. Change individual distance graphs to use si units * Go through the OS and make sure I got all the sensors I can (probably missed some still) Because pollWirelessChannelAsFrequency() is generic and a little complex, so pull it up to OS. Message to help developers adding supports that don't return an array from discover functions. * Fix some issues * Remove noise and signal for now at least A couple more fixes Add a notification * Oopsie * Bonus AirFiber sensors
2017-05-01 23:49:11 -05:00
$valid_wireless_types = WirelessSensor::getTypes(true);
if (!empty($valid_wireless_types)) {
echo '<li class="dropdown">
<a href="wireless/" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown">
<i class="fa fa-wifi fa-fw fa-lg fa-nav-icons hidden-md" aria-hidden="true"></i> <span class="hidden-sm">Wireless</span></a>
<ul class="dropdown-menu">';
foreach ($valid_wireless_types as $type => $meta) {
echo '<li><a href="wireless/metric='.$type.'/">';
echo '<i class="fa fa-'.$meta['icon'].' fa-fw fa-lg" aria-hidden="true"></i> ';
echo $meta['short'];
echo '</a></li>';
}
echo '</ul></li>';
}
$app_list = dbFetchRows("SELECT DISTINCT(`app_type`) AS `app_type` FROM `applications` ORDER BY `app_type`");
if (Auth::user()->hasGlobalRead() && count($app_list) > "0") {
?>
<li class="dropdown">
2016-09-23 08:24:36 -04:00
<a href="apps/" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-tasks fa-fw fa-lg fa-nav-icons hidden-md" aria-hidden="true"></i> <span class="hidden-sm">Apps</span></a>
<ul class="dropdown-menu">
<li><a href="apps/"><i class="fa fa-object-group fa-fw fa-lg" aria-hidden="true"></i> Overview</a></li>
<?php
foreach ($app_list as $app) {
if (isset($app['app_type'])) {
$app_i_list = dbFetchRows("SELECT DISTINCT(`app_instance`) FROM `applications` WHERE `app_type` = ? ORDER BY `app_instance`", array($app['app_type']));
if (count($app_i_list) > 1) {
echo '<li class="dropdown-submenu">';
2016-09-23 08:24:36 -04:00
echo '<a href="apps/app='.$app['app_type'].'/"><i class="fa fa-server fa-fw fa-lg" aria-hidden="true"></i> '.nicecase($app['app_type']).' </a>';
echo '<ul class="dropdown-menu scrollable-menu">';
foreach ($app_i_list as $instance) {
2016-09-23 08:24:36 -04:00
echo ' <li><a href="apps/app='.$app['app_type'].'/instance='.$instance['app_instance'].'/"><i class="fa fa-angle-double-right fa-fw fa-lg" aria-hidden="true"></i> ' . nicecase($instance['app_instance']) . '</a></li>';
}
echo '</ul></li>';
} else {
2016-09-23 08:24:36 -04:00
echo('<li><a href="apps/app='.$app['app_type'].'/"><i class="fa fa-angle-double-right fa-fw fa-lg" aria-hidden="true"></i> '.nicecase($app['app_type']).' </a></li>');
2015-07-13 20:10:26 +02:00
}
}
}
?>
</ul>
2015-07-13 20:10:26 +02:00
</li>
<?php
}
$routing_count['bgp'] = dbFetchCell("SELECT COUNT(bgpPeer_id) from `bgpPeers` LEFT JOIN devices AS D ON bgpPeers.device_id=D.device_id WHERE D.device_id IS NOT NULL");
$routing_count['ospf'] = dbFetchCell("SELECT COUNT(ospf_instance_id) FROM `ospf_instances` WHERE `ospfAdminStat` = 'enabled'");
$routing_count['cef'] = dbFetchCell("SELECT COUNT(cef_switching_id) from `cef_switching`");
$routing_count['vrf'] = dbFetchCell("SELECT COUNT(vrf_id) from `vrfs`");
$component = new LibreNMS\Component();
$options['type'] = 'Cisco-OTV';
$otv = $component->getComponents(null, $options);
$routing_count['cisco-otv'] = count($otv);
if (Auth::user()->hasGlobalRead() && ($routing_count['bgp']+$routing_count['ospf']+$routing_count['cef']+$routing_count['vrf']+$routing_count['cisco-otv']) > "0") {
?>
<li class="dropdown">
<a href="routing/" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-random fa-fw fa-lg fa-nav-icons hidden-md" aria-hidden="true"></i> <span class="hidden-sm">Routing</span></a>
<ul class="dropdown-menu">
<?php
2015-07-13 20:10:26 +02:00
$separator = 0;
if (Auth::user()->hasGlobalRead() && $routing_count['vrf']) {
echo(' <li><a href="routing/protocol=vrf/"><i class="fa fa-arrows fa-fw fa-lg" aria-hidden="true"></i> VRFs</a></li>');
$separator++;
}
2015-07-13 20:10:26 +02:00
if (Auth::user()->hasGlobalRead() && $routing_count['ospf']) {
if ($separator) {
echo(' <li role="presentation" class="divider"></li>');
$separator = 0;
}
2016-09-23 08:24:36 -04:00
echo('<li><a href="routing/protocol=ospf/"><i class="fa fa-circle-o-notch fa-rotate-180 fa-fw fa-lg" aria-hidden="true"></i> OSPF Devices </a></li>');
$separator++;
}
2015-07-13 20:10:26 +02:00
// Cisco OTV Links
if (Auth::user()->hasGlobalRead() && $routing_count['cisco-otv']) {
if ($separator) {
echo(' <li role="presentation" class="divider"></li>');
$separator = 0;
}
2016-09-23 08:24:36 -04:00
echo('<li><a href="routing/protocol=cisco-otv/"><i class="fa fa-exchange fa-fw fa-lg" aria-hidden="true"></i> Cisco OTV </a></li>');
$separator++;
}
2015-07-13 20:10:26 +02:00
// BGP Sessions
if (Auth::user()->hasGlobalRead() && $routing_count['bgp']) {
if ($separator) {
echo(' <li role="presentation" class="divider"></li>');
$separator = 0;
}
echo('<li><a href="routing/protocol=bgp/type=all/graph=NULL/"><i class="fa fa-circle-o fa-fw fa-lg" aria-hidden="true"></i> BGP All Sessions </a></li>
2016-09-23 08:24:36 -04:00
<li><a href="routing/protocol=bgp/type=external/graph=NULL/"><i class="fa fa-external-link fa-fw fa-lg" aria-hidden="true"></i> BGP External</a></li>
<li><a href="routing/protocol=bgp/type=internal/graph=NULL/"><i class="fa fa-external-link fa-rotate-180 fa-fw fa-lg" aria-hidden="true"></i> BGP Internal</a></li>');
}
// CEF info
if (Auth::user()->hasGlobalRead() && $routing_count['cef']) {
if ($separator) {
echo(' <li role="presentation" class="divider"></li>');
$separator = 0;
}
echo('<li><a href="routing/protocol=cef/"><i class="fa fa-exchange fa-fw fa-lg" aria-hidden="true"></i> Cisco CEF </a></li>');
$separator++;
}
// Do Alerts at the bottom
if ($bgp_alerts) {
echo('
<li role="presentation" class="divider"></li>
2016-09-23 08:24:36 -04:00
<li><a href="routing/protocol=bgp/adminstatus=start/state=down/"><i class="fa fa-exclamation-circle fa-fw fa-lg" aria-hidden="true"></i> Alerted BGP (' . $bgp_alerts . ')</a></li>');
}
if (Auth::user()->hasGlobalAdmin() && $routing_count['bgp'] && $config['peeringdb']['enabled'] === true) {
echo '
<li role="presentation" class="divider"></li>
<li><a href="peering/"><i class="fa fa-hand-o-right fa-fw fa-lg" aria-hidden="true"></i> PeeringDB</a></li>';
}
2015-07-13 20:10:26 +02:00
echo(' </ul>');
?>
</li><!-- End 4 columns container -->
<?php
}
2016-09-15 10:21:28 +01:00
$alerts = new ObjectCache('alerts');
2015-03-26 23:51:13 +00:00
2016-09-15 10:21:28 +01:00
if ($alerts['active_count'] > 0) {
$alert_colour = "danger";
} else {
$alert_colour = "success";
}
2016-09-15 10:21:28 +01:00
?>
<li class="dropdown">
2016-09-23 08:24:36 -04:00
<a href="#" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-exclamation-circle fa-col-<?php echo $alert_colour;?> fa-fw fa-lg fa-nav-icons hidden-md" aria-hidden="true"></i> <span class="hidden-sm">Alerts</span></a>
<ul class="dropdown-menu">
2016-09-23 08:24:36 -04:00
<li><a href="<?php echo(generate_url(array('page'=>'alerts'))); ?>"><i class="fa fa-bell fa-fw fa-lg" aria-hidden="true"></i> Notifications</a></li>
<li><a href="<?php echo(generate_url(array('page'=>'alert-log'))); ?>"><i class="fa fa-file-text fa-fw fa-lg" aria-hidden="true"></i> Alert History</a></li>
2016-09-23 08:24:36 -04:00
<li><a href="<?php echo(generate_url(array('page'=>'alert-stats'))); ?>"><i class="fa fa-bar-chart fa-fw fa-lg" aria-hidden="true"></i> Statistics</a></li>
<?php if (Auth::user()->hasGlobalAdmin()) { ?>
<li role="presentation" class="divider"></li>
<li><a href="<?php echo(generate_url(array('page'=>'alert-rules'))); ?>"><i class="fa fa-list fa-fw fa-lg" aria-hidden="true"></i> Alert Rules</a></li>
<li><a href="<?php echo(generate_url(array('page'=>'alert-schedule'))); ?>"><i class="fa fa-calendar fa-fw fa-lg" aria-hidden="true"></i> Scheduled Maintenance</a></li>
<li><a href="<?php echo(generate_url(array('page'=>'templates'))); ?>"><i class="fa fa-file fa-fw fa-lg" aria-hidden="true"></i> Alert Templates</a></li>
Added Alert Transports Mapping (#8660) Hello all, I guess this is the second version of a more fully fleshed out alert contact mapping feature. The old one was GH-8507 Transports to convert: - [x] API - [x] Cisco Spark - [x] Elasticsearch - [x] GitLab - [x] Philips Hue - [x] Jira - [x] Mail - [ ] ~~PagerDuty~~ - Requires a callback so leaving for now - [x] Nagios - [x] IRC - [x] Discord - [x] Rocket.chat - [x] Hipchat - [x] Pushover - [x] Boxcar - [x] Telegram - [x] Pushbullet - [x] VictorOps - [x] OpsGenie - [x] Clickatell - [x] PlaySMS - [x] Canopsis - [x] osTicket - [x] Microsoft Teams - [x] SMSEagle - [x] Syslog - [x] Slack The intention is for this feature to have three different levels to it: 1. Alert rule to an alert contact mapping (where the code is at now) 2. Alert rule to an alert group (made up of alert contacts) mapping 3. Alert contact mapping to different transport configurations. There will be three transport configuration types. 1. Default (the configuration that is held in the configs table) 2. None (no transport configuration - will explain later) 3. Other (a configuration that will be defined in a different able) Take Mail transport for example. It can either be of a "default" or "other" configuration. The hope is that in the future, users can send mail from different mail servers if they wish. However, for ciscospark which requires a room ID and an api-token, I've decided that it has no transport configuration. Most likely, every alert contact will contain a different room-id and an api-token - which is why it has the transport config of "none". For other transports : I am not familiar with them, so hopefully the community can add support for these. I can definitely help! To add support for each transport will require several things: - addition to the UI - addition to forms/alert-contacts.inc.php - modifications to its object class Screenshots ![image](https://user-images.githubusercontent.com/28970851/39594533-2092ce9e-4eca-11e8-9c5d-cd002ece1425.png) ![image](https://user-images.githubusercontent.com/28970851/39594544-276e9856-4eca-11e8-80cc-82789ee0b2b2.png) ![image](https://user-images.githubusercontent.com/28970851/39594553-2fdf528c-4eca-11e8-8a40-4f149e767054.png) I'm not sure if this is the best way to do things, so please let me know if there's a better way to structure the code! Any comments on code/db schema,/UI etc is welcome and encouraged! The UI is heavily based on alert rules (front end is not my strong suit). And parts of the code are based on the code that was written for alert rules. DO NOT DELETE THIS TEXT #### Please note > Please read this information carefully. You can run `./scripts/pre-commit.php` to check your code before submitting. - [x] Have you followed our [code guidelines?](http://docs.librenms.org/Developing/Code-Guidelines/) #### Testers If you would like to test this pull request then please run: `./scripts/github-apply <pr_id>`, i.e `./scripts/github-apply 5926`
2018-07-21 13:34:59 -06:00
<li><a href="<?php echo(generate_url(array('page'=>'alert-transports'))); ?>"><i class="fa fa-bus fa-fw fa-lg" aria-hidden="true"></i> Alert Transports</a></li>
<?php } ?>
</ul>
</li>
<?php
// Custom menubar entries.
if (is_file("includes/print-menubar-custom.inc.php")) {
2015-07-13 20:10:26 +02:00
require 'includes/print-menubar-custom.inc.php';
}
?>
</ul>
<form role="search" class="navbar-form navbar-right global-search">
<div class="form-group">
<input class="form-control typeahead" type="search" id="gsearch" name="gsearch" placeholder="Global Search">
</div>
</form>
<ul class="nav navbar-nav navbar-right">
2015-12-09 23:56:12 +01:00
<li class="dropdown">
<?php
$notifications = new ObjectCache('notifications');
$style = '';
if (empty($notifications['count']) && empty($notifications['sticky_count'])) {
$class = 'badge-default';
} else {
$class = 'badge-danger';
}
echo('<a href="#" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-user fa-fw fa-lg fa-nav-icons" aria-hidden="true"></i> <span class="visible-xs-inline-block">User</span><span class="badge badge-navbar-user count-notif '.$class.'">'.($notifications['sticky_count']+$notifications['count']).'</span></a>');
?>
2015-12-09 23:56:12 +01:00
<ul class="dropdown-menu">
2016-09-23 08:24:36 -04:00
<li><a href="preferences/"><i class="fa fa-cog fa-fw fa-lg" aria-hidden="true"></i> My Settings</a></li>
2015-12-11 22:00:26 +01:00
<?php
$notifications = new ObjectCache('notifications');
2015-12-11 22:00:26 +01:00
echo ('<li><a href="notifications/"><span class="badge count-notif">'.($notifications['sticky_count']+$notifications['count']).'</span> Notifications</a></li>');
?>
2015-12-09 23:56:12 +01:00
<li role="presentation" class="divider"></li>
<?php
2015-12-09 23:56:12 +01:00
if (Auth::check()) {
echo '<li><a href="';
echo route('logout');
echo '" onclick="event.preventDefault(); document.getElementById(\'logout-form\').submit();">';
echo ' <i class="fa fa-sign-out fa-fw fa-lg" aria-hidden="true"></i> ';
echo __('Logout');
echo '</a><form id="logout-form" action="';
echo route('logout');
echo '" method="POST" style="display: none;">';
echo csrf_field();
echo '</form></li>';
2015-12-09 23:56:12 +01:00
}
?>
</ul>
</li>
<li class="dropdown">
2016-09-23 08:24:36 -04:00
<a href="#" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown" style="margin-left:5px"><i class="fa fa-cog fa-fw fa-lg fa-nav-icons" aria-hidden="true"></i> <span class="visible-xs-inline-block">Settings</span></a>
<ul class="dropdown-menu">
<?php
if (Auth::user()->hasGlobalAdmin()) {
2016-09-23 08:24:36 -04:00
echo('<li><a href="settings/"><i class="fa fa-cogs fa-fw fa-lg" aria-hidden="true"></i> Global Settings</a></li>');
echo('<li><a href="validate/"><i class="fa fa-check-circle fa-fw fa-lg" aria-hidden="true"></i> Validate Config</a></li>');
}
2015-07-13 20:10:26 +02:00
?>
<li role="presentation" class="divider"></li>
<?php if (Auth::user()->hasGlobalAdmin()) {
if (LegacyAuth::get()->canManageUsers()) {
2015-07-13 20:10:26 +02:00
echo('
2016-09-23 08:24:36 -04:00
<li><a href="adduser/"><i class="fa fa-user-plus fa-fw fa-lg" aria-hidden="true"></i> Add User</a></li>
<li><a href="deluser/"><i class="fa fa-user-times fa-fw fa-lg" aria-hidden="true"></i> Remove User</a></li>
2015-07-13 20:10:26 +02:00
');
}
echo('
<li><a href="edituser/"><i class="fa fa-user-circle-o fa-fw fa-lg" aria-hidden="true"></i> Edit User</a></li>
<li><a href="authlog/"><i class="fa fa-shield fa-fw fa-lg" aria-hidden="true"></i> Auth History</a></li>
2015-07-13 20:10:26 +02:00
<li role="presentation" class="divider"></li> ');
echo('
<li class="dropdown-submenu">
<a href="pollers"><i class="fa fa-th-large fa-fw fa-lg" aria-hidden="true"></i> Pollers</a>
<ul class="dropdown-menu scrollable-menu">
<li><a href="pollers/tab=pollers/"><i class="fa fa-th-large fa-fw fa-lg" aria-hidden="true"></i> Pollers</a></li>');
2015-03-25 22:05:51 +01:00
if ($config['distributed_poller'] === true) {
2015-07-13 20:10:26 +02:00
echo ('
<li><a href="pollers/tab=groups/"><i class="fa fa-th fa-fw fa-lg" aria-hidden="true"></i> Groups</a></li>');
2015-07-13 20:10:26 +02:00
}
echo ' <li><a href="pollers/tab=performance/"><i class="fa fa-line-chart fa-fw fa-lg" aria-hidden="true"></i> Performance</a></li>';
echo ' <li><a href="pollers/tab=log/"><i class="fa fa-file-text fa-fw fa-lg" aria-hidden="true"></i> History</a></li>';
2015-07-13 20:10:26 +02:00
echo ('
</ul>
</li>
2015-07-13 20:10:26 +02:00
<li role="presentation" class="divider"></li>');
echo('
<li class="dropdown-submenu">
2016-09-23 08:24:36 -04:00
<a href="#"><i class="fa fa-code fa-fw fa-lg" aria-hidden="true"></i> API</a>
<ul class="dropdown-menu scrollable-menu">
<li><a href="api-access/"><i class="fa fa-cog fa-fw fa-lg" aria-hidden="true"></i> API Settings</a></li>
<li><a href="https://docs.librenms.org/API/" target="_blank" rel="noopener"><i class="fa fa-book fa-fw fa-lg" aria-hidden="true"></i> API Docs</a></li>
</ul>
</li>
<li role="presentation" class="divider"></li>');
2015-10-05 12:27:12 -03:00
}
2015-07-13 20:10:26 +02:00
if (Auth::check()) {
2015-07-13 20:10:26 +02:00
echo('
<li class="dropdown-submenu">
<a href="#"><span class="countdown_timer" id="countdown_timer"></span></a>
<ul class="dropdown-menu scrollable-menu">
<li><a href="#"><span class="countdown_timer_status" id="countdown_timer_status"></span></a></li>
</ul>
2015-12-09 23:56:12 +01:00
</li>');
}
?>
<li role="presentation" class="divider"></li>
<li><a href="about/"><i class="fa fa-info-circle fa-fw fa-lg" aria-hidden="true"></i> About&nbsp;<?php echo($config['project_name']); ?></a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<script>
var devices = new Bloodhound({
2015-05-03 23:15:00 +01:00
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "ajax_search.php?search=%QUERY&type=device",
filter: function (devices) {
return $.map(devices, function (device) {
return {
device_id: device.device_id,
device_image: device.device_image,
url: device.url,
name: device.name,
device_os: device.device_os,
version: device.version,
device_hardware: device.device_hardware,
device_ports: device.device_ports,
location: device.location
};
});
},
wildcard: "%QUERY"
}
});
var ports = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "ajax_search.php?search=%QUERY&type=ports",
filter: function (ports) {
return $.map(ports, function (port) {
return {
count: port.count,
url: port.url,
name: port.name,
description: port.description,
colours: port.colours,
hostname: port.hostname
};
});
},
wildcard: "%QUERY"
}
});
var bgp = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "ajax_search.php?search=%QUERY&type=bgp",
filter: function (bgp_sessions) {
return $.map(bgp_sessions, function (bgp) {
return {
count: bgp.count,
url: bgp.url,
name: bgp.name,
description: bgp.description,
localas: bgp.localas,
bgp_image: bgp.bgp_image,
remoteas: bgp.remoteas,
colours: bgp.colours,
hostname: bgp.hostname
};
});
},
wildcard: "%QUERY"
}
});
if ($(window).width() < 768) {
var cssMenu = 'typeahead-left';
} else {
var cssMenu = '';
}
devices.initialize();
ports.initialize();
bgp.initialize();
$('#gsearch').bind('typeahead:select', function(ev, suggestion) {
window.location.href = suggestion.url;
});
$('#gsearch').typeahead({
hint: true,
highlight: true,
minLength: 1,
classNames: {
menu: cssMenu
}
},
{
source: devices.ttAdapter(),
limit: '<?php echo($typeahead_limit); ?>',
async: true,
2015-05-03 23:15:00 +01:00
display: 'name',
valueKey: 'name',
templates: {
header: '<h5><strong>&nbsp;Devices</strong></h5>',
2015-05-03 14:08:45 +01:00
suggestion: Handlebars.compile('<p><a href="{{url}}"><img src="{{device_image}}" border="0"> <small><strong>{{name}}</strong> | {{device_os}} | {{version}} | {{device_hardware}} with {{device_ports}} port(s) | {{location}}</small></a></p>')
}
},
{
source: ports.ttAdapter(),
limit: '<?php echo($typeahead_limit); ?>',
async: true,
2015-05-03 23:15:00 +01:00
display: 'name',
valueKey: 'name',
templates: {
header: '<h5><strong>&nbsp;Ports</strong></h5>',
suggestion: Handlebars.compile('<p><a href="{{url}}"><small><i class="fa fa-link fa-sm icon-theme" aria-hidden="true"></i> <strong>{{name}}</strong> {{hostname}}<br /><i>{{description}}</i></small></a></p>')
}
},
{
source: bgp.ttAdapter(),
limit: '<?php echo($typeahead_limit); ?>',
async: true,
2015-05-03 23:15:00 +01:00
display: 'name',
valueKey: 'name',
templates: {
header: '<h5><strong>&nbsp;BGP Sessions</strong></h5>',
suggestion: Handlebars.compile('<p><a href="{{url}}"><small>{{{bgp_image}}} {{name}} - {{hostname}}<br />AS{{localas}} -> AS{{remoteas}}</small></a></p>')
}
});
$('#gsearch').bind('typeahead:open', function(ev, suggestion) {
$('#gsearch').addClass('search-box');
});
</script>