diff --git a/AUTHORS.md b/AUTHORS.md index 587faee6e..e37abce85 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -63,5 +63,18 @@ Contributors to LibreNMS: - Falk Stern (fstern) - Donovan Bridoux (PandaWawawa) - Sebastian Neuner (9er) - +- Robert Zollner (Lupul) +- Richard Hartmann (RichiH) +- Robert Gornall (rgormley) +- Richard Kojedzinszky (rkojedzinszky) +- Tony Murray (murrant) +- Peter Lamperud (vizay) +- Louis Bailleul (alucardfh) +- Rick Hodger (Tatermen) +- Eldon Koyle (ekoyle) +- Jonathan Bailey (jcbailey2) +- Ruairi Carroll (rucarrol) +- Maxim Tsyplakov (tsypa) +- D. Britz (flatterlight) [1]: http://observium.org/ "Observium web site" diff --git a/Makefile b/Makefile index 92d8dddf1..1b168dd16 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ typeahead: $(GIT_SUBTREE) --prefix=lib/typeahead https://github.com/twitter/typeahead.js.git master gridster: - $(GIT_SUBTREE) --prefix=lib/gridster https://github.com/ducksboard/gridster.js.git master + $(GIT_SUBTREE) --prefix=lib/gridster https://github.com/dsmorse/gridster.js.git master jquery-mapael: $(GIT_SUBTREE) --prefix=lib/jQuery-Mapael https://github.com/neveldo/jQuery-Mapael.git master diff --git a/addhost.php b/addhost.php index f0719cc5e..2280c54e3 100755 --- a/addhost.php +++ b/addhost.php @@ -203,5 +203,5 @@ print $console_color->convert( -f forces the device to be added by skipping the icmp and snmp check against the host. %rRemember to run discovery for the host afterwards.%n - ' +' ); diff --git a/alerts.php b/alerts.php index dc8e9949a..9d6defca5 100755 --- a/alerts.php +++ b/alerts.php @@ -48,7 +48,7 @@ require_once $config['install_dir'].'/includes/definitions.inc.php'; require_once $config['install_dir'].'/includes/functions.php'; require_once $config['install_dir'].'/includes/alerts.inc.php'; -if (!defined('TEST')) { +if (!defined('TEST') && $config['alert']['disable'] != 'true') { echo 'Start: '.date('r')."\r\n"; echo "RunFollowUp():\r\n"; RunFollowUp(); @@ -314,6 +314,9 @@ function ExtTransports($obj) { $tmp = false; // To keep scrutinizer from naging because it doesnt understand eval foreach ($config['alert']['transports'] as $transport => $opts) { + if (is_array($opts)) { + $opts = array_filter($opts); + } if (($opts === true || !empty($opts)) && $opts != false && file_exists($config['install_dir'].'/includes/alerts/transport.'.$transport.'.php')) { echo $transport.' => '; eval('$tmp = function($obj,$opts) { global $config; '.file_get_contents($config['install_dir'].'/includes/alerts/transport.'.$transport.'.php').' return false; };'); diff --git a/check-services.php b/check-services.php index b74ae170d..55295a70f 100755 --- a/check-services.php +++ b/check-services.php @@ -31,8 +31,16 @@ foreach (dbFetchRows('SELECT * FROM `devices` AS D, `services` AS S WHERE S.devi include $checker_script; } else { - $status = '2'; - $check = "Error : Script not found ($checker_script)"; + $cmd = $config['nagios_plugins'] . "/check_" . $service['service_type'] . " -H " . ($service['service_ip'] ? $service['service_ip'] : $service['hostname']); + $cmd .= " ".$service['service_param']; + $check = shell_exec($cmd); + list($check, $time) = split("\|", $check); + if(stristr($check, "ok -")) { + $status = 1; + } + else { + $status = 0; + } } $update = array(); diff --git a/daily.php b/daily.php index e5e06884b..1c3e4d04f 100644 --- a/daily.php +++ b/daily.php @@ -13,10 +13,8 @@ require 'includes/functions.php'; $options = getopt('f:'); if ($options['f'] === 'update') { - $pool_size = dbFetchCell('SELECT @@innodb_buffer_pool_size'); - // The following query is from the excellent mysqltuner.pl by Major Hayden https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl - $pool_used = dbFetchCell('SELECT SUM(DATA_LENGTH+INDEX_LENGTH) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ("information_schema", "performance_schema", "mysql") AND ENGINE = "InnoDB" GROUP BY ENGINE ORDER BY ENGINE ASC'); - if ($pool_used > $pool_size) { + $innodb_buffer = innodb_buffer_check(); + if ($innodb_buffer['used'] > $innodb_buffer['size']) { if (!empty($config['alert']['default_mail'])) { $subject = $config['project_name'] . ' auto-update action required'; $message = ' @@ -26,22 +24,28 @@ We have just tried to update your installation but it looks like the InnoDB buff Because of this we have stopped the auto-update running to ensure your system is ok. -You currently have a configured innodb_buffer_pool_size of ' . $pool_size / 1024 / 1024 . ' MiB but is currently using ' . $pool_used / 1024 / 1024 . ' MiB +You currently have a configured innodb_buffer_pool_size of ' . $innodb_buffer['size'] / 1024 / 1024 . ' MiB but is currently using ' . $innodb_buffer['used'] / 1024 / 1024 . ' MiB Take a look at https://dev.mysql.com/doc/refman/5.6/en/innodb-buffer-pool.html for further details. The ' . $config['project_name'] . ' team.'; send_mail($config['alert']['default_mail'],$subject,$message,$html=false); - } else { - echo 'InnoDB Buffersize too small.'.PHP_EOL; - echo 'Current size: '.($pool_size / 1024 / 1024).' MiB'.PHP_EOL; - echo 'Minimum Required: '.($pool_used / 1024 / 1024).' MiB'.PHP_EOL; - echo 'To ensure integrity, we\'re not going to pull any updates until the buffersize has been adjusted.'.PHP_EOL; } + echo warn_innodb_buffer($innodb_buffer); exit(2); } else { - exit((int) $config['update']); + if ($config['update']) { + if ($config['update_channel'] == 'master') { + exit(1); + } + elseif ($config['update_channel'] == 'release') { + exit(3); + } + } + else { + exit(0); + } } } @@ -102,3 +106,23 @@ if ($options['f'] === 'device_perf') { } } } + +if ($options['f'] === 'notifications') { + include_once 'notifications.php'; +} + +if ($options['f'] === 'purgeusers') { + $purge = 0; + if (is_numeric($config['radius']['users_purge']) && $config['auth_mechanism'] === 'radius') { + $purge = $config['radius']['users_purge']; + } + if ($purge > 0) { + foreach (dbFetchRows("SELECT DISTINCT(`user`) FROM `authlog` WHERE `datetime` >= DATE_SUB(NOW(), INTERVAL ? DAY)", array($purge)) as $user) { + $users[] = $user['user']; + } + $del_users = '"'.implode('","',$users).'"'; + if (dbDelete('users', "username NOT IN ($del_users)",array($del_users))) { + echo "Removed users that haven't logged in for $purge days"; + } + } +} diff --git a/daily.sh b/daily.sh index ddc4f2e9f..795311e90 100755 --- a/daily.sh +++ b/daily.sh @@ -1,18 +1,79 @@ #!/usr/bin/env bash - -set -eu +# Copyright (C) 2015 Daniel Preussker, QuxLabs UG +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . cd "$(dirname "$0")" +arg="$1" -up=$(php daily.php -f update >&2; echo $?) -if [ "$up" -eq 1 ]; then - git pull --quiet - php includes/sql-schema/update.php +# Fancy-Print and run commands +# @arg Text +# @arg Command +# @return Exit-Code of Command +status_run() { + printf "%-50s" "$1" + echo "$1" >> logs/daily.log + tmp=$(bash -c "$2" 2>&1) + ex=$? + echo "$tmp" >> logs/daily.log + echo "Returned: $ex" >> logs/daily.log + [ $ex -eq 0 ] && echo -e ' \033[0;32mOK\033[0m' || echo -e ' \033[0;31mFAIL\033[0m' + return $ex +} + +if [ -z "$arg" ]; then + up=$(php daily.php -f update >&2; echo $?) + if [ "$up" -eq 1 ]; then + # Update to Master-Branch + status_run 'Updating to latest codebase' 'git pull --quiet' + elif [ "$up" -eq 3 ]; then + # Update to last Tag + status_run 'Updating to latest release' 'git fetch --tags && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))' + fi + + cnf=$(echo $(grep '\[.distributed_poller.\]' config.php | egrep -v -e '^//' -e '^#' | cut -d = -f 2 | sed 's/;//g')) + cnd=${cnf,,} + if [ -z "$cnf" ] || [ "$cnf" == "0" ] || [ "$cnf" == "false" ]; then + # Call ourself again in case above pull changed or added something to daily.sh + $0 post-pull + fi +else + case $arg in + post-pull) + # List all tasks to do after pull in the order of execution + status_run 'Updating SQL-Schema' 'php includes/sql-schema/update.php' + status_run 'Updating submodules' "$0 submodules" + status_run 'Cleaning up DB' "$0 cleanup" + status_run 'Fetching notifications' "$0 notifications" + ;; + cleanup) + # DB-Cleanups + php daily.php -f syslog + php daily.php -f eventlog + php daily.php -f authlog + php daily.php -f perf_times + php daily.php -f callback + php daily.php -f device_perf + php daily.php -f purgeusers + ;; + submodules) + # Init+Update our submodules + git submodule --quiet init + git submodule --quiet update + ;; + notifications) + # Get notifications + php daily.php -f notifications + ;; + esac fi - -php daily.php -f syslog -php daily.php -f eventlog -php daily.php -f authlog -php daily.php -f perf_times -php daily.php -f callback -php daily.php -f device_perf diff --git a/doc/API/API-Docs.md b/doc/API/API-Docs.md index 17b34e753..09d3771b6 100644 --- a/doc/API/API-Docs.md +++ b/doc/API/API-Docs.md @@ -18,6 +18,11 @@ - [`list_devices`](#api-route-10) - [`add_device`](#api-route-11) - [`list_oxidized`](#api-route-21) + - [`update_device_field`](#api-route-update_device_field) + - [`get_device_groups`](#api-route-get_device_groups) + - [`devicegroups`](#api-devicegroups) + - [`get_devicegroups`](#api-route-get_devicegroups) + - [`get_devices_by_group`](#api-route-get_devices_by_group) - [`routing`](#api-routing) - [`list_bgp`](#api-route-1) - [`switching`](#api-switching) @@ -315,6 +320,7 @@ Input: - to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information. - width: The graph width, defaults to 1075. - height: The graph height, defaults to 300. + - ifDescr: If this is set to true then we will use ifDescr to lookup the port instead of ifName. Pass the ifDescr value you want to search as you would ifName. Example: ```curl @@ -462,6 +468,183 @@ Output: ] ``` +### Function: `update_device_field` [`top`](#top) + +Update devices field in the database. + +Route: /api/v0/devices/:hostname + +- hostname can be either the device hostname or id + +Input (JSON): + + - field: The column name within the database + - data: The data to update the column with + +Examples: +```curl +curl -X PATCH -d '{"field": "notes", "data": "This server should be kept online"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost +``` + +Output: + +```text +[ + { + "status": "ok", + "message": "Device notes has been updated" + } +] +``` + +### Function `get_device_groups` [`top`](#top) + +List the device groups that a device is matched on. + +Route: /api/v0/devices/:hostname/groups + +- hostname can be either the device hostname or id + +Input (JSON): + + - + +Examples: +```curl +curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/groups +``` + +Output: +```text +[ + { + "status": "ok", + "message": "Found 1 device groups", + "count": 1, + "groups": [ + { + "id": "1", + "name": "Testing", + "desc": "Testing", + "pattern": "%devices.status = \"1\" &&" + } + ] + } +] +``` + +## `Device Groups` [`top`](#top) + +### Function `get_devicegroups` [`top`](#top) + +List all device groups. + +Route: /api/v0/devicegroups + +Input (JSON): + + - + +Examples: +```curl +curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devicegroups +``` + +Output: +```text +[ + { + "status": "ok", + "message": "Found 1 device groups", + "count": 1, + "groups": [ + { + "id": "1", + "name": "Testing", + "desc": "Testing", + "pattern": "%devices.status = \"1\" &&" + } + ] + } +] +``` + +### Function `get_devices_by_group` [`top`](#top) + +List all devices matching the group provided. + +Route: /api/v0/devicegroups/:name + +- name Is the name of the device group which can be obtained using [`get_devicegroups`](#api-route-get_devicegroups). Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded. + +Input (JSON): + + - + +Examples: +```curl +curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devicegroups/LinuxServers +``` + +Output: +```text +[ + { + "status": "error", + "message": "Found 1 in group LinuxServers", + "count": 1, + "devices": [ + { + "device_id": "1", + "hostname": "localhost", + "sysName": "hostname", + "community": "librenms", + "authlevel": null, + "authname": null, + "authpass": null, + "authalgo": null, + "cryptopass": null, + "cryptoalgo": null, + "snmpver": "v2c", + "port": "161", + "transport": "udp", + "timeout": null, + "retries": null, + "bgpLocalAs": null, + "sysObjectID": ".1.3.6.1.4.1.8072.3.2.10", + "sysDescr": "Linux li1045-133.members.linode.com 4.1.5-x86_64-linode61 #7 SMP Mon Aug 24 13:46:31 EDT 2015 x86_64", + "sysContact": "", + "version": "4.1.5-x86_64-linode61", + "hardware": "Generic x86 64-bit", + "features": "CentOS 7.1.1503", + "location": "", + "os": "linux", + "status": "1", + "status_reason": "", + "ignore": "0", + "disabled": "0", + "uptime": "4615964", + "agent_uptime": "0", + "last_polled": "2015-12-12 13:20:04", + "last_poll_attempted": null, + "last_polled_timetaken": "1.90", + "last_discovered_timetaken": "79.53", + "last_discovered": "2015-12-12 12:34:21", + "last_ping": "2015-12-12 13:20:04", + "last_ping_timetaken": "0.08", + "purpose": null, + "type": "server", + "serial": null, + "icon": null, + "poller_group": "0", + "override_sysLocation": "0", + "notes": "Nope" + } + ] + } +] +``` + ## `Routing` [`top`](#top) ### Function: `list_bgp` [`top`](#top) diff --git a/doc/Developing/Dynamic-Config.md b/doc/Developing/Dynamic-Config.md index 73e808f5c..acc9d3079 100644 --- a/doc/Developing/Dynamic-Config.md +++ b/doc/Developing/Dynamic-Config.md @@ -18,7 +18,7 @@ This will determine the default config option for `$config['alert']['tolerance_w If the sub-section you want to add the new config option already exists then update the relevant file within `html/pages/settings/` otherwise you will need to create the new sub-section page. Here's an example of this: -[Commit example](https://github.com/librenm/librenms/commit/c5998f9ee27acdac0c0f7d3092fc830c51ff684c) +[Commit example](https://github.com/librenms/librenms/commit/c5998f9ee27acdac0c0f7d3092fc830c51ff684c) ```php About @@ -372,6 +376,54 @@ $config['alert']['transports']['pushbullet'] = 'MYFANCYACCESSTOKEN'; ``` ~~ +## Clickatell + +Clickatell provides a REST-API requiring an Authorization-Token and at least one Cellphone number. +Please consult Clickatell's documentation regarding number formating. +Here an example using 3 numbers, any amount of numbers is supported: + +~~ +```php +$config['alert']['transports']['clickatell']['token'] = 'MYFANCYACCESSTOKEN'; +$config['alert']['transports']['clickatell']['to'][] = '+1234567890'; +$config['alert']['transports']['clickatell']['to'][] = '+1234567891'; +$config['alert']['transports']['clickatell']['to'][] = '+1234567892'; +``` +~~ + +## PlaySMS + +PlaySMS is an OpenSource SMS-Gateway that can be used via their HTTP-API using a Username and WebService-Token. +Please consult PlaySMS's documentation regarding number formating. +Here an example using 3 numbers, any amount of numbers is supported: + +~~ +```php +$config['alert']['transports']['playsms']['url'] = 'https://localhost/index.php?app=ws'; +$config['alert']['transports']['playsms']['user'] = 'user1'; +$config['alert']['transports']['playsms']['token'] = 'MYFANCYACCESSTOKEN'; +$config['alert']['transports']['playsms']['from'] = '+1234567892'; //Optional +$config['alert']['transports']['playsms']['to'][] = '+1234567890'; +$config['alert']['transports']['playsms']['to'][] = '+1234567891'; +``` +~~ + +## VictorOps + +VictorOps provide a webHook url to make integration extremely simple. To get the URL required login to your VictorOps account and go to: + +Settings -> Integrations -> REST Endpoint -> Enable Integration. + +The URL provided will have $routing_key at the end, you need to change this to something that is unique to the system sending the alerts such as librenms. I.e: + +`https://alert.victorops.com/integrations/generic/20132414/alert/2f974ce1-08fc-4dg8-a4f4-9aee6cf35c98/librenms` + +~~ +```php +$config['alert']['transports']['victorops']['url'] = 'https://alert.victorops.com/integrations/generic/20132414/alert/2f974ce1-08fc-4dg8-a4f4-9aee6cf35c98/librenms'; +``` +~~ + # Entities Entities as described earlier are based on the table and column names within the database, if you are unsure of what the entity is you want then have a browse around inside MySQL using `show tables` and `desc `. @@ -582,4 +634,14 @@ Description: Packet loss % value for the device within the last 15 minutes. Example: `%macros.packet_loss_15m` > 50 +# Additional Options +Here are some of the other options available when adding an alerting rule: + +- Rule name: The name associated with the rule. +- Severity: How "important" the rule is. +- Max alerts: The maximum number of alerts sent for the event. `-1` means unlimited. +- Delay: The amount of time to wait after a rule is matched before sending an alert. +- Interval: The interval of time between alerts for an event until Max is reached. +- Mute alerts: Disable sending alerts for this rule. +- Invert match: Invert the matching rule (ie. alert on items that _don't_ match the rule). diff --git a/doc/Extensions/Authentication.md b/doc/Extensions/Authentication.md index 048a08f13..633b8ed13 100644 --- a/doc/Extensions/Authentication.md +++ b/doc/Extensions/Authentication.md @@ -9,7 +9,11 @@ Here we will provide configuration details for these modules. - LDAP: ldap - HTTP Auth: http-auth +- Active Directory: active_directory + +- HTTP Auth: http-auth + +- Radius: radius #### User levels @@ -99,3 +103,43 @@ $config['auth_ldap_groupmemberattr'] = "memberUid"; ``` Replace {id} with the unique ID provided by Jumpcloud. + +#### Active Directory Authentication + +Config option: `active_directory` + +This is similar to LDAP Authentication. Install __php_ldap__ for CentOS/RHEL or __php5-ldap__ for Debian/Ubuntu. + +If you have issues with secure LDAP try setting `$config['auth_ad_check_certificates']` to `0`. + +##### Require actual membership of the configured groups + +If you set ```$config['auth_ad_require_groupmembership']``` to 1, the authenticated user has to be a member of the specific group. Otherwise all users can authenticate, but are limited to user level 0 and only have access to shared dashboards. + +##### Sample configuration + +``` +$config['auth_ad_url'] = "ldaps://your-domain.controll.er"; +$config['auth_ad_check_certificates'] = 1; // or 0 +$config['auth_ad_domain'] = "your-domain.com"; +$config['auth_ad_base_dn'] = "dc=your-domain,dc=com"; +$config['auth_ad_groups']['admin']['level'] = 10; +$config['auth_ad_groups']['pfy']['level'] = 7; +$config['auth_ad_require_groupmembership'] = 0; +``` + +#### Radius Authentication + +Please note that a mysql user is created for each user the logs in successfully. User level 1 is assigned to those accounts so you will then need to assign the relevant permissions unless you set `$config['radius']['userlevel']` to be something other than 1. + +> Cleanup of old accounts is done using the authlog. You will need to set the cleanup date for when old accounts will be purged which will happen AUTOMATICALLY. +> Please ensure that you set the $config['authlog_purge'] value to be greater than $config['radius']['users_purge'] otherwise old users won't be removed. + +```php +$config['radius']['hostname'] = 'localhost'; +$config['radius']['port'] = '1812'; +$config['radius']['secret'] = 'testing123'; +$config['radius']['timeout'] = 3; +$config['radius']['users_purge'] = 14;//Purge users who haven't logged in for 14 days. +$config['radius']['default_level'] = 1;//Set the default user level when automatically creating a user. +``` diff --git a/doc/Extensions/Memcached.md b/doc/Extensions/Memcached.md index ae55ff342..3d226e83a 100644 --- a/doc/Extensions/Memcached.md +++ b/doc/Extensions/Memcached.md @@ -14,3 +14,5 @@ By default values are kept for 4 Minutes inside the memcached, you can adjust th It's strongly discouraged to set this above `300` (5 Minutes) to avoid interferences with the polling, discovery and alerting processes. If you use the Distributed Poller, you can point this to the same memcached instance. However a local memcached will perform better in any case. + +By default `memcached` on many distributions starts itself with 64 MB of memory for it to store data in. If you have lots of devices or look at graphs frequently, it might be worth it to expand `memcached`'s footprint a bit. Generally this can be done in `/etc/memcached.conf`, replacing `-m 64` with `-m 512`, or however many megs of memory you want to allocate for `memcached`. Then restart the `memcached` service. diff --git a/doc/Extensions/Oxidized.md b/doc/Extensions/Oxidized.md index 19ba60f15..38297dbbc 100644 --- a/doc/Extensions/Oxidized.md +++ b/doc/Extensions/Oxidized.md @@ -40,3 +40,10 @@ You will need to configure default credentials for your devices, LibreNMS doesn' ``` If you have devices which you do not wish to appear in Oxidized then you can edit those devices in Device -> Edit -> Misc and enable "Exclude from Oxidized?" + +It's also possible to exclude certain device types and OS' from being output via the API. This is currently only possible via config.php: + +```php +$config['oxidized']['ignore_types'] = array('server'); +$config['oxidized']['ignore_os'] = array('linux'); +``` diff --git a/doc/Extensions/Proxmox.md b/doc/Extensions/Proxmox.md index 0691e1d27..4b7f8a2a1 100644 --- a/doc/Extensions/Proxmox.md +++ b/doc/Extensions/Proxmox.md @@ -1,6 +1,5 @@ # Proxmox graphing - -It is possible to create graphs of the Proxmox VMs that run on your monitored machines. Currently, only trafficgraphs are created. One for each interface on each VM. Possibly, IO grahps will be added later on. +It is possible to create graphs of the Proxmox **VMs** that run on your monitored machines. Currently, only trafficgraphs are created. One for each interface on each VM. Possibly, IO grahps will be added later on. The ultimate goal is to be able to create traffic bills for VMs, no matter on which physical machine that VM runs. @@ -10,14 +9,20 @@ To enable Proxmox graphs, do the following: In config.php, enable Proxmox: ```php -$config['enable_proxmox'] = 1 +$config['enable_proxmox'] = 1; ``` -Then, install librenms-agent on the machines running Proxmox, and enable the Proxmox-plugin using: +Then, install [librenms-agent](http://docs.librenms.org/Extensions/Agent-Setup/) on the machines running Proxmox and enable the Proxmox-script using: + ```bash -mk_enplug proxmox +cp /opt/librenms-agent/proxmox /usr/lib/check_mk_agent/local/proxmox +chmod +x /usr/lib/check_mk_agent/local/proxmox ``` -Then, enable the unix-agent on the machines running Proxmox. +Then, restart the xinetd service +```bash +/etc/init.d/xinetd restart +``` +Then in LibreNMS active the librenms-agent and proxmox application flag for the device you are monitoring. You should now see an application in LibreNMS, as well as a new menu-item in the topmenu, allowing you to choose which cluster you want to look at. diff --git a/doc/Extensions/RRDTune.md b/doc/Extensions/RRDTune.md new file mode 100644 index 000000000..7ee7095d2 --- /dev/null +++ b/doc/Extensions/RRDTune.md @@ -0,0 +1,21 @@ +# RRDTune? + +When we create rrd files for ports, we currently do so with a max value of 12500000000 (100G). Because of this if a device sends us bad data back then it can appear as though +a 100M port is doing 40G+ which is impossible. To counter this you can enable the rrdtool tune option which will fix the max value to the interfaces physical speed (minimum of 10M). + +To enable this you can do so in three ways! + + - Globally under Global Settings -> External Settings -> RRDTool Setup + - For the actual device, Edit Device -> Misc + - For each port, Edit Device -> Port Settings + +Now when a port interface speed changes (this can happen because of a physical change or just because the device has mis-reported) the max value is set. If you don't want to wait until +a port speed changes then you can run the included script: + +script/tune_port.php -h -p + +Wildcards are supported using *, i.e: + +script/tune_port.php -h local* -p eth* + +This script will then perform the rrdtool tune on each port found using the provided ifSpeed for that port. diff --git a/doc/Extensions/Services.md b/doc/Extensions/Services.md index 7ad7c9d29..dba098588 100644 --- a/doc/Extensions/Services.md +++ b/doc/Extensions/Services.md @@ -3,7 +3,7 @@ Services within LibreNMS provides the ability to use Nagios plugins to perform additional monitoring outside of SNMP. These services are tied into an existing device so you need at least one device that supports SNMP to be able to add it -to LibreNMS - localhot is a good one. +to LibreNMS - localhost is a good one. ## Setup diff --git a/doc/Extensions/Smokeping.md b/doc/Extensions/Smokeping.md index 902b14f2a..7c0703471 100644 --- a/doc/Extensions/Smokeping.md +++ b/doc/Extensions/Smokeping.md @@ -43,3 +43,129 @@ $config['own_hostname'] ``` You should now see a new tab in your device page called ping. + + + + +### Install and integrate Smokeping [Debian/Ubuntu] ### + +> This guide assumes you have already installed librenms, and you installed apache2 in the process. Tested with Ubuntu 14.04 and Apache 2.4. + +Nearly everything we do will require root, and at one point we'll encounter a problem if we just use sudo, so we'll just switch to root at the beginning... + +```bash +sudo su - +``` + +### Install Smokeping ### + +```bash +apt-get install smokeping +``` + +At the end of installation, you may have gotten this error: `ERROR: /etc/smokeping/config.d/pathnames, line 1: File '/usr/sbin/sendmail' does not exist` + +If so, just edit smokeping's pathnames. + +```bash +nano /etc/smokeping/config.d/pathnames +``` + +Comment out the first line: + +```bash +#sendmail = /usr/sbin/sendmail +``` + +Exit and save. + +Check if the smokeping config file was created for apache2: + +```bash +ls /etc/apache2/conf-available/ +``` + +If you don't see `smokeping.conf` listed, you'll need to create a symlink for it: + +```bash +ln -s /etc/smokeping/apache2.conf /etc/apache2/conf-available/smokeping.conf +``` + +Edit the smokeping config so smokeping knows the hostname it's running on: + +```bash +nano /etc/smokeping/config.d/General +``` + +Change the `cgiurl` value to `http://yourhost/cgi-bin/smokeping.cgi` +Modify any other values you wish, then exit and save. + +### LibreNMS integration ### + +So far this is a relatively normal Smokeping installation; next we'll set up the LibreNMS integration. + +Generate the configuration file so Smokeping knows the hosts you have set up for monitoring in LibreNMS. + +```bash +cd /opt/librenms/scripts/ +(echo "+ LibreNMS"; php ./gen_smokeping.php) > /etc/smokeping/config.d/librenms.conf +``` + +Add a cron job so as you add or remove hosts in librenms they'll get updated with Smokeping. + +```bash +crontab -e +``` + +Add the example cron below; it's set to run daily at 02:05 + +```bash +05 02 * * * root cd /opt/librenms/scripts && (echo "+ LibreNMS"; php ./gen_smokeping.php) > /etc/smokeping/config.d/librenms.conf && service smokeping reload >> /dev/null +``` + +Exit and save. + +Include `librenms.conf` in smokeping's config: +```bash +nano /etc/smokeping/config +``` + +Add the following line at the end: + +```bash +@include /etc/smokeping/config.d/librenms.conf +``` + +Exit and save. + +### Configure LibreNMS ### + +```bash +nano /opt/librenms/config.php +``` + +Scroll to the bottom, and paste in the following: + +```bash +$config['smokeping']['dir'] = '/var/lib/smokeping'; +$config['smokeping']['integration'] = true; +``` + +Exit and save. + +Run the following commands: +```bash +a2enconf smokeping +a2enmod cgid +service apache2 restart +service smokeping restart +``` + +Return to your normal user shell + +```bash +exit +``` + +Done! You should be able to load the Smokeping web interface at `http://yourhost/cgi-bin/smokeping.cgi` +In LibreNMS, a Ping tab should also appear. diff --git a/doc/General/Acknowledgement.md b/doc/General/Acknowledgement.md index 6f9b50ea2..328a8f867 100644 --- a/doc/General/Acknowledgement.md +++ b/doc/General/Acknowledgement.md @@ -23,6 +23,7 @@ LibreNMS 3rd party acknowledgements - Tag Manager (http://soliantconsulting.github.io/tagmanager/): MIT - TW Sack (https://code.google.com/p/tw-sack/): GPLv3 - Gridster (http://gridster.net/): MIT + - Pure PHP radius class (http://developer.sysco.ch/php/): GPLv3 #### 3rd Party GPLv3 Non-compliant diff --git a/doc/General/Callback-Stats-and-Privacy.md b/doc/General/Callback-Stats-and-Privacy.md index e0d32c7a7..3e043ea98 100644 --- a/doc/General/Callback-Stats-and-Privacy.md +++ b/doc/General/Callback-Stats-and-Privacy.md @@ -28,5 +28,6 @@ Now onto the bit you're interested in, what is submitted and what we do with tha Hopefully this answers the questions you might have on why and what we are doing here, if not, please pop into our irc channel or google mailing list and ask any questions you like. +#### How do I enable stats submission? #### If you're happy with all of this - please consider switching the call back system on, you can do this within the About LibreNMS page within your control panel. In the Statistics section you will find a toggle switch to enable / disable the feature. If you've previously had it switched on and want to opt out and remove your data, click the 'Clear remote stats' button and on the next submission all the data you've sent us will be removed! diff --git a/doc/General/Changelog.md b/doc/General/Changelog.md index 6a951d90b..5e83df17d 100644 --- a/doc/General/Changelog.md +++ b/doc/General/Changelog.md @@ -1,16 +1,157 @@ +### December 2015 + +#### Bug fixes + - WebUI: + - Fixed regex for negative lat/lng coords (PR2524) + - Fixed map page looping due to device connected to itself (PR2545) + - Fixed PATH_INFO for nginx (PR2551) + - urlencode the custom port types (PR2597) + - Stop non-admin users from being able to get to settings pages (PR2627) + - Fix JpGraph php version compare (PR2631) + - Discovery / Polling: + - Pointed snmp calls for Huawei to correct MIB folder (PR2541) + - Fixed Ceph unix-agent support. (PR2588) + - Moved memory graphs from storage to memory polling (PR2616) + - Mask alert_log mysql output when debug is enabled to stop console crashes (PR2618) + - Stop Quanta devices being detected as Ubiquiti (PR2632) + - Fix MySQL unix-agent graphs (PR2645) + - Added MTA-MIB and NETWORK-SERVICES-MIB to stop warnings printed in poller debug (PR2653) + - Services: + - Fix SSL check for PHP 7 (PR2647) + - Alerting: + - Fix glue-expansion for alerts (PR2522) + - Fix HipChat transport (PR2586) + - Documentation: + - Removed duplicate mysql-client install from Debian/Ubuntu install docs (PR2543) + - Misc: + - Update daily.sh to ignore issues writing to log file (PR2595) + +#### Improvements + - WebUI: + - Converted sensors page to use bootgrid (PR2531) + - Added new widgets for dashboard. Notes (PR2582), Generic image (PR2617) + - Added config option to disable lazy loading of images (PR2589) + - Visual update to Navbar. (PR2593) + - Update alert rules to show actual alert rule ID (PR2603) + - Initial support added for per user default dashboard (PR2620) + - Updated Worldmap to show clusters in red if one device is down (PR2621) + - Discovery / Polling + - Added traffic bits as default for Cambium devices (PR2525) + - Overwrite eth0 port data from UniFi MIBs for AirFibre devices (PR2544) + - Added lastupdate column to sensors table for use with alerts (PR2590,PR2592) + - Updated auto discovery via lldp to check for devices that use mac address in lldpRemPortId (PR2591) + - Updated auto discovery via lldp with absent lldpRemSysName (PR2619) + - API: + - Added ability to filter devices by type and os for Oxidized API call (PR2539) + - Added ability to update device information (PR2585) + - Added support for returning device groups (PR2611) + - Added ability to select port graphs based on ifDescr (PR2648) + - Documentation: + - Improved alerting docs explaining more options (PR2560) + - Added Docs for Ubuntu/Debian Smokeping integration (PR2610) + - Added detection for: + - Updated Netonix switch MIBs (PR2523) + - Updated Fotinet MIBs (PR2529, PR2534) + - Cisco SG500 (PR2609) + - Updated processor support for Fortigate (PR2613) + - Misc: + - Updated validation to check for php extension and classes required (PR2602) + - Added Radius Authentication support (PR2615) + - Removed distinct() from alerts query to use indexes (PR2649) + +### November 2015 + +#### Bug fixes + - WebUI: + - getRates should return in and out average rates (PR2375) + - Fix 95th percent lines in negative range (PR2405) + - Fix percentage bar for billing pages (PR2419) + - Use HC counters first in realtime graphs (PR2420) + - Fix netcmd.php URI for sub dir installations (PR2428) + - Fixed Oxidized fetch config with groups (PR2501) + - Fixed background colour to white for some graphs (PR2516) + - API: + - Added missing quotes for MySQL queries (PR2382) + - Discovery / Polling: + - Specified MIB used when polling ntpd-server (PR2418) + - Added missing fields when inserting data into applications table (PR2445) + - Fix auto-discovery failing (PR2457) + - Juniper hardware inventory fix (PR2466) + - Fix discovery of Cisco PIX running PixOS 8.0 (PR2480) + - Fix bug in Proxmox support if only one VM was detected (PR2490, PR2547) + - Alerting: + - Strip && and || from query for device-groups (PR2476) + - Fix transports being triggered when empty keys set (PR2491) + Misc: + - Updated device_traffic_descr config to stop graphs failing (PR2386) + +#### Improvements + - WebUI: + - Status column now sortable for /devices/ (PR2397) + - Update Gridster library to be responsive (PR2414) + - Improved rrdtool 1.4/1.5 compatibility (PR2430) + - Use event_id in query for Eventlog (PR2437) + - Add graph selector to devices overview (PR2438) + - Improved Navbar for varying screen sizes (PR2450) + - Added RIPE NCC API support for lookups (PR2455, PR2474) + - Improved ports page for device with large number of neighbours (PR2460) + - Merged all CPU graphs into one on overview page (PR2470) + - Added support for sortting by traffic on device port page (PR2508) + - Added support for dynamic graph sizes based on browser size (PR2510) + - Made device location clickable in device header (PR2515) + - Visual improvements to bills page (PR2519) + - Discovery / Polling: + - Updated Cisco SB discovery (PR2396) + - Added Ceph support via Applications (PR2412) + - Added support for per device unix-agent port (PR2439) + - Added ability to select up/down devices on worldmap (PR2441) + - Allow powerdns app to be set for Unix Agent (PR2489) + - Added SLES detection to distro script (PR2502) + - Added detection for: + - Added CPU + Memory usage for Ubiquiti UniFi (PR2421) + - Added support for LigoWave Infinity AP's (PR2456) + - Alerting: + - Added ability to globally disable sending alerts (PR2385) + - Added support for Clickatell, PlaySMS and VictorOps (PR24104, PR2443) + - Documnetation: + - Improved CentOS install docs (PR2462) + - Improved Proxmox setup docs (PR2483) + - Misc: + - Provide InnoDB config for buffer size issues (PR2401) + - Added AD Authentication support (PR2411, PR2425, PR2432, PR2434) + - Added Features document (PR2436, PR2511, PR2513) + - Centralised innodb buffer check and added to validate (PR2482) + - Updated and improved daily.sh (PR2487) + + ### October 2015 #### Bug fixes - Discovery / Polling: - Check file exists via rrdcached before creating new files on 1.5 (PR2041) + - Fix Riverbed discovery (PR2133) + - Fixes issue where snmp_get would not return the value 0 (PR2134) + - Fixed powerdns snmp checks (PR2176) + - De-dupe checks for hostname when adding hosts (PR2189) - WebUI: - Soft fail if PHP Pear not installed (PR2036) - Escape quotes for ifAlias in overlib calls (PR2072) - Fix table name for access points (PR2075) - Removed STACK text in graphs (PR2097) - Enable multiple ifDescr overrides to be done per device (PR2099) + - Removed ping + performance graphs and tab if skip ping check (PR2175) + - Fixed services -> Alerts menu link + page (PR2173) + - Fix percent bar also for quota bills (PR2198) + - Fix new Bill (PR2199) + - Change default solver to hierarchicalRepulsion in vis.js (PR2202) + - Fix: setting user port permissions fails (PR2203) + - Updated devices Graphs links to use non-static time references (PR2211) + - Removed ignored,deleted and disabled ports from query (PR2213) - API: - Fixed API call for alert states (PR2076) + - Fixed nginx rewrite for api (PR2112) + - Change on the add_edit_rule to modify a rule without modify the name (PR2159) + - Fixed list_bills function when using :bill_id (PR2212) #### Improvements - WebUI: @@ -18,23 +159,46 @@ - Added billing graphs to graphs widget (PR2027) - Lock widgets by default so they can't be moved (PR2042) - Moved Device Groups menu (PR2049) + - Show Config tab only if device isn't excluded from oxidized (PR2118) + - Simplify adding config options to WebUI (PR2120) + - Move red map markers to foreground (PR2127) + - Styled the two factor auth token prompt (PR2151) + - Update Font Awesome (PR2167) + - Allow user to influence when devices are grouped on world map (PR2170) + - Centralised the date selector for graphs for re-use (PR2183) + - Dont show dashboard settings if `/bare=yes/` (PR2364) - API: - Added unmute alert function to API (PR2082) - - Added detection support for: - - Pulse Secure OS (PR2053) - Discovery / Polling: - Added additional support for some UPS' based on Multimatic cards (PR2046) - Improved WatchGuard OS detection (PR2048) - Treat Dell branded Wifi controllers as ArubaOS (PR2065) - Added discovery option for OS or Device type (PR2088) - Updated pfSense to firewall type (PR2096) + - Added ability to turn off icmp checks globally or per device (PR2131) + - Reformat check a bit to make it easier for adding additional oids in (PR2135) + - Updated to disable auto-discovery by ip (PR2182) + - Updated to use env in distro script (PR2204) - Added detection for: + - Pulse Secure OS (PR2053) - Riverbed Steelhead support (PR2107) + - OpenBSD sensors (PR2113) + - Additional comware detection (PR2162) + - Version from Synology MIB (PR2163) + - VCSA as VMWare (PR2185) + - SAF Lumina radios (PR2361) + - TP-Link detection (PR2362) - Documentation: - Improved RHEL/CentOS install docs (PR2043) + - Update Varnish Docs (PR2116, PR2126) + - Added passworded channels for the IRC-Bot (PR2122) + - Updated Two-Factor-Auth.md RE: Google Authenticator (PR2146) - General: - Added colour support to IRC bot (PR2059) - Fixed IRC bot reconnect if socket dies (PR2061) + - Updated default crons (PR2177) + - Reverts: + - "Removed what appears to be unecessary STACK text" (PR2128) ### September 2015 diff --git a/doc/Installation/Installation-(Debian-Ubuntu).md b/doc/Installation/Installation-(Debian-Ubuntu).md index 70927a3e7..fce129201 100644 --- a/doc/Installation/Installation-(Debian-Ubuntu).md +++ b/doc/Installation/Installation-(Debian-Ubuntu).md @@ -57,7 +57,7 @@ This host is where the web server and SNMP poller run. It could be the same mac Install the required software: - apt-get install libapache2-mod-php5 php5-cli php5-mysql php5-gd php5-snmp php-pear php5-curl snmp graphviz php5-mcrypt php5-json apache2 fping imagemagick whois mtr-tiny nmap python-mysqldb snmpd mysql-client php-net-ipv4 php-net-ipv6 rrdtool git + apt-get install libapache2-mod-php5 php5-cli php5-mysql php5-gd php5-snmp php-pear php5-curl snmp graphviz php5-mcrypt php5-json apache2 fping imagemagick whois mtr-tiny nmap python-mysqldb snmpd php-net-ipv4 php-net-ipv6 rrdtool git The packages listed above are an all-inclusive list of packages that were necessary on a clean install of Ubuntu 12.04/14.04. diff --git a/doc/Installation/Installation-(RHEL-CentOS).md b/doc/Installation/Installation-(RHEL-CentOS).md index 25fbc1db9..ddfdc2cc1 100644 --- a/doc/Installation/Installation-(RHEL-CentOS).md +++ b/doc/Installation/Installation-(RHEL-CentOS).md @@ -99,7 +99,8 @@ Note if not using HTTPd (Apache): RHEL requires `httpd` to be installed regardle **CentOS 7** ```bash - yum install php php-cli php-gd php-mysql php-snmp php-pear php-curl httpd net-snmp graphviz graphviz-php mariadb ImageMagick jwhois nmap mtr rrdtool MySQL-python net-snmp-utils vixie-cron php-mcrypt fping git + yum install epel-release + yum install php php-cli php-gd php-mysql php-snmp php-pear php-curl httpd net-snmp graphviz graphviz-php mariadb ImageMagick jwhois nmap mtr rrdtool MySQL-python net-snmp-utils cronie php-mcrypt fping git pear install Net_IPv4-1.3.4 pear install Net_IPv6-1.2.2b2 ``` @@ -185,6 +186,7 @@ server { try_files $uri $uri/ @librenms; } location ~ \.php { + fastcgi_param PATH_INFO $fastcgi_path_info; include fastcgi.conf; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php5-fpm.sock; diff --git a/doc/Support/Configuration.md b/doc/Support/Configuration.md index 7ffdffe08..8c4fc0ac3 100644 --- a/doc/Support/Configuration.md +++ b/doc/Support/Configuration.md @@ -177,6 +177,11 @@ $config['web_mouseover'] = TRUE; ``` You can disable the mouseover popover for mini graphs by setting this to FALSE. +```php +$config['enable_lazy_load'] = true; +``` +You can disable image lazy loading by setting this to false. + ```php $config['show_overview_tab'] = TRUE; ``` @@ -261,6 +266,12 @@ $config['autodiscovery']['nets-exclude'][] = "240.0.0.0/4"; ``` Arrays of subnets to exclude in auto discovery mode. +```php +$config['discovery_by_ip'] = true; +``` +Enable auto discovery by IP. By default we only discover based on hostnames but manually adding by IP is allowed. +Please note this could lead to duplicate devices being added based on IP, Hostname or sysName. + #### Email configuration > You can configure these options within the WebUI now, please avoid setting these options within config.php @@ -430,7 +441,7 @@ $config['auth_mechanism'] = "mysql"; ``` This is the authentication type to use for the WebUI. MySQL is the default and configured when following the installation instructions. ldap and http-auth are also valid options. For instructions on the different authentication modules please -see [Authentication](http://doc.librenms.org/Extensions/Authentication/). +see [Authentication](http://docs.librenms.org/Extensions/Authentication/). ```php $config['auth_remember'] = '30'; diff --git a/doc/Support/FAQ.md b/doc/Support/FAQ.md index d7317db4f..d6da5de50 100644 --- a/doc/Support/FAQ.md +++ b/doc/Support/FAQ.md @@ -12,6 +12,7 @@ - [How do I debug the discovery process?](#faq11) - [How do I debug the poller process?](#faq12) - [Why do I get a lot apache or rrdtool zombies in my process list?](#faq14) + - [Why do I see traffic spikes in my graphs?](#faq15) ### Developing - [How do I add support for a new OS?](#faq8) @@ -94,6 +95,13 @@ Please see the [Poller Support](http://docs.librenms.org/Support/Poller Support) If this is related to your web service for LibreNMS then this has been tracked down to an issue within php which the developers aren't fixing. We have implemented a work around which means you shouldn't be seeing this. If you are, please report this in [issue 443](https://github.com/librenms/librenms/issues/443). +#### Why do I see traffic spikes in my graphs? + +This occurs either when a counter resets or the device sends back bogus data making it look like a counter reset. We have enabled support for setting a maximum value for rrd files for ports. +Before this all rrd files were set to 100G max values, now you can enable support to limit this to the actual port speed. + +rrdtool tune will change the max value when the interface speed is detected as being changed (min value will be set for anything 10M or over) or when you run the included script (scripts/tune_port.php). + #### How do I add support for a new OS? The easiest way to show you how to do that is to link to an existing pull request that has been merged in on [GitHub](https://github.com/librenms/librenms/pull/352/files) diff --git a/doc/Support/Features.md b/doc/Support/Features.md new file mode 100644 index 000000000..2d994c4bc --- /dev/null +++ b/doc/Support/Features.md @@ -0,0 +1,128 @@ +### Features + +Here's a brief list of supported features, some might be missing. +If you think something is missing, feel free to ask us. + +* Alerting +* API +* Auto Updating +* Customizable Dashboards +* Device Backup (Oxidized, RANCID) +* Distributed Polling +* Multiple Authentication Methods (MySQL, LDAP, Active Directory, HTTP) +* NetFlow, sFlow, IPFIX (NfSen) +* Service monitoring (Nagios Plugins) +* Syslog (Integrated, Graylog) +* Traffic Billing (Quota, 95th Percentile) +* Two Factor Authentication + +### Vendors +Here's a brief list of supported vendors, some might be missing. +If you are unsure of whether your device is supported or not, feel free to ask us. + +* 3Com +* Aerohive +* AKCP +* Alcatel-Lucent +* Allied Telesis +* APC +* Apple +* Areca +* Arista +* Aruba +* Avaya +* Avocent +* Axis +* Barracuda +* BCM963 +* BNT +* Brocade +* Brother +* Canopy +* Cisco +* Cisco Small Business +* Citrix +* Cometsystem +* Comware +* D-Link +* Datacom +* Dell +* Delta Power Solutions +* Eaton +* Engenius +* Enterasys +* Epson +* Extreme Networks +* F5 +* FiberHome +* Force10 +* Fortigate +* FreeBSD +* Gamatronic +* Hikvision +* HP +* Huawei +* IBM +* iPoMan +* ITWatchDogs +* Juniper +* Konica Minolta +* Kyocera +* Liebert +* LigoWave +* Linux +* Mellanox +* Meraki +* MGE +* Mikrotic +* MRVLD +* Multimatic +* NetApp +* NetBSD +* NETGEAR +* NetMan +* Netonix +* Netopia +* NetVision +* NetWare +* NRG +* OKI +* OpenBSD +* PacketShaper +* Palo Alto Networks +* Papouch +* PBN +* Perle +* Powercode +* Prestige +* Proxim +* Proxmox +* Quanta +* Radlan +* Raritan +* Redback +* Ricoh +* Riverbed +* Ruckus +* SAF +* Siklu +* Sentry3 +* Solaris +* SonicWALL +* SpeedTouch +* Supermicro +* Symbol +* TPLink +* Tranzeo +* Triplite +* Ubiquiti +* VMware +* VRP +* Vyatta +* VyOS +* Watchguard +* WebPower +* Windows +* Xerox +* ZTE +* ZyXEL diff --git a/html/ajax_setresolution.php b/html/ajax_setresolution.php new file mode 100644 index 000000000..b72bd748e --- /dev/null +++ b/html/ajax_setresolution.php @@ -0,0 +1,8 @@ +group( // api/v0/devices/$hostname $app->get('/:hostname', 'authToken', 'get_device')->name('get_device'); // api/v0/devices/$hostname + $app->patch('/:hostname', 'authToken', 'update_device')->name('update_device_field'); $app->get('/:hostname/vlans', 'authToken', 'get_vlans')->name('get_vlans'); // api/v0/devices/$hostname/vlans $app->get('/:hostname/graphs', 'authToken', 'get_graphs')->name('get_graphs'); // api/v0/devices/$hostname/graphs $app->get('/:hostname/ports', 'authToken', 'get_port_graphs')->name('get_port_graphs'); // api/v0/devices/$hostname/ports + $app->get('/:hostname/groups', 'authToken', 'get_device_groups')->name('get_device_groups'); $app->get('/:hostname/:type', 'authToken', 'get_graph_generic_by_hostname')->name('get_graph_generic_by_hostname'); // api/v0/devices/$hostname/$type $app->get('/:hostname/ports/:ifname', 'authToken', 'get_port_stats_by_port_hostname')->name('get_port_stats_by_port_hostname'); @@ -60,6 +62,13 @@ $app->group( // api/v0/devices $app->post('/devices', 'authToken', 'add_device')->name('add_device'); // api/v0/devices (json data needs to be passed) + $app->group( + '/devicegroups', + function () use ($app) { + $app->get('/:name', 'authToken', 'get_devices_by_group')->name('get_devices_by_group'); + } + ); + $app->get('/devicegroups', 'authToken', 'get_device_groups')->name('get_devicegroups'); $app->group( '/portgroups', function () use ($app) { diff --git a/html/css/styles.css b/html/css/styles.css index 46abbc37f..ea9dde575 100644 --- a/html/css/styles.css +++ b/html/css/styles.css @@ -1764,4 +1764,94 @@ tr.search:nth-child(odd) { label { font-weight: normal; -} \ No newline at end of file +} + +.nav>li>a.dropdown-toggle { + padding: 15px 6px; +} + +.badge-navbar-user{ + background:red; + border-radius: 40%; + font-size: 65%; + height: auto; + margin: 0; + padding:5px; + position:absolute; + right:-3px; + top:5px; + width: auto; + } + +@media only screen and (max-width: 480px) { + .thumbnail_graph_table b { font-size : 6px;} + .thumbnail_graph_table img { + max-width: 45px; + max-height: 50px; + } + .device-header-table .device_icon img { + max-width: 20px; + max-height: 20px; + } + .device-header-table img { + max-width: 115px; + max-height: 40px; + } + .device-header-table {font-size : 8px;} + .device-header-table a {font-size : 11px;} +} + +@media only screen and (max-width: 768px) and (min-width: 481px) { + .thumbnail_graph_table b { font-size : 8px;} + .thumbnail_graph_table img { + max-width: 60px; + max-height: 55px; + } + .device-header-table img { + max-width: 150px; + max-height: 50px; + } + .device-header-table {font-size : 10px;} + .device-header-table a {font-size : 17px;} +} + + +@media only screen and (max-width: 800px) and (min-width: 721px) { + .thumbnail_graph_table b { font-size : 8px;} + .thumbnail_graph_table img { + max-width: 75px; + max-height: 60px; + } +} + +@media only screen and (max-width: 1024px) and (min-width: 801px) { + .thumbnail_graph_table b { font-size : 9px;} + .thumbnail_graph_table img { + max-width: 105px; + max-height: 70px; + } +} + +@media only screen and (min-width: 1024px) { +} + +.redCluster { + background-color: rgba(255,0,0); + background-color: rgba(255,0,0,0.7); + text-align: center; + width: 25px !important; + height: 25px !important; + font-size: 14px; + color: white; +} + +.greenCluster { + background-color: rgba(0,255,0); + background-color: rgba(0,255,0,0.7); + text-align: center; + width: 25px !important; + height: 25px !important; + font-size: 14px; + color: black; + border-color:transparent; +} diff --git a/html/data.php b/html/data.php index b55d09c32..4267ddb5d 100644 --- a/html/data.php +++ b/html/data.php @@ -31,14 +31,14 @@ if (is_numeric($_GET['id']) && ($config['allow_unauth_graphs'] || port_permitted $auth = true; } -$in = snmp_get($device, 'ifInOctets.'.$port['ifIndex'], '-OUqnv', 'IF-MIB'); -$out = snmp_get($device, 'ifOutOctets.'.$port['ifIndex'], '-OUqnv', 'IF-MIB'); +$in = snmp_get($device, 'ifHCInOctets.'.$port['ifIndex'], '-OUqnv', 'IF-MIB'); if (empty($in)) { - $in = snmp_get($device, 'ifHCInOctets.'.$port['ifIndex'], '-OUqnv', 'IF-MIB'); + $in = snmp_get($device, 'ifInOctets.'.$port['ifIndex'], '-OUqnv', 'IF-MIB'); } +$out = snmp_get($device, 'ifHCOutOctets.'.$port['ifIndex'], '-OUqnv', 'IF-MIB'); if (empty($out)) { - $out = snmp_get($device, 'ifHCOutOctets.'.$port['ifIndex'], '-OUqnv', 'IF-MIB'); + $out = snmp_get($device, 'ifOutOctets.'.$port['ifIndex'], '-OUqnv', 'IF-MIB'); } $time = time(); diff --git a/html/images/os/ligowave.png b/html/images/os/ligowave.png new file mode 100644 index 000000000..fb54f80bd Binary files /dev/null and b/html/images/os/ligowave.png differ diff --git a/html/images/os/quanta.png b/html/images/os/quanta.png new file mode 100644 index 000000000..f3cb0db4a Binary files /dev/null and b/html/images/os/quanta.png differ diff --git a/html/images/os/saf.png b/html/images/os/saf.png new file mode 100644 index 000000000..010a780be Binary files /dev/null and b/html/images/os/saf.png differ diff --git a/html/images/os/samsungprinter.png b/html/images/os/samsungprinter.png new file mode 100644 index 000000000..f3fac3a42 Binary files /dev/null and b/html/images/os/samsungprinter.png differ diff --git a/html/images/os/tplink.png b/html/images/os/tplink.png new file mode 100644 index 000000000..d9a93d9dc Binary files /dev/null and b/html/images/os/tplink.png differ diff --git a/html/includes/api_functions.inc.php b/html/includes/api_functions.inc.php index 1761cabf2..8c4cf2817 100644 --- a/html/includes/api_functions.inc.php +++ b/html/includes/api_functions.inc.php @@ -13,7 +13,7 @@ */ require_once '../includes/functions.php'; - +require_once '../includes/device-groups.inc.php'; function authToken(\Slim\Route $route) { $app = \Slim\Slim::getInstance(); @@ -62,10 +62,17 @@ function get_graph_by_port_hostname() { $vars['to'] = $_GET['to']; } + if ($_GET['ifDescr'] == true) { + $port = 'ifDescr'; + } + else { + $port = 'ifName'; + } + $vars['width'] = $_GET['width'] ?: 1075; $vars['height'] = $_GET['height'] ?: 300; $auth = '1'; - $vars['id'] = dbFetchCell('SELECT `P`.`port_id` FROM `ports` AS `P` JOIN `devices` AS `D` ON `P`.`device_id` = `D`.`device_id` WHERE `D`.`hostname`=? AND `P`.`ifName`=?', array($hostname, $vars['port'])); + $vars['id'] = dbFetchCell("SELECT `P`.`port_id` FROM `ports` AS `P` JOIN `devices` AS `D` ON `P`.`device_id` = `D`.`device_id` WHERE `D`.`hostname`=? AND `P`.`$port`=?", array($hostname, $vars['port'])); $app->response->headers->set('Content-Type', 'image/png'); include 'includes/graphs/graph.inc.php'; @@ -163,23 +170,23 @@ function list_devices() { } if (stristr($order, ' desc') === false && stristr($order, ' asc') === false) { - $order .= ' ASC'; + $order = '`'.$order.'` ASC'; } if ($type == 'all' || empty($type)) { $sql = '1'; } elseif ($type == 'ignored') { - $sql = "ignore='1' AND disabled='0'"; + $sql = "`ignore`='1' AND `disabled`='0'"; } elseif ($type == 'up') { - $sql = "status='1' AND ignore='0' AND disabled='0'"; + $sql = "`status`='1' AND `ignore`='0' AND `disabled`='0'"; } elseif ($type == 'down') { - $sql = "status='0' AND ignore='0' AND disabled='0'"; + $sql = "`status`='0' AND `ignore`='0' AND `disabled`='0'"; } elseif ($type == 'disabled') { - $sql = "disabled='1'"; + $sql = "`disabled`='1'"; } elseif ($type == 'mac') { $join = " LEFT JOIN `ports` ON `devices`.`device_id`=`ports`.`device_id` LEFT JOIN `ipv4_mac` ON `ports`.`port_id`=`ipv4_mac`.`port_id` "; @@ -890,12 +897,14 @@ function get_inventory() { function list_oxidized() { - // return details of a single device + global $config; $app = \Slim\Slim::getInstance(); $app->response->headers->set('Content-Type', 'application/json'); $devices = array(); - foreach (dbFetchRows("SELECT hostname,os FROM `devices` LEFT JOIN devices_attribs AS `DA` ON devices.device_id = DA.device_id AND `DA`.attrib_type='override_Oxidized_disable' WHERE `status`='1' AND (DA.attrib_value = 'false' OR DA.attrib_value IS NULL)") as $device) { + $device_types = "'".implode("','", $config['oxidized']['ignore_types'])."'"; + $device_os = "'".implode("','", $config['oxidized']['ignore_os'])."'"; + foreach (dbFetchRows("SELECT hostname,os FROM `devices` LEFT JOIN devices_attribs AS `DA` ON devices.device_id = DA.device_id AND `DA`.attrib_type='override_Oxidized_disable' WHERE `status`='1' AND (DA.attrib_value = 'false' OR DA.attrib_value IS NULL) AND (`type` NOT IN ($device_types) AND `os` NOT IN ($device_os))") as $device) { $devices[] = $device; } @@ -925,7 +934,7 @@ function list_bills() { $param = array($bill_ref); } elseif (is_numeric($bill_id)) { - $sql = '`bill_id` = ?'; + $sql = '`bills`.`bill_id` = ?'; $param = array($bill_id); } else { @@ -976,3 +985,109 @@ function list_bills() { $app->response->headers->set('Content-Type', 'application/json'); echo _json_encode($output); } + +function update_device() { + global $config; + $app = \Slim\Slim::getInstance(); + $router = $app->router()->getCurrentRoute()->getParams(); + $status = 'error'; + $code = 500; + $hostname = $router['hostname']; + // use hostname as device_id if it's all digits + $device_id = ctype_digit($hostname) ? $hostname : getidbyname($hostname); + $data = json_decode(file_get_contents('php://input'), true); + $bad_fields = array('id','hostname'); + if (empty($data['field'])) { + $message = 'Device field to patch has not been supplied'; + } + elseif (in_array($data['field'], $bad_fields)) { + $message = 'Device field is not allowed to be updated'; + } + else { + if (dbUpdate(array(mres($data['field']) => mres($data['data'])), 'devices', '`device_id`=?', array($device_id)) >= 0) { + $status = 'ok'; + $message = 'Device ' . mres($data['field']) . ' field has been updated'; + $code = 200; + } + else { + $message = 'Device ' . mres($data['field']) . ' field failed to be updated'; + } + } + $output = array( + 'status' => $status, + 'message' => $message, + ); + $app->response->setStatus($code); + $app->response->headers->set('Content-Type', 'application/json'); + echo _json_encode($output); +} + +function get_device_groups() { + $app = \Slim\Slim::getInstance(); + $router = $app->router()->getCurrentRoute()->getParams(); + $status = 'error'; + $code = 404; + $hostname = $router['hostname']; + // use hostname as device_id if it's all digits + $device_id = ctype_digit($hostname) ? $hostname : getidbyname($hostname); + if (is_numeric($device_id)) { + $groups = GetGroupsFromDevice($device_id,1); + } + else { + $groups = GetDeviceGroups(); + } + if (empty($groups)) { + $message = 'No device groups found'; + } + else { + $status = 'ok'; + $code = 200; + $message = 'Found ' . count($groups) . ' device groups'; + } + + $output = array( + 'status' => $status, + 'message' => $message, + 'count' => count($groups), + 'groups' => $groups, + ); + $app->response->setStatus($code); + $app->response->headers->set('Content-Type', 'application/json'); + echo _json_encode($output); +} + +function get_devices_by_group() { + $app = \Slim\Slim::getInstance(); + $router = $app->router()->getCurrentRoute()->getParams(); + $status = 'error'; + $code = 404; + $count = 0; + $name = urldecode($router['name']); + $devices = array(); + if (empty($name)) { + $message = 'No device group name provided'; + } + else { + $group_id = dbFetchCell("SELECT `id` FROM `device_groups` WHERE `name`=?",array($name)); + $devices = GetDevicesFromGroup($group_id); + $count = count($devices); + if (empty($devices)) { + $message = 'No devices found in group ' . $name; + } + else { + $message = "Found $count in group $name"; + $code = 200; + } + } + $output = array( + 'status' => $status, + 'message' => $message, + 'count' => $count, + 'devices' => $devices, + ); + + $app->response->setStatus($code); + $app->response->headers->set('Content-Type', 'application/json'); + echo _json_encode($output); + +} diff --git a/html/includes/authenticate.inc.php b/html/includes/authenticate.inc.php index f1f5087d2..12ccd7d2e 100644 --- a/html/includes/authenticate.inc.php +++ b/html/includes/authenticate.inc.php @@ -62,7 +62,7 @@ else { $auth_success = 0; if ((isset($_SESSION['username'])) || (isset($_COOKIE['sess_id'],$_COOKIE['token']))) { - if ((authenticate($_SESSION['username'], $_SESSION['password'])) || (reauthenticate($_COOKIE['sess_id'], $_COOKIE['token']))) { + if (reauthenticate($_COOKIE['sess_id'], $_COOKIE['token']) || authenticate($_SESSION['username'], $_SESSION['password'])) { $_SESSION['userlevel'] = get_userlevel($_SESSION['username']); $_SESSION['user_id'] = get_userid($_SESSION['username']); if (!$_SESSION['authenticated']) { diff --git a/html/includes/authentication/active_directory.inc.php b/html/includes/authentication/active_directory.inc.php new file mode 100644 index 000000000..633ac0c04 --- /dev/null +++ b/html/includes/authentication/active_directory.inc.php @@ -0,0 +1,307 @@ + 0) { + $search = ldap_search($ds, $config['auth_ad_base_dn'], + "(samaccountname={$username})", array('memberOf')); + $entries = ldap_get_entries($ds, $search); + + $user_authenticated = 0; + + foreach ($entries[0]['memberof'] as $entry) { + $group_cn = get_cn($entry); + if (isset($config['auth_ad_groups'][$group_cn]['level'])) { + // user is in one of the defined groups + $user_authenticated = 1; + adduser($username); + } + } + + return $user_authenticated; + + } + else { + // group membership is not required and user is valid + adduser($username); + return 1; + } + } + else { + return 0; + } + } + else { + echo ldap_error($ds); + } + + return 0; +} + +function reauthenticate() { + // not supported so return 0 + return 0; +} + + +function passwordscanchange() { + // not supported so return 0 + return 0; +} + + +function changepassword() { + // not supported so return 0 + return 0; +} + + +function auth_usermanagement() { + // not supported so return 0 + return 0; +} + + +function adduser($username) { + // Check to see if user is already added in the database + if (!user_exists_in_db($username)) { + $userid = dbInsert(array('username' => $username, 'user_id' => get_userid($username), 'level' => "0", 'can_modify_passwd' => 0, 'twofactor' => 0), 'users'); + if ($userid == false) { + return false; + } + else { + foreach (dbFetchRows('select notifications.* from notifications where not exists( select 1 from notifications_attribs where notifications.notifications_id = notifications_attribs.notifications_id and notifications_attribs.user_id = ?) order by notifications.notifications_id desc',array($userid)) as $notif) { + dbInsert(array('notifications_id'=>$notif['notifications_id'],'user_id'=>$userid,'key'=>'read','value'=>1),'notifications_attribs'); + } + } + return $userid; + } + else { + return false; + } +} + +function user_exists_in_db($username) { + $return = dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username), true); + return $return; +} + +function user_exists($username) { + global $config, $ds; + + $search = ldap_search($ds, $config['auth_ad_base_dn'], + "(samaccountname={$username})",array('samaccountname')); + $entries = ldap_get_entries($ds, $search); + + + if ($entries['count']) { + return 1; + } + + return 0; +} + + +function get_userlevel($username) { + global $config, $ds; + + $userlevel = 0; + + // Find all defined groups $username is in + $search = ldap_search($ds, $config['auth_ad_base_dn'], + "(samaccountname={$username})", array('memberOf')); + $entries = ldap_get_entries($ds, $search); + + // Loop the list and find the highest level + foreach ($entries[0]['memberof'] as $entry) { + $group_cn = get_cn($entry); + if ($config['auth_ad_groups'][$group_cn]['level'] > $userlevel) { + $userlevel = $config['auth_ad_groups'][$group_cn]['level']; + } + } + + return $userlevel; +} + + +function get_userid($username) { + global $config, $ds; + + $attributes = array('objectsid'); + $search = ldap_search($ds, $config['auth_ad_base_dn'], + "(samaccountname={$username})", $attributes); + $entries = ldap_get_entries($ds, $search); + + if ($entries['count']) { + return preg_replace('/.*-(\d+)$/','$1',sid_from_ldap($entries[0]['objectsid'][0])); + } + + return -1; +} + + +function deluser() { + // not supported so return 0 + return 0; +} + + +function get_userlist() { + global $config, $ds; + $userlist = array(); + $userhash = array(); + + $ldap_groups = get_group_list(); + + foreach($ldap_groups as $ldap_group) { + $group_cn = get_cn($ldap_group); + $search = ldap_search($ds, $config['auth_ad_base_dn'], "(cn={$group_cn})", array('member')); + $entries = ldap_get_entries($ds, $search); + + foreach($entries[0]['member'] as $member) { + $member_cn = get_cn($member); + $search = ldap_search($ds, $config['auth_ad_base_dn'], "(cn={$member_cn})", + array('sAMAccountname', 'displayName', 'objectSID', 'mail')); + $results = ldap_get_entries($ds, $search); + foreach($results as $result) { + if(isset($result['samaccountname'][0])) { + $userid = preg_replace('/.*-(\d+)$/','$1', + sid_from_ldap($result['objectsid'][0])); + + // don't make duplicates, user may be member of more than one group + $userhash[$result['samaccountname'][0]] = array( + 'realname' => $result['displayName'][0], + 'user_id' => $userid, + 'email' => $result['mail'][0] + ); + } + } + } + } + + foreach(array_keys($userhash) as $key) { + $userlist[] = array( + 'username' => $key, + 'realname' => $userhash[$key]['realname'], + 'user_id' => $userhash[$key]['user_id'], + 'email' => $userhash[$key]['email'] + ); + } + + return $userlist; +} + + +function can_update_users() { + // not supported so return 0 + return 0; +} + + +function get_user($user_id) { + // not supported so return 0 + return 0; +} + + +function update_user($user_id, $realname, $level, $can_modify_passwd, $email) { + // not supported so return 0 + return 0; + +} + + +function get_fullname($username) { + global $config, $ds; + + $attributes = array('name'); + $result = ldap_search($ds, $config['auth_ad_base_dn'], + "(samaccountname={$username})", $attributes); + $entries = ldap_get_entries($ds, $result); + if ($entries['count'] > 0) { + $membername = $entries[0]['name'][0]; + } + else { + $membername = $username; + } + + return $membername; +} + + +function get_group_list() { + global $config; + + $ldap_groups = array(); + + // show all Active Directory Users by default + $default_group = 'Users'; + + if (isset($config['auth_ad_group'])) { + if ($config['auth_ad_group'] !== $default_group) { + $ldap_groups[] = $config['auth_ad_group']; + } + } + + if (!isset($config['auth_ad_groups']) && !isset($config['auth_ad_group'])) { + $ldap_groups[] = get_dn($default_group); + } + + foreach ($config['auth_ad_groups'] as $key => $value) { + $ldap_groups[] = get_dn($key); + } + + return $ldap_groups; + +} + +function get_dn($samaccountname) { + global $config, $ds; + + + $attributes = array('dn'); + $result = ldap_search($ds, $config['auth_ad_base_dn'], + "(samaccountname={$samaccountname})", $attributes); + $entries = ldap_get_entries($ds, $result); + if ($entries['count'] > 0) { + return $entries[0]['dn']; + } + else { + return ''; + } +} + +function get_cn($dn) { + preg_match('/[^,]*/', $dn, $matches, PREG_OFFSET_CAPTURE, 3); + return $matches[0][0]; +} + +function sid_from_ldap($sid) +{ + $sidHex = unpack('H*hex', $sid); + $subAuths = unpack('H2/H2/n/N/V*', $sid); + $revLevel = hexdec(substr($sidHex, 0, 2)); + $authIdent = hexdec(substr($sidHex, 4, 12)); + return 'S-'.$revLevel.'-'.$authIdent.'-'.implode('-', $subAuths); +} diff --git a/html/includes/authentication/http-auth.inc.php b/html/includes/authentication/http-auth.inc.php index 221de3adc..691480181 100644 --- a/html/includes/authentication/http-auth.inc.php +++ b/html/includes/authentication/http-auth.inc.php @@ -44,11 +44,20 @@ function auth_usermanagement() { } -function adduser($username, $password, $level, $email='', $realname='', $can_modify_passwd='1') { +function adduser($username, $password, $level, $email='', $realname='', $can_modify_passwd=1, $description='', $twofactor=0) { if (!user_exists($username)) { $hasher = new PasswordHash(8, false); $encrypted = $hasher->HashPassword($password); - return dbInsert(array('username' => $username, 'password' => $encrypted, 'level' => $level, 'email' => $email, 'realname' => $realname), 'users'); + $userid = dbInsert(array('username' => $username, 'password' => $encrypted, 'level' => $level, 'email' => $email, 'realname' => $realname, 'can_modify_passwd' => $can_modify_passwd, 'descr' => $description, 'twofactor' => $twofactor), 'users'); + if ($userid == false) { + return false; + } + else { + foreach (dbFetchRows('select notifications.* from notifications where not exists( select 1 from notifications_attribs where notifications.notifications_id = notifications_attribs.notifications_id and notifications_attribs.user_id = ?) order by notifications.notifications_id desc',array($userid)) as $notif) { + dbInsert(array('notifications_id'=>$notif['notifications_id'],'user_id'=>$userid,'key'=>'read','value'=>1),'notifications_attribs'); + } + } + return $userid; } else { return false; diff --git a/html/includes/authentication/mysql.inc.php b/html/includes/authentication/mysql.inc.php index c16e716f8..0248d66b3 100644 --- a/html/includes/authentication/mysql.inc.php +++ b/html/includes/authentication/mysql.inc.php @@ -104,7 +104,16 @@ function adduser($username, $password, $level, $email='', $realname='', $can_mod if (!user_exists($username)) { $hasher = new PasswordHash(8, false); $encrypted = $hasher->HashPassword($password); - return dbInsert(array('username' => $username, 'password' => $encrypted, 'level' => $level, 'email' => $email, 'realname' => $realname, 'can_modify_passwd' => $can_modify_passwd, 'descr' => $description, 'twofactor' => $twofactor), 'users'); + $userid = dbInsert(array('username' => $username, 'password' => $encrypted, 'level' => $level, 'email' => $email, 'realname' => $realname, 'can_modify_passwd' => $can_modify_passwd, 'descr' => $description, 'twofactor' => $twofactor), 'users'); + if ($userid == false) { + return false; + } + else { + foreach (dbFetchRows('select notifications.* from notifications where not exists( select 1 from notifications_attribs where notifications.notifications_id = notifications_attribs.notifications_id and notifications_attribs.user_id = ?) order by notifications.notifications_id desc',array($userid)) as $notif) { + dbInsert(array('notifications_id'=>$notif['notifications_id'],'user_id'=>$userid,'key'=>'read','value'=>1),'notifications_attribs'); + } + } + return $userid; } else { return false; diff --git a/html/includes/authentication/radius.inc.php b/html/includes/authentication/radius.inc.php new file mode 100644 index 000000000..3e2fb1641 --- /dev/null +++ b/html/includes/authentication/radius.inc.php @@ -0,0 +1,120 @@ +SetDebugMode(TRUE); + } + $rad = $radius->AccessRequest($username,$password); + if($rad === true) { + adduser($username); + return 1; + } + else { + return 0; + } + } +} + +function reauthenticate() { + return 0; +} + + +function passwordscanchange() { + // not supported so return 0 + return 0; +} + + +function changepassword() { + // not supported so return 0 + return 0; +} + + +function auth_usermanagement() { + // not supported so return 0 + return 1; +} + + +function adduser($username, $password, $level=1, $email='', $realname='', $can_modify_passwd=0, $description='', $twofactor=0) { + // Check to see if user is already added in the database + global $config; + if (!user_exists($username)) { + $hasher = new PasswordHash(8, false); + $encrypted = $hasher->HashPassword($password); + if ($config['radius']['default_level'] > 0) { + $level = $config['radius']['default_level']; + } + $userid = dbInsert(array('username' => $username, 'password' => $encrypted, 'realname' => $realname, 'email' => $email, 'descr' => $description, 'level' => $level, 'can_modify_passwd' => $can_modify_passwd, 'twofactor' => $twofactor), 'users'); + if ($userid == false) { + return false; + } + else { + foreach (dbFetchRows('select notifications.* from notifications where not exists( select 1 from notifications_attribs where notifications.notifications_id = notifications_attribs.notifications_id and notifications_attribs.user_id = ?) order by notifications.notifications_id desc',array($userid)) as $notif) { + dbInsert(array('notifications_id'=>$notif['notifications_id'],'user_id'=>$userid,'key'=>'read','value'=>1),'notifications_attribs'); + } + } + return $userid; + } + else { + return false; + } +} + +function user_exists($username) { + return dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username), true); +} + + +function get_userlevel($username) { + return dbFetchCell('SELECT `level` FROM `users` WHERE `username` = ?', array($username), true); +} + + +function get_userid($username) { + return dbFetchCell('SELECT `user_id` FROM `users` WHERE `username` = ?', array($username), true); +} + + +function deluser($username) { + dbDelete('bill_perms', '`user_name` = ?', array($username)); + dbDelete('devices_perms', '`user_name` = ?', array($username)); + dbDelete('ports_perms', '`user_name` = ?', array($username)); + dbDelete('users_prefs', '`user_name` = ?', array($username)); + dbDelete('users', '`user_name` = ?', array($username)); + return dbDelete('users', '`username` = ?', array($username)); +} + + +function get_userlist() { + return dbFetchRows('SELECT * FROM `users`'); +} + + +function can_update_users() { + // supported so return 1 + return 1; +} + + +function get_user($user_id) { + return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id), true); +} + + +function update_user($user_id, $realname, $level, $can_modify_passwd, $email) { + dbUpdate(array('realname' => $realname, 'level' => $level, 'can_modify_passwd' => $can_modify_passwd, 'email' => $email), 'users', '`user_id` = ?', array($user_id)); + +} diff --git a/html/includes/common/generic-image.inc.php b/html/includes/common/generic-image.inc.php new file mode 100644 index 000000000..440168202 --- /dev/null +++ b/html/includes/common/generic-image.inc.php @@ -0,0 +1,54 @@ + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +/** + * Generic Image Widget + * @author Daniel Preussker + * @copyright 2015 Daniel Preussker, QuxLabs UG + * @license GPL + * @package LibreNMS + * @subpackage Widgets + */ + +if( defined('show_settings') || empty($widget_settings) ) { + $common_output[] = ' +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
'; +} +else { + $widget_settings['title'] = $widget_settings['image_title']; + $common_output[] = ''; +} diff --git a/html/includes/common/notes.inc.php b/html/includes/common/notes.inc.php new file mode 100644 index 000000000..9d2d17018 --- /dev/null +++ b/html/includes/common/notes.inc.php @@ -0,0 +1,39 @@ + + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +if( defined('show_settings') || empty($widget_settings) ) { + + $common_output[] = ' +
+
+
+ html is supported here. If you want just text then wrap in <pre></pre> +
+
+
+ +
+ +
+
+
+
+ +
+
+
'; +} +else { + $common_output[] = stripslashes(nl2br($widget_settings['notes'])); +} diff --git a/html/includes/common/worldmap.inc.php b/html/includes/common/worldmap.inc.php index bf9e6f36e..fabda7779 100644 --- a/html/includes/common/worldmap.inc.php +++ b/html/includes/common/worldmap.inc.php @@ -30,7 +30,7 @@ if ($config['map']['engine'] == 'leaflet') {
-
+
@@ -46,7 +46,7 @@ if ($config['map']['engine'] == 'leaflet') {
-
+
+
+
+ +
+
+ '; } + elseif ($type == 'text') { + return ''; + } }//end dynamic_override_config() function generate_dynamic_config_panel($title,$end_panel=true,$config_groups,$items=array(),$transport='') { @@ -1186,7 +1195,7 @@ function generate_dynamic_config_panel($title,$end_panel=true,$config_groups,$it

- '.$title.' + '.$title.' '; if (!empty($transport)) { $output .= ''; @@ -1249,3 +1258,9 @@ function generate_dynamic_config_panel($title,$end_panel=true,$config_groups,$it } return $output; }//end generate_dynamic_config_panel() + +function get_ripe_api_whois_data_json($ripe_data_param, $ripe_query_param) { + $ripe_whois_url = 'https://stat.ripe.net/data/'. $ripe_data_param . '/data.json?resource=' . $ripe_query_param; + return json_decode(file_get_contents($ripe_whois_url) , true); +}//end get_ripe_api_whois_data_json() + diff --git a/html/includes/graphs/XXX_device_memory_windows.inc.php b/html/includes/graphs/XXX_device_memory_windows.inc.php index 7122762da..731250de9 100644 --- a/html/includes/graphs/XXX_device_memory_windows.inc.php +++ b/html/includes/graphs/XXX_device_memory_windows.inc.php @@ -39,7 +39,7 @@ $rrd_options .= ' GPRINT:availreal:LAST:\ \ \ %7.2lf%sB'; $rrd_options .= ' GPRINT:availreal:AVERAGE:%7.2lf%sB'; $rrd_options .= " GPRINT:availreal:MAX:%7.2lf%sB\\\\n"; $rrd_options .= ' LINE1:usedreal#d0b080:'; -$rrd_options .= ' AREA:shared#afeced::'; +$rrd_options .= ' AREA:shared#afeced:'; $rrd_options .= ' AREA:buffered#cc0000::STACK'; $rrd_options .= ' AREA:cached#ffaa66::STACK'; $rrd_options .= ' LINE1.25:shared#008fea:shared'; diff --git a/html/includes/graphs/application/ceph_osd_performance.inc.php b/html/includes/graphs/application/ceph_osd_performance.inc.php new file mode 100644 index 000000000..58381a978 --- /dev/null +++ b/html/includes/graphs/application/ceph_osd_performance.inc.php @@ -0,0 +1,25 @@ + $filena $colour = $config['graph_colours'][$colourset][$iter]; $iter++; + // FIXME: $descr unused? -- PDG 2015-11-14 $descr = rrdtool_escape($source, $descr_len); $filename = generate_smokeping_file($device,$filename); diff --git a/html/includes/graphs/device/storage.inc.php b/html/includes/graphs/device/storage.inc.php index 769e9ce91..e52e8fa65 100644 --- a/html/includes/graphs/device/storage.inc.php +++ b/html/includes/graphs/device/storage.inc.php @@ -42,6 +42,6 @@ foreach (dbFetchRows('SELECT * FROM storage where device_id = ?', array($device[ $rrd_options .= " LINE1.25:$storage[storage_id]perc#".$colour.":'$descr'"; $rrd_options .= " GPRINT:$storage[storage_id]size:LAST:%6.2lf%sB"; $rrd_options .= " GPRINT:$storage[storage_id]used:LAST:%6.2lf%sB"; - $rrd_options .= " GPRINT:$storage[storage_id]perc:LAST:%5.2lf%%\\\\l"; + $rrd_options .= " GPRINT:$storage[storage_id]perc:LAST:%5.2lf%%\\l"; $iter++; }//end foreach diff --git a/html/includes/graphs/device/ucd_load.inc.php b/html/includes/graphs/device/ucd_load.inc.php index ccdf61ee5..1a5e5ab9a 100644 --- a/html/includes/graphs/device/ucd_load.inc.php +++ b/html/includes/graphs/device/ucd_load.inc.php @@ -14,12 +14,12 @@ $rrd_options .= ' CDEF:b=5min,100,/'; $rrd_options .= ' CDEF:c=15min,100,/'; $rrd_options .= ' CDEF:cdefd=a,b,c,+,+'; $rrd_options .= " COMMENT:'Load Average Current Average Maximum\\n'"; -$rrd_options .= " AREA:a#ffeeaa:'1 Min':"; +$rrd_options .= " AREA:a#ffeeaa:'1 Min'"; $rrd_options .= ' LINE1:a#c5aa00:'; $rrd_options .= " GPRINT:a:LAST:' %7.2lf'"; $rrd_options .= " GPRINT:a:AVERAGE:' %7.2lf'"; $rrd_options .= " GPRINT:a:MAX:' %7.2lf\\n'"; -$rrd_options .= " LINE1.25:b#ea8f00:'5 Min':"; +$rrd_options .= " LINE1.25:b#ea8f00:'5 Min'"; $rrd_options .= " GPRINT:b:LAST:' %7.2lf'"; $rrd_options .= " GPRINT:b:AVERAGE:' %7.2lf'"; $rrd_options .= " GPRINT:b:MAX:' %7.2lf\\n'"; diff --git a/html/includes/graphs/device/ucd_memory.inc.php b/html/includes/graphs/device/ucd_memory.inc.php index 606fed717..05c0dd685 100644 --- a/html/includes/graphs/device/ucd_memory.inc.php +++ b/html/includes/graphs/device/ucd_memory.inc.php @@ -73,7 +73,7 @@ $rrd_options .= " 'COMMENT: \\n'"; $rrd_options .= " 'LINE1:usedreal#d0b080:'"; -$rrd_options .= " 'AREA:shared#afeced::'"; +$rrd_options .= " 'AREA:shared#afeced:'"; $rrd_options .= " 'AREA:buffered#cc0000::STACK'"; $rrd_options .= " 'AREA:cached#ffaa66::STACK'"; diff --git a/html/includes/graphs/generic_data.inc.php b/html/includes/graphs/generic_data.inc.php index e13fce80c..46560b036 100644 --- a/html/includes/graphs/generic_data.inc.php +++ b/html/includes/graphs/generic_data.inc.php @@ -87,7 +87,7 @@ $rrd_options .= ' VDEF:tot=octets,TOTAL'; $rrd_options .= ' VDEF:95thin=inbits,95,PERCENT'; $rrd_options .= ' VDEF:95thout=outbits,95,PERCENT'; -$rrd_options .= ' VDEF:d95thout=doutbits,5,PERCENT'; +$rrd_options .= ' CDEF:d95thoutn=doutbits,-1,* VDEF:d95thoutn95=d95thoutn,95,PERCENT CDEF:d95thoutn95n=doutbits,doutbits,-,d95thoutn95,-1,*,+ VDEF:d95thout=d95thoutn95n,FIRST'; if ($format == 'octets' || $format == 'bytes') { $units = 'Bps'; @@ -107,7 +107,7 @@ $rrd_options .= ' LINE:in'.$format."#608720:'In '"; $rrd_options .= ' GPRINT:in'.$format.':LAST:%6.2lf%s'; $rrd_options .= ' GPRINT:in'.$format.':AVERAGE:%6.2lf%s'; $rrd_options .= ' GPRINT:in'.$format.'_max:MAX:%6.2lf%s'; -$rrd_options .= " GPRINT:95thin:%6.2lf%s\\\\n"; +$rrd_options .= " GPRINT:95thin:%6.2lf%s\\n"; $rrd_options .= ' AREA:dout'.$format.'_max#E0E0FF:'; $rrd_options .= ' AREA:dout'.$format.'#8080C0:'; @@ -116,7 +116,7 @@ $rrd_options .= ' LINE:dout'.$format."#606090:'Out'"; $rrd_options .= ' GPRINT:out'.$format.':LAST:%6.2lf%s'; $rrd_options .= ' GPRINT:out'.$format.':AVERAGE:%6.2lf%s'; $rrd_options .= ' GPRINT:out'.$format.'_max:MAX:%6.2lf%s'; -$rrd_options .= " GPRINT:95thout:%6.2lf%s\\\\n"; +$rrd_options .= " GPRINT:95thout:%6.2lf%s\\n"; if ($config['rrdgraph_real_95th']) { $rrd_options .= ' HRULE:95thhigh#FF0000:"Highest"'; @@ -125,7 +125,7 @@ if ($config['rrdgraph_real_95th']) { $rrd_options .= " GPRINT:tot:'Total %6.2lf%s'"; $rrd_options .= " GPRINT:totin:'(In %6.2lf%s'"; -$rrd_options .= " GPRINT:totout:'Out %6.2lf%s)\\\\l'"; +$rrd_options .= " GPRINT:totout:'Out %6.2lf%s)\\l'"; $rrd_options .= ' LINE1:95thin#aa0000'; $rrd_options .= ' LINE1:d95thout#aa0000'; diff --git a/html/includes/graphs/generic_multi.inc.php b/html/includes/graphs/generic_multi.inc.php index d02e82ebb..6d7f78a1c 100644 --- a/html/includes/graphs/generic_multi.inc.php +++ b/html/includes/graphs/generic_multi.inc.php @@ -11,7 +11,7 @@ else { } if ($nototal) { - $descrlen += '2'; + $descr_len += '2'; $unitlen += '2'; } @@ -57,16 +57,16 @@ foreach ($rrd_list as $rrd) { if ($rrd['invert']) { $rrd_options .= ' CDEF:'.$id.'i='.$id.',-1,*'; - $rrd_optionsc .= ' AREA:'.$id.'i#'.$colour.":'$descr':".$cstack; + $rrd_optionsc .= ' AREA:'.$id.'i#'.$colour.":'$descr'".$cstack; $rrd_optionsc .= ' GPRINT:'.$id.':LAST:%5.1lf%s GPRINT:'.$id.'min:MIN:%5.1lf%s'; $rrd_optionsc .= ' GPRINT:'.$id.'max:MAX:%5.1lf%s GPRINT:'.$id.":AVERAGE:'%5.1lf%s\\n'"; - $cstack = 'STACK'; + $cstack = ':STACK'; } else { - $rrd_optionsb .= ' AREA:'.$id.'#'.$colour.":'$descr':".$bstack; + $rrd_optionsb .= ' AREA:'.$id.'#'.$colour.":'$descr'".$bstack; $rrd_optionsb .= ' GPRINT:'.$id.':LAST:%5.1lf%s GPRINT:'.$id.'min:MIN:%5.1lf%s'; $rrd_optionsb .= ' GPRINT:'.$id.'max:MAX:%5.1lf%s GPRINT:'.$id.":AVERAGE:'%5.1lf%s\\n'"; - $bstack = 'STACK'; + $bstack = ':STACK'; } $i++; diff --git a/html/includes/graphs/generic_multi_bits.inc.php b/html/includes/graphs/generic_multi_bits.inc.php index caa765e4d..5233fdb81 100644 --- a/html/includes/graphs/generic_multi_bits.inc.php +++ b/html/includes/graphs/generic_multi_bits.inc.php @@ -57,7 +57,7 @@ if ($i) { $rrd_options .= ' CDEF:doutbits=doutoctets,8,*'; $rrd_options .= ' VDEF:95thin=inbits,95,PERCENT'; $rrd_options .= ' VDEF:95thout=outbits,95,PERCENT'; - $rrd_options .= ' VDEF:d95thout=doutbits,5,PERCENT'; + $rrd_options .= ' CDEF:d95thoutn=doutbits,-1,* VDEF:d95thoutn95=d95thoutn,95,PERCENT CDEF:d95thoutn95n=doutbits,doutbits,-,d95thoutn95,-1,*,+ VDEF:d95thout=d95thoutn95n,FIRST'; if ($_GET['previous'] == 'yes') { $rrd_options .= ' CDEF:'.$in.'octetsX='.$in_thingX.$pluses; @@ -68,7 +68,7 @@ if ($i) { $rrd_options .= ' CDEF:doutbitsX=doutoctetsX,8,*'; $rrd_options .= ' VDEF:95thinX=inbitsX,95,PERCENT'; $rrd_options .= ' VDEF:95thoutX=outbitsX,95,PERCENT'; - $rrd_options .= ' VDEF:d95thoutX=doutbitsX,5,PERCENT'; + $rrd_options .= ' CDEF:d95thoutXn=doutbitsX,-1,* VDEF:d95thoutXn95=d95thoutXn,95,PERCENT CDEF:d95thoutXn95n=doutbitsX,doutbitsX,-,d95thoutXn95,-1,*,+ VDEF:d95thoutX=d95thoutXn95n,FIRST'; } if ($legend == 'no' || $legend == '1') { diff --git a/html/includes/graphs/generic_multi_bits_separated.inc.php b/html/includes/graphs/generic_multi_bits_separated.inc.php index 181f0ae4d..88bbdec99 100644 --- a/html/includes/graphs/generic_multi_bits_separated.inc.php +++ b/html/includes/graphs/generic_multi_bits_separated.inc.php @@ -49,9 +49,6 @@ foreach ($rrd_list as $rrd) { } $descr_out = rrdtool_escape($rrd['descr_out'], $descr_len).' Out'; - $descr = str_replace("'", '', $descr); - // FIXME does this mean ' should be filtered in rrdtool_escape? probably... - $descr_out = str_replace("'", '', $descr_out); } $rrd_options .= ' DEF:'.$in.$i.'='.$rrd['filename'].':'.$ds_in.':AVERAGE '; @@ -68,10 +65,10 @@ foreach ($rrd_list as $rrd) { } if ($i) { - $stack = 'STACK'; + $stack = ':STACK'; } - $rrd_options .= ' AREA:inB'.$i.'#'.$colour_in.":'".$descr."':$stack"; + $rrd_options .= ' AREA:inB'.$i.'#'.$colour_in.":'".$descr."'$stack"; if (!$nodetails) { $rrd_options .= ' GPRINT:inB'.$i.":LAST:%6.2lf%s$units"; $rrd_options .= ' GPRINT:inB'.$i.":AVERAGE:%6.2lf%s$units"; @@ -84,7 +81,7 @@ foreach ($rrd_list as $rrd) { } $rrd_options .= " 'HRULE:0#".$colour_out.':'.$descr_out."'"; - $rrd_optionsb .= " 'AREA:outB".$i.'_neg#'.$colour_out."::$stack'"; + $rrd_optionsb .= " 'AREA:outB".$i.'_neg#'.$colour_out.":$stack'"; if (!$nodetails) { $rrd_options .= ' GPRINT:outB'.$i.":LAST:%6.2lf%s$units"; diff --git a/html/includes/graphs/generic_multi_data.inc.php b/html/includes/graphs/generic_multi_data.inc.php index 90f5c908e..d3ab6c2e2 100644 --- a/html/includes/graphs/generic_multi_data.inc.php +++ b/html/includes/graphs/generic_multi_data.inc.php @@ -66,7 +66,7 @@ if ($i) { $rrd_options .= ' CDEF:doutbits=doutoctets,8,*'; $rrd_options .= ' VDEF:95thin=inbits,95,PERCENT'; $rrd_options .= ' VDEF:95thout=outbits,95,PERCENT'; - $rrd_options .= ' VDEF:d95thout=doutbits,5,PERCENT'; + $rrd_options .= ' CDEF:d95thoutn=doutbits,-1,* VDEF:d95thoutn95=d95thoutn,95,PERCENT CDEF:d95thoutn95n=doutbits,doutbits,-,d95thoutn95,-1,*,+ VDEF:d95thout=d95thoutn95n,FIRST'; if ($_GET['previous'] == 'yes') { $rrd_options .= ' CDEF:'.$in.'octetsX='.$in_thingX.$pluses; @@ -77,7 +77,7 @@ if ($i) { $rrd_options .= ' CDEF:doutbitsX=doutoctetsX,8,*'; $rrd_options .= ' VDEF:95thinX=inbitsX,95,PERCENT'; $rrd_options .= ' VDEF:95thoutX=outbitsX,95,PERCENT'; - $rrd_options .= ' VDEF:d95thoutX=doutbitsX,5,PERCENT'; + $rrd_options .= ' CDEF:d95thoutXn=doutbitsX,-1,* VDEF:d95thoutXn95=d95thoutXn,95,PERCENT CDEF:d95thoutXn95n=doutbitsX,doutbitsX,-,d95thoutXn95,-1,*,+ VDEF:d95thoutX=d95thoutXn95n,FIRST'; } if ($legend == 'no' || $legend == '1') { diff --git a/html/includes/graphs/generic_multi_data_separated.inc.php b/html/includes/graphs/generic_multi_data_separated.inc.php index 7865d03de..07caefd37 100644 --- a/html/includes/graphs/generic_multi_data_separated.inc.php +++ b/html/includes/graphs/generic_multi_data_separated.inc.php @@ -45,9 +45,6 @@ foreach ($rrd_list as $rrd) { } $descr_out = rrdtool_escape($rrd['descr_out'], $descr_len).' Out'; - $descr = str_replace("'", '', $descr); - // FIXME does this mean ' should be filtered in rrdtool_escape? probably... - $descr_out = str_replace("'", '', $descr_out); $rrd_options .= ' DEF:'.$in.$i.'='.$rrd['filename'].':'.$ds_in.':AVERAGE '; $rrd_options .= ' DEF:'.$out.$i.'='.$rrd['filename'].':'.$ds_out.':AVERAGE '; @@ -69,10 +66,10 @@ foreach ($rrd_list as $rrd) { } if ($i) { - $stack = 'STACK'; + $stack = ':STACK'; } - $rrd_options .= ' AREA:inB'.$i.'#'.$colour_in.":'".$descr."':$stack"; + $rrd_options .= ' AREA:inB'.$i.'#'.$colour_in.":'".$descr."'$stack"; $rrd_options .= ' GPRINT:inB'.$i.":LAST:%6.2lf%s$units"; $rrd_options .= ' GPRINT:inB'.$i.":AVERAGE:%6.2lf%s$units"; $rrd_options .= ' GPRINT:inB'.$i.":MAX:%6.2lf%s$units\l"; @@ -82,7 +79,7 @@ foreach ($rrd_list as $rrd) { } $rrd_options .= " 'HRULE:0#".$colour_out.':'.$descr_out."'"; - $rrd_optionsb .= " 'AREA:outB".$i.'_neg#'.$colour_out."::$stack'"; + $rrd_optionsb .= " 'AREA:outB".$i.'_neg#'.$colour_out.":$stack'"; $rrd_options .= ' GPRINT:outB'.$i.":LAST:%6.2lf%s$units"; $rrd_options .= ' GPRINT:outB'.$i.":AVERAGE:%6.2lf%s$units"; $rrd_options .= ' GPRINT:outB'.$i.":MAX:%6.2lf%s$units\l"; @@ -111,13 +108,13 @@ if (!$nototal) { $rrd_options .= ' VDEF:95thin=inbits,95,PERCENT'; $rrd_options .= ' VDEF:95thout=outbits,95,PERCENT'; - $rrd_options .= ' VDEF:d95thout=doutbits,5,PERCENT'; + $rrd_options .= ' CDEF:d95thoutn=doutbits,-1,* VDEF:d95thoutn95=d95thoutn,95,PERCENT CDEF:d95thoutn95n=doutbits,doutbits,-,d95thoutn95,-1,*,+ VDEF:d95thout=d95thoutn95n,FIRST'; $rrd_options .= ' VDEF:totin=inoctets,TOTAL'; $rrd_options .= ' VDEF:totout=outoctets,TOTAL'; $rrd_options .= ' VDEF:tot=octets,TOTAL'; - // $rrd_options .= " AREA:totin#" . $colour_in . ":'" . $descr . "':$stack"; + // $rrd_options .= " AREA:totin#" . $colour_in . ":'" . $descr . "'$stack"; // $rrd_options .= " GPRINT:totin:LAST:%6.2lf%s$units"; // $rrd_options .= " GPRINT:totin:AVERAGE:%6.2lf%s$units"; // $rrd_options .= " GPRINT:totin:MAX:%6.2lf%s$units\l"; diff --git a/html/includes/graphs/generic_multi_line.inc.php b/html/includes/graphs/generic_multi_line.inc.php index c34d78e77..513b23674 100644 --- a/html/includes/graphs/generic_multi_line.inc.php +++ b/html/includes/graphs/generic_multi_line.inc.php @@ -11,7 +11,7 @@ else { } if ($nototal) { - $descrlen += '2'; + $descr_len += '2'; $unitlen += '2'; } diff --git a/html/includes/graphs/generic_multi_seperated.inc.php b/html/includes/graphs/generic_multi_seperated.inc.php index 9b37f3751..e45752d40 100644 --- a/html/includes/graphs/generic_multi_seperated.inc.php +++ b/html/includes/graphs/generic_multi_seperated.inc.php @@ -71,7 +71,7 @@ foreach ($rrd_list as $rrd) { } if ($i) { - $stack = 'STACK'; + $stack = ':STACK'; } $rrd_options .= ' AREA:inbits'.$i.'#'.$colour_in.":'".rrdtool_escape($rrd['descr'], 9)."In '$stack"; @@ -84,7 +84,7 @@ foreach ($rrd_list as $rrd) { } $rrd_options .= " COMMENT:'\\n'"; - $rrd_optionsb .= ' AREA:outbits'.$i.'_neg#'.$colour_out.":$stack"; + $rrd_optionsb .= ' AREA:outbits'.$i.'_neg#'.$colour_out."$stack"; $rrd_options .= ' HRULE:999999999999999#'.$colour_out.":'".str_pad('', 10)."Out'"; $rrd_options .= ' GPRINT:outbits'.$i.':LAST:%6.2lf%s'; $rrd_options .= ' GPRINT:outbits'.$i.':AVERAGE:%6.2lf%s'; @@ -111,7 +111,7 @@ if ($_GET['previous'] == 'yes') { $rrd_options .= ' CDEF:doutbitsX=doutBX,8,*'; $rrd_options .= ' VDEF:95thinX=inbitsX,95,PERCENT'; $rrd_options .= ' VDEF:95thoutX=outbitsX,95,PERCENT'; - $rrd_options .= ' VDEF:d95thoutX=doutbitsX,5,PERCENT'; + $rrd_options .= ' CDEF:d95thoutXn=doutbitsX,-1,* VDEF:d95thoutXn95=d95thoutXn,95,PERCENT CDEF:d95thoutXn95n=doutbitsX,doutbitsX,-,d95thoutXn95,-1,*,+ VDEF:d95thoutX=d95thoutXn95n,FIRST'; } if ($_GET['previous'] == 'yes') { @@ -132,7 +132,7 @@ if (!$args['nototal']) { $rrd_options .= ' CDEF:doutbits=doutB,8,*'; $rrd_options .= ' VDEF:95thin=inbits,95,PERCENT'; $rrd_options .= ' VDEF:95thout=outbits,95,PERCENT'; - $rrd_options .= ' VDEF:d95thout=doutbits,5,PERCENT'; + $rrd_options .= ' CDEF:d95thoutn=doutbits,-1,* VDEF:d95thoutn95=d95thoutn,95,PERCENT CDEF:d95thoutn95n=doutbits,doutbits,-,d95thoutn95,-1,*,+ VDEF:d95thout=d95thoutn95n,FIRST'; $rrd_options .= ' VDEF:totin=inB,TOTAL'; $rrd_options .= ' VDEF:avein=inbits,AVERAGE'; $rrd_options .= ' VDEF:totout=outB,TOTAL'; diff --git a/html/includes/graphs/generic_multi_simplex_seperated.inc.php b/html/includes/graphs/generic_multi_simplex_seperated.inc.php index 18df802ae..6125cb807 100644 --- a/html/includes/graphs/generic_multi_simplex_seperated.inc.php +++ b/html/includes/graphs/generic_multi_simplex_seperated.inc.php @@ -12,7 +12,7 @@ else { } if ($nototal) { - $descrlen += '2'; + $descr_len += '2'; $unitlen += '2'; } @@ -32,7 +32,7 @@ else { $unitlen = '10'; if ($nototal) { - $descrlen += '2'; + $descr_len += '2'; $unitlen += '2'; } @@ -81,7 +81,7 @@ foreach ($rrd_list as $i => $rrd) { // This this not the first entry? if ($i) { - $stack = 'STACK'; + $stack = ':STACK'; } // if we've been passed a multiplier we must make a CDEF based on it! @@ -109,13 +109,13 @@ foreach ($rrd_list as $i => $rrd) { $t_defname = $g_defname; } - $rrd_options .= ' AREA:'.$g_defname.$i.'#'.$colour.":'".$descr."':$stack"; + $rrd_options .= ' AREA:'.$g_defname.$i.'#'.$colour.":'".$descr."'$stack"; $rrd_options .= ' GPRINT:'.$t_defname.$i.':LAST:%5.2lf%s GPRINT:'.$t_defname.$i.'min:MIN:%5.2lf%s'; $rrd_options .= ' GPRINT:'.$t_defname.$i.'max:MAX:%5.2lf%s GPRINT:'.$t_defname.$i.":AVERAGE:'%5.2lf%s\\n'"; if (!$nototal) { - $rrd_options .= ' GPRINT:tot'.$rrd['ds'].$i.':%6.2lf%s'.rrdtool_escape($total_units).''; + $rrd_options .= ' GPRINT:tot'.$rrd['ds'].$i.":%6.2lf%s'".rrdtool_escape($total_units)."'"; } $rrd_options .= " COMMENT:'\\n'"; diff --git a/html/includes/graphs/munin/graph.inc.php b/html/includes/graphs/munin/graph.inc.php index 9b634813b..cae85137f 100644 --- a/html/includes/graphs/munin/graph.inc.php +++ b/html/includes/graphs/munin/graph.inc.php @@ -50,7 +50,7 @@ foreach ($dbq as $ds) { $descr = rrdtool_escape($ds['ds_label'], $descr_len); - $cmd_graph .= ' '.$ds['ds_draw'].':'.$ds_name.'#'.$colour.':"'.$descr.'"'; + $cmd_graph .= ' '.$ds['ds_draw'].':'.$ds_name.'#'.$colour.":'".$descr."'"; $cmd_graph .= ' GPRINT:'.$ds_name.':LAST:"%6.2lf%s"'; $cmd_graph .= ' GPRINT:'.$ds_name.':AVERAGE:"%6.2lf%s"'; $cmd_graph .= ' GPRINT:'.$ds_name.':MAX:"%6.2lf%s\\n"'; diff --git a/html/includes/graphs/old_generic_simplex.inc.php b/html/includes/graphs/old_generic_simplex.inc.php index 24a93147c..91cd0612e 100644 --- a/html/includes/graphs/old_generic_simplex.inc.php +++ b/html/includes/graphs/old_generic_simplex.inc.php @@ -20,7 +20,7 @@ else { } if ($print_total) { - $rrd_options .= ' VDEF:'.$ds.'_total=ds,TOTAL'; + $rrd_options .= ' VDEF:'.$ds.'_total='.$ds.',TOTAL'; } if ($percentile) { @@ -43,7 +43,7 @@ if ($_GET['previous'] == 'yes') { } if ($print_total) { - $rrd_options .= ' VDEF:'.$ds.'_totalX=ds,TOTAL'; + $rrd_options .= ' VDEF:'.$ds.'_totalX='.$ds.',TOTAL'; } if ($percentile) { @@ -74,11 +74,11 @@ if ($percentile) { $rrd_options .= ' GPRINT:'.$ds.'_percentile:%6.2lf%s'; } -$rrd_options .= "\\\\n"; -$rrd_options .= " COMMENT:\\\\n"; +$rrd_options .= "\\n"; +$rrd_options .= " COMMENT:\\n"; if ($print_total) { - $rrd_options .= ' GPRINT:'.$ds.'_tot:Total\ %6.2lf%s\)\\\\l'; + $rrd_options .= ' GPRINT:'.$ds.'_total:Total" %6.2lf%s"\\l'; } if ($percentile) { @@ -86,6 +86,6 @@ if ($percentile) { } if ($_GET['previous'] == 'yes') { - $rrd_options .= ' LINE1.25:'.$ds."X#666666:'Prev \\\\n'"; + $rrd_options .= ' LINE1.25:'.$ds."X#666666:'Prev \\n'"; $rrd_options .= ' AREA:'.$ds.'X#99999966:'; } diff --git a/html/includes/graphs/processor/usage.inc.php b/html/includes/graphs/processor/usage.inc.php index 5954685d7..53db2c490 100644 --- a/html/includes/graphs/processor/usage.inc.php +++ b/html/includes/graphs/processor/usage.inc.php @@ -5,6 +5,7 @@ $scale_max = '100'; $ds = 'usage'; +// FIXME: As far as I can tell, $descr is never mentioned in includes/graphs/generic_simplex.inc.php -- PDG 2015-11-14 $descr = rrdtool_escape(short_hrDeviceDescr($proc['processor_descr']), 28); $colour_line = 'cc0000'; diff --git a/html/includes/graphs/sensor/temperature.inc.php b/html/includes/graphs/sensor/temperature.inc.php index c8ffb312d..05f7ed0ef 100644 --- a/html/includes/graphs/sensor/temperature.inc.php +++ b/html/includes/graphs/sensor/temperature.inc.php @@ -19,7 +19,7 @@ $rrd_options .= ' AREA:sensor_diff#c5c5c5::STACK'; $rrd_options .= " LINE1.5:sensor#cc0000:'".rrdtool_escape($sensor['sensor_descr'], 21)."'"; $rrd_options .= ' GPRINT:sensor_min:MIN:%4.1lfC'; $rrd_options .= ' GPRINT:sensor:LAST:%4.1lfC'; -$rrd_options .= ' GPRINT:sensor_max:MAX:%4.1lfC\\\\l'; +$rrd_options .= ' GPRINT:sensor_max:MAX:%4.1lfC\\l'; if (is_numeric($sensor['sensor_limit'])) { $rrd_options .= ' HRULE:'.$sensor['sensor_limit'].'#999999::dashes'; diff --git a/html/includes/jpgraph/src/jpgraph.php b/html/includes/jpgraph/src/jpgraph.php index f5df2afe3..a92e58836 100644 --- a/html/includes/jpgraph/src/jpgraph.php +++ b/html/includes/jpgraph/src/jpgraph.php @@ -222,21 +222,16 @@ if (!defined('MBTTF_DIR')) { } } -// -// Check minimum PHP version -// +/* + * Check minimum PHP version + * @author f0o + * @copyright 2015 f0o, LibreNMS + * @license GPL + * @package LibreNMS + * @subpackage Billing + */ function CheckPHPVersion($aMinVersion) { - list($majorC, $minorC, $editC) = preg_split('/[\/.-]/', PHP_VERSION); - list($majorR, $minorR, $editR) = preg_split('/[\/.-]/', $aMinVersion); - - if ($majorC != $majorR) return false; - if ($majorC < $majorR) return false; - // same major - check minor - if ($minorC > $minorR) return true; - if ($minorC < $minorR) return false; - // and same minor - if ($editC >= $editR) return true; - return true; + return version_compare(PHP_VERSION, $aMinVersion, '>='); } // diff --git a/html/includes/print-alert-rules.php b/html/includes/print-alert-rules.php index 14ae13e0c..6a287604b 100644 --- a/html/includes/print-alert-rules.php +++ b/html/includes/print-alert-rules.php @@ -132,7 +132,6 @@ foreach ($result_options as $option) { echo ''; -$rulei = 1; $count_query = 'SELECT COUNT(id)'; $full_query = 'SELECT *'; $sql = ''; @@ -142,7 +141,7 @@ if (isset($device['device_id']) && $device['device_id'] > 0) { $param = array($device['device_id']); } -$query = " FROM alert_rules $sql ORDER BY device_id,id"; +$query = " FROM alert_rules $sql ORDER BY id ASC"; $count_query = $count_query.$query; $count = dbFetchCell($count_query, $param); if (!isset($_POST['page_number']) && $_POST['page_number'] < 1) { @@ -199,7 +198,7 @@ foreach (dbFetchRows($full_query, $param) as $rule) { $popover_msg = 'Device specific rule'; } echo ""; - echo '#'.((int) $rulei++).''; + echo '#'.((int) $rule['id']).''; echo ''.$rule['name'].''; echo ""; if ($rule_extra['invert'] === true) { diff --git a/html/includes/print-graphrow.inc.php b/html/includes/print-graphrow.inc.php index 2ee411551..f6157a953 100644 --- a/html/includes/print-graphrow.inc.php +++ b/html/includes/print-graphrow.inc.php @@ -37,6 +37,22 @@ else { ); }//end if +if($_SESSION['screen_width']) { + if($_SESSION['screen_width'] < 1024 && $_SESSION['screen_width'] > 700) { + $graph_array['width'] = round(($_SESSION['screen_width'] - 90 )/2,0); + } + else { + if($_SESSION['screen_width'] > 1024) { + $graph_array['width'] = round(($_SESSION['screen_width'] - 90 )/count($periods)+1,0); + } + else { + $graph_array['width'] = $_SESSION['screen_width'] - 70; + } + } +} + +$graph_array['height'] = round($graph_array['width'] /2.15); + $graph_array['to'] = $config['time']['now']; $graph_data = array(); diff --git a/html/includes/print-interface.inc.php b/html/includes/print-interface.inc.php index 223c169fc..1c02fb8a1 100644 --- a/html/includes/print-interface.inc.php +++ b/html/includes/print-interface.inc.php @@ -36,11 +36,20 @@ else { $mac = ''; } -echo " - "; -echo ' +echo " + "; + +// Don't echo out ports ifIndex if it's a NOS device since their ifIndex is, for lack of better words....different +if ($device['os'] == 'nos') { + echo ' + '.generate_port_link($port, $port['label'])." $error_img $mac +
".$port['ifAlias'].''; +} +else { + echo ' '.generate_port_link($port, $port['ifIndex'].'. '.$port['label'])." $error_img $mac
".$port['ifAlias'].''; +} if ($port['ifAlias']) { echo '
'; @@ -50,19 +59,19 @@ unset($break); if ($port_details) { foreach (dbFetchRows('SELECT * FROM `ipv4_addresses` WHERE `port_id` = ?', array($port['port_id'])) as $ip) { - echo "$break ".$ip['ipv4_address'].'/'.$ip['ipv4_prefixlen'].''; + echo "$break ".$ip['ipv4_address'].'/'.$ip['ipv4_prefixlen'].''; $break = '
'; } foreach (dbFetchRows('SELECT * FROM `ipv6_addresses` WHERE `port_id` = ?', array($port['port_id'])) as $ip6) { - echo "$break ".Net_IPv6::compress($ip6['ipv6_address']).'/'.$ip6['ipv6_prefixlen'].''; + echo "$break ".Net_IPv6::compress($ip6['ipv6_address']).'/'.$ip6['ipv6_prefixlen'].''; $break = '
'; } } echo '
'; -echo ''; +echo ""; if ($port_details) { $port['graph_type'] = 'port_bits'; @@ -73,7 +82,7 @@ if ($port_details) { echo generate_port_link($port, ""); } -echo ''; +echo ""; if ($port['ifOperStatus'] == 'up') { $port['in_rate'] = ($port['ifInOctets_rate'] * 8); @@ -86,7 +95,7 @@ if ($port['ifOperStatus'] == 'up') { ".format_bi($port['ifOutUcastPkts_rate']).'pps'; } -echo ''; +echo ""; if ($port['ifSpeed']) { echo ''.humanspeed($port['ifSpeed']).''; } @@ -130,19 +139,19 @@ if ($device['os'] == 'ios' || $device['os'] == 'iosxe') { }//end if if ($port_adsl['adslLineCoding']) { - echo ''; + echo ""; echo $port_adsl['adslLineCoding'].'/'.rewrite_adslLineType($port_adsl['adslLineType']); echo '
'; echo 'Sync:'.formatRates($port_adsl['adslAtucChanCurrTxRate']).'/'.formatRates($port_adsl['adslAturChanCurrTxRate']); echo '
'; echo 'Max:'.formatRates($port_adsl['adslAtucCurrAttainableRate']).'/'.formatRates($port_adsl['adslAturCurrAttainableRate']); - echo ''; + echo ""; echo 'Atten:'.$port_adsl['adslAtucCurrAtn'].'dB/'.$port_adsl['adslAturCurrAtn'].'dB'; echo '
'; echo 'SNR:'.$port_adsl['adslAtucCurrSnrMgn'].'dB/'.$port_adsl['adslAturCurrSnrMgn'].'dB'; } else { - echo ''; + echo ""; if ($port['ifType'] && $port['ifType'] != '') { echo ''.fixiftype($port['ifType']).''; } @@ -158,7 +167,7 @@ else { echo '-'; } - echo ''; + echo ""; if ($port['ifPhysAddress'] && $port['ifPhysAddress'] != '') { echo ''.formatMac($port['ifPhysAddress']).''; } @@ -176,13 +185,17 @@ else { }//end if echo ''; -echo ''; +echo ''; + +$neighborsCount=0; +$nbLinks=0; if (strpos($port['label'], 'oopback') === false && !$graph_type) { foreach (dbFetchRows('SELECT * FROM `links` AS L, `ports` AS I, `devices` AS D WHERE L.local_port_id = ? AND L.remote_port_id = I.port_id AND I.device_id = D.device_id', array($if_id)) as $link) { // echo("Directly Connected " . generate_port_link($link, makeshortif($link['label'])) . " on " . generate_device_link($link, shorthost($link['hostname'])) . "
"); // $br = "
"; $int_links[$link['port_id']] = $link['port_id']; $int_links_phys[$link['port_id']] = 1; + $nbLinks++; } unset($br); @@ -233,10 +246,23 @@ if (strpos($port['label'], 'oopback') === false && !$graph_type) { }//end foreach }//end if + if(count($int_links) > 3) + { + echo '
+ '; + } + + if ($port_details && $config['enable_port_relationship'] === true && port_permitted($int_link,$device['device_id'])) { foreach ($int_links as $int_link) { + $neighborsCount++; + if($neighborsCount == 4) + { + echo '
[...]
'; + echo '
'; + echo '
'; +} echo ''; // If we're showing graphs, generate the graph and print the img tags diff --git a/html/includes/print-map.inc.php b/html/includes/print-map.inc.php index eb41929fe..515fc68f4 100644 --- a/html/includes/print-map.inc.php +++ b/html/includes/print-map.inc.php @@ -132,10 +132,10 @@ foreach ($list as $items) { if (!in_array($items['local_device_id'],$tmp_ids)) { $tmp_devices[] = array('id'=>$items['local_device_id'],'label'=>$items['local_hostname'],'title'=>generate_device_link($local_device,'',array(),'','','',0),'shape'=>'box'); } + array_push($tmp_ids,$items['local_device_id']); if (!in_array($items['remote_device_id'],$tmp_ids)) { $tmp_devices[] = array('id'=>$items['remote_device_id'],'label'=>$items['remote_hostname'],'title'=>generate_device_link($remote_device,'',array(),'','','',0),'shape'=>'box'); } - array_push($tmp_ids,$items['local_device_id']); array_push($tmp_ids,$items['remote_device_id']); $speed = $items['local_ifspeed']/1000/1000; if ($speed == 100) { @@ -218,7 +218,7 @@ echo $edges; var network = new vis.Network(container, data, options); network.on('click', function (properties) { if (properties.nodes > 0) { - window.location.href = "/device/device="+properties.nodes+"/tab=map/" + window.location.href = "device/device="+properties.nodes+"/tab=map/" } }); diff --git a/html/includes/print-menubar.php b/html/includes/print-menubar.php index 09d4b57b7..424d273ab 100644 --- a/html/includes/print-menubar.php +++ b/html/includes/print-menubar.php @@ -47,7 +47,7 @@ else {
+ This may be required based on the service check.

diff --git a/html/includes/print-service-edit.inc.php b/html/includes/print-service-edit.inc.php index d0ad23a56..7b5c1bafb 100644 --- a/html/includes/print-service-edit.inc.php +++ b/html/includes/print-service-edit.inc.php @@ -26,6 +26,9 @@ if (isset($_POST['service']) && is_numeric($_POST['service'])) {
+
+ This may be required based on the service check. +
diff --git a/html/includes/print-service.inc.php b/html/includes/print-service.inc.php index e91535d79..ddf4ae977 100644 --- a/html/includes/print-service.inc.php +++ b/html/includes/print-service.inc.php @@ -24,6 +24,9 @@ else if ($service[service_status] == '2') { $message = trim($service['service_message']); $message = str_replace("\n", '
', $message); +$desc = trim($service['service_desc']); +$desc = str_replace("\n", '
', $desc); + $since = (time() - $service['service_changed']); $since = formatUptime($since); @@ -42,11 +45,11 @@ $popup .= "
"; + "; if ($device_id) { if (!$samehost) { - echo "".generate_device_link($device).''; + echo "".generate_device_link($device).''; } else { echo ''; @@ -54,16 +57,18 @@ if ($device_id) { } echo " - + $status - - + $since - + $message + + $desc + "; $i++; diff --git a/html/includes/print-vm.inc.php b/html/includes/print-vm.inc.php index e69730001..91b04b495 100644 --- a/html/includes/print-vm.inc.php +++ b/html/includes/print-vm.inc.php @@ -1,7 +1,5 @@ '; - echo ''; if (getidbyname($vm['vmwVmDisplayName'])) { @@ -12,7 +10,13 @@ else { } echo ''; -echo ''.$vm['vmwVmState'].''; + +if ($vm['vmwVmState'] == 'powered off') { + echo 'OFF'; +} +else { + echo 'ON'; +} if ($vm['vmwVmGuestOS'] == 'E: tools not installed') { echo 'Unknown (VMware Tools not installed)'; diff --git a/html/includes/table/arp-search.inc.php b/html/includes/table/arp-search.inc.php index 090476048..0e1484c76 100644 --- a/html/includes/table/arp-search.inc.php +++ b/html/includes/table/arp-search.inc.php @@ -12,20 +12,35 @@ if (is_admin() === false && is_read() === false) { $sql .= " WHERE M.port_id = P.port_id AND P.device_id = D.device_id $where "; -if (isset($_POST['searchby']) && $_POST['searchby'] == 'ip') { - $sql .= ' AND `ipv4_address` LIKE ?'; - $param[] = '%'.trim($_POST['address']).'%'; -} -else if (isset($_POST['searchby']) && $_POST['searchby'] == 'mac') { - $sql .= ' AND `mac_address` LIKE ?'; - $param[] = '%'.str_replace(array(':', ' ', '-', '.', '0x'), '', mres($_POST['address'])).'%'; -} - if (is_numeric($_POST['device_id'])) { $sql .= ' AND P.device_id = ?'; $param[] = $_POST['device_id']; } +if (is_numeric($_POST['port_id'])) { + $sql .= ' AND P.port_id = ?'; + $param[] = $_POST['port_id']; +} + +if (isset($_POST['searchPhrase']) && !empty($_POST['searchPhrase'])) { + $ip_search = '%'.mres(trim($_POST['searchPhrase'])).'%'; + $mac_search = '%'.str_replace(array(':', ' ', '-', '.', '0x'), '', mres($_POST['searchPhrase'])).'%'; + + if (isset($_POST['searchby']) && $_POST['searchby'] == 'ip') { + $sql .= ' AND `ipv4_address` LIKE ?'; + $param[] = $ip_search; + } + else if (isset($_POST['searchby']) && $_POST['searchby'] == 'mac') { + $sql .= ' AND `mac_address` LIKE ?'; + $param[] = $mac_search; + } + else { + $sql .= ' AND (`ipv4_address` LIKE ? OR `mac_address` LIKE ?)'; + $param[] = $ip_search; + $param[] = $mac_search; + } +} + $count_sql = "SELECT COUNT(`M`.`port_id`) $sql"; $total = dbFetchCell($count_sql, $param); diff --git a/html/includes/table/edit-ports.inc.php b/html/includes/table/edit-ports.inc.php index d4ccba8a5..625ac5e75 100644 --- a/html/includes/table/edit-ports.inc.php +++ b/html/includes/table/edit-ports.inc.php @@ -54,17 +54,22 @@ foreach (dbFetchRows($sql, $param) as $port) { $isportbad = ($port['ifOperStatus'] == 'down' && $port['ifAdminStatus'] != 'down') ? 1 : 0; $dowecare = ($port['ignore'] == 0 && $port['disabled'] == 0) ? $isportbad : !$isportbad; $outofsync = $dowecare ? " class='red'" : ''; + $checked = ''; + if (get_dev_attrib($device_id, 'ifName_tune:'.$port['ifName']) == "true") { + $checked = 'checked'; + } $response[] = array( - 'ifIndex' => $port['ifIndex'], - 'ifName' => $port['label'], - 'ifAdminStatus' => $port['ifAdminStatus'], - 'ifOperStatus' => ''.$port['ifOperStatus'].'', - 'disabled' => ' - ', - 'ignore' => ' - ', - 'ifAlias' => '
' + 'ifIndex' => $port['ifIndex'], + 'ifName' => $port['label'], + 'ifAdminStatus' => $port['ifAdminStatus'], + 'ifOperStatus' => ''.$port['ifOperStatus'].'', + 'disabled' => ' + ', + 'ignore' => ' + ', + 'port_tune' => '', + 'ifAlias' => '
', ); }//end foreach diff --git a/html/includes/table/eventlog.inc.php b/html/includes/table/eventlog.inc.php index 797b71d77..62edbbefd 100644 --- a/html/includes/table/eventlog.inc.php +++ b/html/includes/table/eventlog.inc.php @@ -29,7 +29,7 @@ if (isset($searchPhrase) && !empty($searchPhrase)) { $sql .= " AND (`D`.`hostname` LIKE '%$searchPhrase%' OR `E`.`datetime` LIKE '%$searchPhrase%' OR `E`.`message` LIKE '%$searchPhrase%' OR `E`.`type` LIKE '%$searchPhrase%')"; } -$count_sql = "SELECT COUNT(datetime) $sql"; +$count_sql = "SELECT COUNT(event_id) $sql"; $total = dbFetchCell($count_sql, $param); if (empty($total)) { $total = 0; diff --git a/html/includes/table/sensors.inc.php b/html/includes/table/sensors.inc.php new file mode 100644 index 000000000..62fd73b64 --- /dev/null +++ b/html/includes/table/sensors.inc.php @@ -0,0 +1,144 @@ += $sensor['sensor_limit']) { + $alert = 'alert'; + } + else { + $alert = ''; + } + } + + // FIXME - make this "four graphs in popup" a function/include and "small graph" a function. + // FIXME - So now we need to clean this up and move it into a function. Isn't it just "print-graphrow"? + // FIXME - DUPLICATED IN device/overview/sensors + $graph_colour = str_replace('#', '', $row_colour); + + $graph_array = array(); + $graph_array['height'] = '100'; + $graph_array['width'] = '210'; + $graph_array['to'] = $config['time']['now']; + $graph_array['id'] = $sensor['sensor_id']; + $graph_array['type'] = $graph_type; + $graph_array['from'] = $config['time']['day']; + $graph_array['legend'] = 'no'; + + $link_array = $graph_array; + $link_array['page'] = 'graphs'; + unset($link_array['height'], $link_array['width'], $link_array['legend']); + $link_graph = generate_url($link_array); + + $link = generate_url(array('page' => 'device', 'device' => $sensor['device_id'], 'tab' => 'health', 'metric' => $sensor['sensor_class'])); + + $overlib_content = '

'.$device['hostname'].' - '.$sensor['sensor_descr'].'

'; + foreach (array('day', 'week', 'month', 'year') as $period) { + $graph_array['from'] = $config['time'][$period]; + $overlib_content .= str_replace('"', "\'", generate_graph_tag($graph_array)); + } + + $overlib_content .= '
'; + + $graph_array['width'] = 80; + $graph_array['height'] = 20; + $graph_array['bg'] = 'ffffff00'; + // the 00 at the end makes the area transparent. + $graph_array['from'] = $config['time']['day']; + $sensor_minigraph = generate_lazy_graph_tag($graph_array); + + $sensor['sensor_descr'] = truncate($sensor['sensor_descr'], 48, ''); + + $response[] = array( + 'hostname' => generate_device_link($sensor), + 'sensor_descr' => overlib_link($link, $sensor['sensor_descr'], $overlib_content, null), + 'graph' => overlib_link($link_graph, $sensor_minigraph, $overlib_content, null), + 'alert' => $alert, + 'sensor_current' => $sensor['sensor_current'].$unit, + 'sensor_range' => round($sensor['sensor_limit_low'], 2).$unit.' - '.round($sensor['sensor_limit'], 2).$unit, + ); + + if ($_POST['view'] == 'graphs') { + + $daily_graph = 'graph.php?id='.$sensor['sensor_id'].'&type='.$graph_type.'&from='.$config['time']['day'].'&to='.$config['time']['now'].'&width=211&height=100'; + $daily_url = 'graph.php?id='.$sensor['sensor_id'].'&type='.$graph_type.'&from='.$config['time']['day'].'&to='.$config['time']['now'].'&width=400&height=150'; + + $weekly_graph = 'graph.php?id='.$sensor['sensor_id'].'&type='.$graph_type.'&from='.$config['time']['week'].'&to='.$config['time']['now'].'&width=211&height=100'; + $weekly_url = 'graph.php?id='.$sensor['sensor_id'].'&type='.$graph_type.'&from='.$config['time']['week'].'&to='.$config['time']['now'].'&width=400&height=150'; + + $monthly_graph = 'graph.php?id='.$sensor['sensor_id'].'&type='.$graph_type.'&from='.$config['time']['month'].'&to='.$config['time']['now'].'&width=211&height=100'; + $monthly_url = 'graph.php?id='.$sensor['sensor_id'].'&type='.$graph_type.'&from='.$config['time']['month'].'&to='.$config['time']['now'].'&width=400&height=150'; + + $yearly_graph = 'graph.php?id='.$sensor['sensor_id'].'&type='.$graph_type.'&from='.$config['time']['year'].'&to='.$config['time']['now'].'&width=211&height=100'; + $yearly_url = 'graph.php?id='.$sensor['sensor_id'].'&type='.$graph_type.'&from='.$config['time']['year'].'&to='.$config['time']['now'].'&width=400&height=150'; + + $response[] = array( + 'hostname' => "', LEFT);\" onmouseout=\"return nd();\"> + ", + 'sensor_descr' => "', LEFT);\" onmouseout=\"return nd();\"> + ", + 'graph' => "', LEFT);\" onmouseout=\"return nd();\"> + ", + 'alert' => '', + 'sensor_current' => "', LEFT);\" onmouseout=\"return nd();\"> + ", + 'sensor_range' => '', + ); + } //end if +}//end foreach + +$output = array( + 'current' => $current, + 'rowCount' => $rowCount, + 'rows' => $response, + 'total' => $count, +); +echo _json_encode($output); diff --git a/html/index.php b/html/index.php index 6499e2c27..2f068860f 100644 --- a/html/index.php +++ b/html/index.php @@ -12,11 +12,13 @@ * */ -if( strstr($_SERVER['SERVER_SOFTWARE'],"nginx") ) { - $_SERVER['PATH_INFO'] = str_replace($_SERVER['PATH_TRANSLATED'].$_SERVER['PHP_SELF'],"",$_SERVER['ORIG_SCRIPT_FILENAME']); -} -else { - $_SERVER['PATH_INFO'] = !empty($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : (!empty($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : ''); +if (empty($_SERVER['PATH_INFO'])) { + if( strstr($_SERVER['SERVER_SOFTWARE'],"nginx") ) { + $_SERVER['PATH_INFO'] = str_replace($_SERVER['PATH_TRANSLATED'].$_SERVER['PHP_SELF'],"",$_SERVER['ORIG_SCRIPT_FILENAME']); + } + else { + $_SERVER['PATH_INFO'] = !empty($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : ''; + } } function logErrors($errno, $errstr, $errfile, $errline) { @@ -163,8 +165,14 @@ else { + + "; +} + if ((isset($vars['bare']) && $vars['bare'] != "yes") || !isset($vars['bare'])) { if ($_SESSION['authenticated']) { require 'includes/print-menubar.php'; diff --git a/html/js/lazyload.js b/html/js/lazyload.js index 723d4e7e6..ec261f8ce 100644 --- a/html/js/lazyload.js +++ b/html/js/lazyload.js @@ -32,5 +32,5 @@ $(document).ready(function(){ function lazyload_done() { //Since RRD takes the width and height params for only the canvas, we must unset them //from the final (larger) image to prevent the browser from resizing them. - $(this).removeAttr('width').removeAttr('height').removeClass('lazy'); -} \ No newline at end of file + $(this).removeAttr('height').removeClass('lazy'); +} diff --git a/html/js/librenms.js b/html/js/librenms.js index 05e5fc471..b91090761 100644 --- a/html/js/librenms.js +++ b/html/js/librenms.js @@ -1,15 +1,47 @@ +function override_config(event, state, tmp_this) { + event.preventDefault(); + var $this = tmp_this; + var attrib = $this.data('attrib'); + var device_id = $this.data('device_id'); + $.ajax({ + type: 'POST', + url: 'ajax_form.php', + data: { type: 'override-config', device_id: device_id, attrib: attrib, state: state }, + dataType: 'json', + success: function(data) { + if (data.status == 'ok') { + toastr.success(data.message); + } + else { + toastr.error(data.message); + } + }, + error: function() { + toastr.error('Could not set this override'); + } + }); +} + +var oldH; +var oldW; $(document).ready(function() { // Device override ajax calls $("[name='override_config']").bootstrapSwitch('offColor','danger'); $('input[name="override_config"]').on('switchChange.bootstrapSwitch', function(event, state) { + override_config(event,state,$(this)); + }); + + // Device override for text inputs + $(document).on('blur', 'input[name="override_config_text"]', function(event) { event.preventDefault(); var $this = $(this); var attrib = $this.data('attrib'); var device_id = $this.data('device_id'); + var value = $this.val(); $.ajax({ type: 'POST', url: 'ajax_form.php', - data: { type: 'override-config', device_id: device_id, attrib: attrib, state: state }, + data: { type: 'override-config', device_id: device_id, attrib: attrib, state: value }, dataType: 'json', success: function(data) { if (data.status == 'ok') { @@ -96,11 +128,14 @@ $(document).ready(function() { } }); }); + + oldW=$(window).width(); + oldH=$(window).height(); }); function submitCustomRange(frmdata) { - var reto = /to=([0-9])+/g; - var refrom = /from=([0-9])+/g; + var reto = /to=([0-9a-zA-Z\-])+/g; + var refrom = /from=([0-9a-zA-Z\-])+/g; var tsto = moment(frmdata.dtpickerto.value).unix(); var tsfrom = moment(frmdata.dtpickerfrom.value).unix(); frmdata.selfaction.value = frmdata.selfaction.value.replace(reto, 'to=' + tsto); @@ -109,3 +144,82 @@ function submitCustomRange(frmdata) { return true; } +function updateResolution(refresh) +{ + $.post('ajax_setresolution.php', + { + width: $(window).width(), + height:$(window).height() + }, + function(data) { + if(refresh == true) { + location.reload(); + } + },'json' + ); +} + +var rtime; +var timeout = false; +var delta = 500; +var newH; +var newW; + +$(window).on('resize', function(){ + rtime = new Date(); + if (timeout === false) { + timeout = true; + setTimeout(resizeend, delta); + } +}); + +function resizeend() { + if (new Date() - rtime < delta) { + setTimeout(resizeend, delta); + } + else { + newH=$(window).height(); + newW=$(window).width(); + timeout = false; + if(Math.abs(oldW - newW) >= 200) + { + refresh = true; + } + else { + refresh = false; + resizeGraphs(); + } + updateResolution(refresh); + } +}; + +function resizeGraphs() { + ratioW=newW/oldW; + ratioH=newH/oldH; + + $('.graphs').each(function (){ + var img = jQuery(this); + img.attr('width',img.width() * ratioW); + }); + oldH=newH; + oldW=newW; +} + + +$(document).on("click", '.collapse-neighbors', function(event) +{ + var caller = $(this); + var button = caller.find('.neighbors-button'); + var list = caller.find('.neighbors-interface-list'); + var continued = caller.find('.neighbors-list-continued'); + + if(button.hasClass("glyphicon-plus")) { + button.addClass('glyphicon-minus').removeClass('glyphicon-plus'); + } + else { + button.addClass('glyphicon-plus').removeClass('glyphicon-minus'); + } + + list.toggle(); + continued.toggle(); +}); diff --git a/html/pages/addsrv.inc.php b/html/pages/addsrv.inc.php index 05a5c2eac..8fe145982 100644 --- a/html/pages/addsrv.inc.php +++ b/html/pages/addsrv.inc.php @@ -9,7 +9,7 @@ else { $updated = '1'; // FIXME should call add_service (needs more parameters) - $service_id = dbInsert(array('device_id' => $_POST['device'], 'service_ip' => $_POST['ip'], 'service_type' => $_POST['type'], 'service_desc' => $_POST['descr'], 'service_param' => $_POST['params'], 'service_ignore' => '0'), 'services'); + $service_id = dbInsert(array('device_id' => $_POST['device'], 'service_ip' => $_POST['ip'], 'service_type' => $_POST['type'], 'service_desc' => $_POST['descr'], 'service_param' => $_POST['params'], 'service_ignore' => '0', 'service_status' => '0', 'service_checked' => '0', 'service_changed' => '0', 'service_message' => 'New check', 'service_disabled' => '0'), 'services'); if ($service_id) { $message .= $message_break.'Service added ('.$service_id.')!'; @@ -18,10 +18,11 @@ else { } } - if ($handle = opendir($config['install_dir'].'/includes/services/')) { + if ($handle = opendir($config['nagios_plugins'])) { while (false !== ($file = readdir($handle))) { - if ($file != '.' && $file != '..' && !strstr($file, '.')) { - $servicesform .= ""; + if ($file != '.' && $file != '..' && !strstr($file, '.') && strstr($file, 'check_')) { + list(,$check_name) = explode('_',$file,2); + $servicesform .= ""; } } diff --git a/html/pages/bill.inc.php b/html/pages/bill.inc.php index 22855aacf..1be387354 100644 --- a/html/pages/bill.inc.php +++ b/html/pages/bill.inc.php @@ -188,7 +188,7 @@ if (bill_permitted($bill_id)) { $background = get_percentage_colours($percent); - echo '

'.print_percentage_bar(350, 20, $perc, null, 'ffffff', $background['left'], $percent.'%', 'ffffff', $background['right']).'

'; + echo '

'.print_percentage_bar(350, 20, $percent, null, 'ffffff', $background['left'], $percent.'%', 'ffffff', $background['right']).'

'; $type = '&ave=yes'; } diff --git a/html/pages/bill/delete.inc.php b/html/pages/bill/delete.inc.php index fc4ea7ccd..6a7d247b5 100644 --- a/html/pages/bill/delete.inc.php +++ b/html/pages/bill/delete.inc.php @@ -1,6 +1,4 @@ -
- -
- Delete Bill -
- -
-
+ +
+
- +
diff --git a/html/pages/bill/edit.inc.php b/html/pages/bill/edit.inc.php index 59d174504..3fd69c361 100644 --- a/html/pages/bill/edit.inc.php +++ b/html/pages/bill/edit.inc.php @@ -1,123 +1,123 @@ = 1) { - $quota = array( - 'type' => 'tb', - 'select_tb' => ' selected', - 'data' => $tmp['tb'], - ); - } - else if (($tmp['gb'] >= 1) and ($tmp['gb'] < $base)) { - $quota = array( - 'type' => 'gb', - 'select_gb' => ' selected', - 'data' => $tmp['gb'], - ); - } - else if (($tmp['mb'] >= 1) and ($tmp['mb'] < $base)) { - $quota = array( - 'type' => 'mb', - 'select_mb' => ' selected', - 'data' => $tmp['mb'], - ); - } -}//end if - -if ($bill_data['bill_type'] == 'cdr') { - $data = $bill_data['bill_cdr']; - $tmp['kbps'] = ($data / $base); - $tmp['mbps'] = ($data / $base / $base); - $tmp['gbps'] = ($data / $base / $base / $base); - if ($tmp['gbps'] >= 1) { - $cdr = array( - 'type' => 'gbps', - 'select_gbps' => ' selected', - 'data' => $tmp['gbps'], - ); - } - else if (($tmp['mbps'] >= 1) and ($tmp['mbps'] < $base)) { - $cdr = array( - 'type' => 'mbps', - 'select_mbps' => ' selected', - 'data' => $tmp['mbps'], - ); - } - else if (($tmp['kbps'] >= 1) and ($tmp['kbps'] < $base)) { - $cdr = array( - 'type' => 'kbps', - 'select_kbps' => ' selected', - 'data' => $tmp['kbps'], - ); - } -}//end if - -?> - + require 'includes/javascript-interfacepicker.inc.php'; + + // This needs more verification. Is it already added? Does it exist? + // Calculation to extract MB/GB/TB of Kbps/Mbps/Gbps + $base = $config['billing']['base']; + + if ($bill_data['bill_type'] == 'quota') { + $data = $bill_data['bill_quota']; + $tmp['mb'] = ($data / $base / $base); + $tmp['gb'] = ($data / $base / $base / $base); + $tmp['tb'] = ($data / $base / $base / $base / $base); + if ($tmp['tb'] >= 1) { + $quota = array( + 'type' => 'tb', + 'select_tb' => ' selected', + 'data' => $tmp['tb'], + ); + } + else if (($tmp['gb'] >= 1) and ($tmp['gb'] < $base)) { + $quota = array( + 'type' => 'gb', + 'select_gb' => ' selected', + 'data' => $tmp['gb'], + ); + } + else if (($tmp['mb'] >= 1) and ($tmp['mb'] < $base)) { + $quota = array( + 'type' => 'mb', + 'select_mb' => ' selected', + 'data' => $tmp['mb'], + ); + } + }//end if + + if ($bill_data['bill_type'] == 'cdr') { + $data = $bill_data['bill_cdr']; + $tmp['kbps'] = ($data / $base); + $tmp['mbps'] = ($data / $base / $base); + $tmp['gbps'] = ($data / $base / $base / $base); + if ($tmp['gbps'] >= 1) { + $cdr = array( + 'type' => 'gbps', + 'select_gbps' => ' selected', + 'data' => $tmp['gbps'], + ); + } + else if (($tmp['mbps'] >= 1) and ($tmp['mbps'] < $base)) { + $cdr = array( + 'type' => 'mbps', + 'select_mbps' => ' selected', + 'data' => $tmp['mbps'], + ); + } + else if (($tmp['kbps'] >= 1) and ($tmp['kbps'] < $base)) { + $cdr = array( + 'type' => 'kbps', + 'select_kbps' => ' selected', + 'data' => $tmp['kbps'], + ); + } + }//end if + + ?>
- +

Bill Properties

+
-
+
-
-
- -
+
+ +
-
+
+

Optional Information

+
-
+
-
+
-
+
- + - -

Billed Ports

-
-", $devicebtn); - $devicebtn = str_replace("
',;", "
',", $devicebtn); - $portbtn = str_replace('interface-upup', 'btn', generate_port_link($port)); - $portbtn = str_replace('interface-updown', 'btn btn-warning', $portbtn); - $portbtn = str_replace('interface-downdown', 'btn btn-warning', $portbtn); - $portbtn = str_replace('interface-admindown', 'btn btn-warning disabled', $portbtn); - $portbtn = str_replace("overlib('", "overlib('
", $portbtn); - $portbtn = str_replace("
',;", "
',", $portbtn); - $portalias = (empty($port['ifAlias']) ? '' : ' - '.$port['ifAlias'].''); - $devicebtn = str_replace('">'.$port['hostname'], '" style="color: #000;"> '.$port['hostname'], $devicebtn); - $portbtn = str_replace('">'.strtolower($port['ifName']), '" style="color: #000;"> '.$port['ifName'].''.$portalias, $portbtn); - echo '
\n"; - echo " \n"; - echo ' \n"; - echo "
\n"; - echo "
\n"; - echo "
\n"; - // echo(" \n"); - echo ' '.$devicebtn."\n"; - echo ' '.$portbtn."\n"; - echo "
\n"; - echo "
\n"; - echo ' Remove Interface\n"; - echo "
\n"; - echo "
\n"; - }//end foreach - - if (!$emptyCheck) { - echo "
\n"; - echo " There are no ports assigned to this bill\n"; - echo "
\n"; +
+

Billed Ports

+
+
+ ", $devicebtn); + $devicebtn = str_replace("
',;", "
',", $devicebtn); + $portbtn = str_replace('interface-upup', 'btn', generate_port_link($port)); + $portbtn = str_replace('interface-updown', 'btn btn-warning', $portbtn); + $portbtn = str_replace('interface-downdown', 'btn btn-warning', $portbtn); + $portbtn = str_replace('interface-admindown', 'btn btn-warning disabled', $portbtn); + $portbtn = str_replace("overlib('", "overlib('
", $portbtn); + $portbtn = str_replace("
',;", "
',", $portbtn); + $portalias = (empty($port['ifAlias']) ? '' : ' - '.$port['ifAlias'].''); + $devicebtn = str_replace('">'.$port['hostname'], '" style="color: #000;"> '.$port['hostname'], $devicebtn); + $portbtn = str_replace('">'.strtolower($port['ifName']), '" style="color: #000;"> '.$port['ifName'].''.$portalias, $portbtn); + echo '
\n"; + echo " \n"; + echo ' \n"; + echo "
\n"; + echo "
\n"; + echo "
\n"; + echo ' '.$devicebtn."\n"; + echo ' '.$portbtn."\n"; + echo "
\n"; + echo "
\n"; + echo ' Remove Interface\n"; + echo "
\n"; + echo "
\n"; + } + + if (!$emptyCheck) { + echo "
\n"; + echo " There are no ports assigned to this bill\n"; + echo "
\n"; + } } -}//end if -?> -
- + ?> + +
+

Add Port

+
-
+
-
-
-
+
-
-
- + diff --git a/html/pages/bill/history.inc.php b/html/pages/bill/history.inc.php index 26a4750b6..6770271c8 100644 --- a/html/pages/bill/history.inc.php +++ b/html/pages/bill/history.inc.php @@ -101,7 +101,7 @@ foreach (dbFetchRows('SELECT * FROM `bill_history` WHERE `bill_id` = ? ORDER BY $total_data $rate_95th $overuse - ".print_percentage_bar(250, 20, $perc, null, 'ffffff', $background['left'], $percent.'%', 'ffffff', $background['right']).' + ".print_percentage_bar(250, 20, $percent, null, 'ffffff', $background['left'], $percent.'%', 'ffffff', $background['right']).' Show details diff --git a/html/pages/bill/reset.inc.php b/html/pages/bill/reset.inc.php index 756f85bd2..728963abd 100644 --- a/html/pages/bill/reset.inc.php +++ b/html/pages/bill/reset.inc.php @@ -1,5 +1,4 @@
- -
- Reset Bill -
- -
-
-
-
-
+
+ +
+ +
+ \ No newline at end of file diff --git a/html/pages/bills.inc.php b/html/pages/bills.inc.php index f43c79301..f9fef2120 100644 --- a/html/pages/bills.inc.php +++ b/html/pages/bills.inc.php @@ -52,6 +52,18 @@ if ($_POST['addbill'] == 'yes') { 'bill_custid' => $_POST['bill_custid'], 'bill_ref' => $_POST['bill_ref'], 'bill_notes' => $_POST['bill_notes'], + 'rate_95th_in' => 0, + 'rate_95th_out' => 0, + 'rate_95th' => 0, + 'dir_95th' => 'in', + 'total_data' => 0, + 'total_data_in' => 0, + 'total_data_out' => 0, + 'rate_average' => 0, + 'rate_average_in' => 0, + 'rate_average_out' => 0, + 'bill_last_calc' => array('NOW()'), + 'bill_autoadded' => 0, ); $bill_id = dbInsert($insert, 'bills'); @@ -64,7 +76,7 @@ if ($_POST['addbill'] == 'yes') { $message .= $message_break.'Port '.mres($_POST['port']).' added!'; $message_break .= '
'; } -}//end if +} $pagetitle[] = 'Billing'; @@ -118,10 +130,10 @@ else if ($vars['view'] == 'add') { $devicebtn = str_replace('list-device', 'btn', generate_device_link($port)); $portbtn = str_replace('interface-upup', 'btn', generate_port_link($port)); $portalias = (empty($port['ifAlias']) ? '' : ' - '.$port['ifAlias'].''); - $devicebtn = str_replace('">'.$port['hostname'], '" style="color: #000;"> '.$port['hostname'], $devicebtn); + $devicebtn = str_replace('">'.$port['hostname'], '" style="color: #000;"> '.$port['hostname'], $devicebtn); $devicebtn = str_replace("overlib('", "overlib('
", $devicebtn); $devicebtn = str_replace("
',;", "
',", $devicebtn); - $portbtn = str_replace('">'.strtolower($port['ifName']), '" style="color: #000;"> '.$port['ifName'].''.$portalias, $portbtn); + $portbtn = str_replace('">'.strtolower($port['ifName']), '" style="color: #000;"> '.$port['ifName'].''.$portalias, $portbtn); $portbtn = str_replace("overlib('", "overlib('
", $portbtn); $portbtn = str_replace("
',;", "
',", $portbtn); echo "
\n"; @@ -136,7 +148,7 @@ else if ($vars['view'] == 'add') { echo "
\n"; echo "
\n"; echo " \n"; - }//end if + } ?>
@@ -228,7 +240,7 @@ else if ($vars['view'] == 'add') {
- + '; -}//end if - -// echo(""); +} diff --git a/html/pages/bills/pmonth.inc.php b/html/pages/bills/pmonth.inc.php index abac72f00..39f1ff75c 100644 --- a/html/pages/bills/pmonth.inc.php +++ b/html/pages/bills/pmonth.inc.php @@ -60,7 +60,7 @@ foreach (dbFetchRows('SELECT * FROM `bills` ORDER BY `bill_name`') as $bill) { $total_data $rate_95th $overuse - ".print_percentage_bar(250, 20, $perc, null, 'ffffff', $background['left'], $percent.'%', 'ffffff', $background['right']).' + ".print_percentage_bar(250, 20, $percent, null, 'ffffff', $background['left'], $percent.'%', 'ffffff', $background['right']).' '; $i++; diff --git a/html/pages/deleted-ports.inc.php b/html/pages/deleted-ports.inc.php index 8f2895281..6f59e7b95 100644 --- a/html/pages/deleted-ports.inc.php +++ b/html/pages/deleted-ports.inc.php @@ -19,8 +19,8 @@ else if ($vars['purge']) { echo '
Deleted '.generate_device_link($interface).' - '.generate_port_link($interface).'
'; } -echo ''; -echo ""; +echo '
Purge All
'; +echo ""; foreach (dbFetchRows("SELECT * FROM `ports` AS P, `devices` as D WHERE P.`deleted` = '1' AND D.device_id = P.device_id",array(),true) as $interface) { $interface = ifLabel($interface, $interface); @@ -29,7 +29,7 @@ foreach (dbFetchRows("SELECT * FROM `ports` AS P, `devices` as D WHERE P.`delete echo ''; echo ''; echo ''; - echo ""; + echo ""; } } diff --git a/html/pages/device.inc.php b/html/pages/device.inc.php index 688a18900..1a68f9dbf 100644 --- a/html/pages/device.inc.php +++ b/html/pages/device.inc.php @@ -33,7 +33,7 @@ if (device_permitted($vars['device']) || $check_device == $vars['device']) { } echo '
'; - echo '
DevicePort Purge All
'.generate_device_link($interface).''.generate_port_link($interface).' Purge Purge
'; + echo '
'; require 'includes/device-header.inc.php'; echo '
'; echo ''; diff --git a/html/pages/device/apps/ceph.inc.php b/html/pages/device/apps/ceph.inc.php new file mode 100644 index 000000000..988d64803 --- /dev/null +++ b/html/pages/device/apps/ceph.inc.php @@ -0,0 +1,88 @@ + 'Pool stats', + 'ceph_osdperf' => 'OSD Performance', + 'ceph_df' => 'Usage', +); + +$rrddir = $config['rrd_dir'].'/'.$device['hostname']; + +foreach ($graphs as $key => $text) { + echo '

'.$text.'

'; + $graph_array['height'] = '100'; + $graph_array['width'] = '215'; + $graph_array['to'] = $config['time']['now']; + $graph_array['id'] = $app['app_id']; + + if ($key == "ceph_poolstats") { + foreach (glob($rrddir."/app-ceph-".$app['app_id']."-pool-*") as $rrd_filename) { + if (preg_match("/.*-pool-(.+)\.rrd$/", $rrd_filename, $pools)) { + $pool = $pools[1]; + echo '

'.$pool.' Reads/Writes

'; + $graph_array['type'] = 'application_ceph_pool_io'; + $graph_array['pool'] = $pool; + + echo ""; + include 'includes/print-graphrow.inc.php'; + echo ''; + + echo '

'.$pool.' IOPS

'; + $graph_array['type'] = 'application_ceph_pool_iops'; + $graph_array['pool'] = $pool; + + echo ""; + include 'includes/print-graphrow.inc.php'; + echo ''; + } + } + } + elseif ($key == "ceph_osdperf") { + foreach (glob($rrddir."/app-ceph-".$app['app_id']."-osd-*") as $rrd_filename) { + if (preg_match("/.*-osd-(.+)\.rrd$/", $rrd_filename, $osds)) { + $osd = $osds[1]; + echo '

'.$osd.' Latency

'; + $graph_array['type'] = 'application_ceph_osd_performance'; + $graph_array['osd'] = $osd; + + echo ""; + include 'includes/print-graphrow.inc.php'; + echo ''; + } + } + } + elseif ($key == "ceph_df") { + foreach (glob($rrddir."/app-ceph-".$app['app_id']."-df-*") as $rrd_filename) { + if (preg_match("/.*-df-(.+)\.rrd$/", $rrd_filename, $pools)) { + $pool = $pools[1]; + if ($pool == "c") { + echo '

Cluster Usage

'; + $graph_array['type'] = 'application_ceph_pool_df'; + $graph_array['pool'] = $pool; + + echo ""; + include 'includes/print-graphrow.inc.php'; + echo ''; + } + else { + echo '

'.$pool.' Usage

'; + $graph_array['type'] = 'application_ceph_pool_df'; + $graph_array['pool'] = $pool; + + echo ""; + include 'includes/print-graphrow.inc.php'; + echo ''; + + echo '

'.$pool.' Objects

'; + $graph_array['type'] = 'application_ceph_pool_objects'; + $graph_array['pool'] = $pool; + + echo ""; + include 'includes/print-graphrow.inc.php'; + echo ''; + } + } + } + } + +} diff --git a/html/pages/device/edit/apps.inc.php b/html/pages/device/edit/apps.inc.php index c885666df..fc5e50eea 100644 --- a/html/pages/device/edit/apps.inc.php +++ b/html/pages/device/edit/apps.inc.php @@ -36,7 +36,7 @@ if ($_POST['device']) { foreach ($enabled as $app) { if (!in_array($app, $app_in_db)) { - $updated += dbInsert(array('device_id' => $device['device_id'], 'app_type' => $app), 'applications'); + $updated += dbInsert(array('device_id' => $device['device_id'], 'app_type' => $app, 'app_status' => '', 'app_instance' => ''), 'applications'); } } @@ -99,4 +99,4 @@ echo '
'; echo ''; echo '
'; -echo ''; \ No newline at end of file +echo ''; diff --git a/html/pages/device/edit/misc.inc.php b/html/pages/device/edit/misc.inc.php index a85689852..b46932a15 100644 --- a/html/pages/device/edit/misc.inc.php +++ b/html/pages/device/edit/misc.inc.php @@ -3,17 +3,29 @@ echo '
- -
+ +
'.dynamic_override_config('checkbox','override_icmp_disable', $device).'
- -
+ +
'.dynamic_override_config('checkbox','override_Oxidized_disable', $device).'
+
+ +
+ '.dynamic_override_config('text','override_Unixagent_port', $device).' +
+
+
+ +
+ '.dynamic_override_config('checkbox','override_rrdtool_tune', $device).' +
+
'; diff --git a/html/pages/device/edit/ports.inc.php b/html/pages/device/edit/ports.inc.php index 37cccb9d2..2e14cbb46 100644 --- a/html/pages/device/edit/ports.inc.php +++ b/html/pages/device/edit/ports.inc.php @@ -5,7 +5,7 @@ '> -
+
@@ -15,6 +15,7 @@ + @@ -23,6 +24,7 @@ diff --git a/html/pages/device/overview/processors.inc.php b/html/pages/device/overview/processors.inc.php index 4f631567a..3aae5f5f8 100644 --- a/html/pages/device/overview/processors.inc.php +++ b/html/pages/device/overview/processors.inc.php @@ -1,7 +1,5 @@
Oper Disable IgnoreRRD Tune Description
'; + $graph_array = array(); + $graph_array['to'] = $config['time']['now']; + $graph_array['type'] = 'processor_usage'; + $graph_array['from'] = $config['time']['day']; + $graph_array['legend'] = 'no'; + + $totalPercent=0; + foreach ($processors as $proc) { $text_descr = rewrite_entity_descr($proc['processor_descr']); - // disable short hrDeviceDescr. need to make this prettier. - // $text_descr = short_hrDeviceDescr($proc['processor_descr']); $percent = $proc['processor_usage']; - $background = get_percentage_colours($percent); - $graph_colour = str_replace('#', '', $row_colour); + if ($config['cpu_details_overview'] === true) + { - $graph_array = array(); + $background = get_percentage_colours($percent); + + $graph_array['id'] = $proc['processor_id']; + + //Generate tooltip graphs + $graph_array['height'] = '100'; + $graph_array['width'] = '210'; + $link_array = $graph_array; + $link_array['page'] = 'graphs'; + unset($link_array['height'], $link_array['width'], $link_array['legend']); + $link = generate_url($link_array); + $overlib_content = generate_overlib_content($graph_array, $device['hostname'].' - '.$text_descr); + + //Generate the minigraph + $graph_array['width'] = 80; + $graph_array['height'] = 20; + $graph_array['bg'] = 'ffffff00'; // the 00 at the end makes the area transparent. + $minigraph = generate_lazy_graph_tag($graph_array); + + echo ' + + + + '; + } + else { + $totalPercent = $totalPercent + $percent; + } + + }//end foreach + + if ($config['cpu_details_overview'] === false) + { + + //Generate average cpu graph $graph_array['height'] = '100'; - $graph_array['width'] = '210'; - $graph_array['to'] = $config['time']['now']; - $graph_array['id'] = $proc['processor_id']; - $graph_array['type'] = $graph_type; - $graph_array['from'] = $config['time']['day']; - $graph_array['legend'] = 'no'; + $graph_array['width'] = '485'; + $graph_array['device'] = $device['device_id']; + $graph_array['type'] = 'device_processor'; + $graph = generate_lazy_graph_tag($graph_array); + //Generate link to graphs $link_array = $graph_array; $link_array['page'] = 'graphs'; - unset($link_array['height'], $link_array['width'], $link_array['legend']); + unset($link_array['height'], $link_array['width']); $link = generate_url($link_array); - $overlib_content = generate_overlib_content($graph_array, $device['hostname'].' - '.$text_descr); - - $graph_array['width'] = 80; - $graph_array['height'] = 20; - $graph_array['bg'] = 'ffffff00'; - // the 00 at the end makes the area transparent. - $minigraph = generate_lazy_graph_tag($graph_array); + //Generate tooltip + $graph_array['width'] = '210'; + $overlib_content = generate_overlib_content($graph_array, $device['hostname'].' - CPU usage'); echo ' - - - - '; - }//end foreach + + '; + + //Add a row with CPU desc, count and percent graph + $totalPercent=$totalPercent/count($processors); + $background = get_percentage_colours($totalPercent); + + echo ' + + + + '; + + } echo '
'.overlib_link($link, $text_descr, $overlib_content).''.overlib_link($link, $minigraph, $overlib_content).''.overlib_link($link, print_percentage_bar(200, 20, $percent, null, 'ffffff', $background['left'], $percent.'%', 'ffffff', $background['right']), $overlib_content).' +
'.overlib_link($link, $text_descr, $overlib_content).''.overlib_link($link, $minigraph, $overlib_content).''.overlib_link($link, print_percentage_bar(200, 20, $percent, null, 'ffffff', $background['left'], $percent.'%', 'ffffff', $background['right']), $overlib_content).' -
'; + echo overlib_link($link, $graph, $overlib_content, null); + echo '
'.overlib_link($link, $text_descr, $overlib_content).''.overlib_link($link,'x'.count($processors),$overlib_content).''.overlib_link($link, print_percentage_bar(200, 20, $totalPercent, null, 'ffffff', $background['left'], $percent.'%', 'ffffff', $background['right']), $overlib_content).'
diff --git a/html/pages/device/port/arp.inc.php b/html/pages/device/port/arp.inc.php index 821787543..21dd2551e 100644 --- a/html/pages/device/port/arp.inc.php +++ b/html/pages/device/port/arp.inc.php @@ -1,48 +1,29 @@ + + + + + + + + + +
MAC addressIPv4 addressRemote deviceRemote interface
-echo ''; -$i = '1'; + - $arp_host = dbFetchRow('SELECT * FROM ipv4_addresses AS A, ports AS I, devices AS D WHERE A.ipv4_address = ? AND I.port_id = A.port_id AND D.device_id = I.device_id', array($arp['ipv4_address'])); - - if ($arp_host) { - $arp_name = generate_device_link($arp_host); - } - else { - unset($arp_name); - } - - if ($arp_host) { - $arp_if = generate_port_link($arp_host); - } - else { - unset($arp_if); - } - - if ($arp_host['device_id'] == $device['device_id']) { - $arp_name = 'Localhost'; - } - - if ($arp_host['port_id'] == $arp['port_id']) { - $arp_if = 'Local Port'; - } - - echo ' - - - - - - '; - $i++; -}//end foreach - -echo '
'.formatmac($arp['mac_address']).''.$arp['ipv4_address'].''.$arp_name.''.$arp_if.'
'; diff --git a/html/pages/device/ports.inc.php b/html/pages/device/ports.inc.php index 56d3ee542..c03812029 100644 --- a/html/pages/device/ports.inc.php +++ b/html/pages/device/ports.inc.php @@ -103,9 +103,11 @@ if ($vars['view'] == 'minigraphs') { echo "
".makeshortif($port['ifDescr']).'
".$device['hostname'].' - '.$port['ifDescr'].'
\ +
\ +
".$device['hostname'].' - '.$port['ifDescr'].'
\ '.$port['ifAlias']." \ \ +
\ ', CENTER, LEFT, FGCOLOR, '#e5e5e5', BGCOLOR, '#e5e5e5', WIDTH, 400, HEIGHT, 150);\" onmouseout=\"return nd();\" >"."
".truncate(short_port_descr($port['ifAlias']), 32, '').'
@@ -121,8 +123,19 @@ else { if ($vars['view'] == 'details') { $port_details = 1; } +?> +
+ + + + + + + + + +
">Port">TrafficSpeedMediaMac Address
"; $i = '1'; global $port_cache, $port_index_cache; @@ -130,9 +143,20 @@ else { $ports = dbFetchRows("SELECT * FROM `ports` WHERE `device_id` = ? AND `deleted` = '0' ORDER BY `ifIndex` ASC", array($device['device_id'])); // As we've dragged the whole database, lets pre-populate our caches :) // FIXME - we should probably split the fetching of link/stack/etc into functions and cache them here too to cut down on single row queries. - foreach ($ports as $port) { + + foreach ($ports as $key => $port) { $port_cache[$port['port_id']] = $port; $port_index_cache[$port['device_id']][$port['ifIndex']] = $port; + $ports[$key]["ifOctets_rate"] = $port["ifInOctets_rate"] + $port["ifOutOctets_rate"]; + } + + switch ($vars["sort"]) { + case 'traffic': + $ports = array_sort($ports, 'ifOctets_rate', SORT_DESC); + break; + default: + $ports = array_sort($ports, 'ifIndex', SORT_ASC); + break; } foreach ($ports as $port) { diff --git a/html/pages/device/ports/arp.inc.php b/html/pages/device/ports/arp.inc.php index 6ac7e39a5..5c804464d 100644 --- a/html/pages/device/ports/arp.inc.php +++ b/html/pages/device/ports/arp.inc.php @@ -1,51 +1,30 @@ +
+ + + + + + + + + +
PortMAC addressIPv4 addressRemote deviceRemote interface
-echo ''; -echo ''; + -foreach (dbFetchRows('SELECT * FROM ipv4_mac AS M, ports AS I WHERE I.port_id = M.port_id AND I.device_id = ?', array($device['device_id'])) as $arp) { - if (!is_integer($i / 2)) { - $bg_colour = $list_colour_a; - } - else { - $bg_colour = $list_colour_b; - } - - $arp_host = dbFetchRow('SELECT * FROM ipv4_addresses AS A, ports AS I, devices AS D WHERE A.ipv4_address = ? AND I.port_id = A.port_id AND D.device_id = I.device_id', array($arp['ipv4_address'])); - - if ($arp_host) { - $arp_name = generate_device_link($arp_host); - } - else { - unset($arp_name); - } - - if ($arp_host) { - $arp_if = generate_port_link($arp_host); - } - else { - unset($arp_if); - } - - if ($arp_host['device_id'] == $device['device_id']) { - $arp_name = 'Localhost'; - } - - if ($arp_host['port_id'] == $arp['port_id']) { - $arp_if = 'Local Port'; - } - - echo " - - - - - - - "; - $i++; -}//end foreach - -echo '
PortMAC addressIPv4 addressRemote deviceRemote port
".generate_port_link(array_merge($arp, $device)).''.formatmac($arp['mac_address']).''.$arp['ipv4_address']."$arp_name$arp_if
'; diff --git a/html/pages/device/showconfig.inc.php b/html/pages/device/showconfig.inc.php index ac5672d82..675e43674 100644 --- a/html/pages/device/showconfig.inc.php +++ b/html/pages/device/showconfig.inc.php @@ -98,13 +98,13 @@ if ($_SESSION['userlevel'] >= '7') { list($oid,$date,$version) = explode('|',mres($_POST['config'])); $text = file_get_contents($config['oxidized']['url'].'/node/version/view?node='.$device['hostname'].'&group=&oid='.$oid.'&date='.urlencode($date).'&num='.$version.'&format=text'); if ($text == 'node not found') { - $text = file_get_contents($config['oxidized']['url'].'/node/version/view?node='.$device['hostname'].'&group='.$device['os'].'&oid='.$oid.'&date='.urlencode($date).'&num='.$version.'&format=text'); + $text = file_get_contents($config['oxidized']['url'].'/node/version/view?node='.$device['hostname'].'&group='.(is_array($node_info) ? $node_info['group'] : $device['os']).'&oid='.$oid.'&date='.urlencode($date).'&num='.$version.'&format=text'); } } else { $text = file_get_contents($config['oxidized']['url'].'/node/fetch/'.$device['hostname']); if ($text == 'node not found') { - $text = file_get_contents($config['oxidized']['url'].'/node/fetch/'.$device['os'].'/'.$device['hostname']); + $text = file_get_contents($config['oxidized']['url'].'/node/fetch/'.(is_array($node_info) ? $node_info['group'] : $device['os']).'/'.$device['hostname']); } } if ($config['oxidized']['features']['versioning'] === true) { diff --git a/html/pages/device/vm.inc.php b/html/pages/device/vm.inc.php index 5dee674a5..699fb92f3 100644 --- a/html/pages/device/vm.inc.php +++ b/html/pages/device/vm.inc.php @@ -1,15 +1,11 @@ Server NamePower StatusOperating SystemMemoryCPU'; - +echo ''; $i = '1'; -foreach (dbFetchRows('SELECT * FROM vminfo WHERE device_id = ? ORDER BY vmwVmDisplayName', array($device['device_id'])) as $vm) { +foreach (dbFetchRows('SELECT `vmwVmDisplayName`,`vmwVmState`,`vmwVmGuestOS`,`vmwVmMemSize`,`vmwVmCpus` FROM `vminfo` WHERE `device_id` = ? ORDER BY `vmwVmDisplayName`', array($device['device_id'])) as $vm) { include 'includes/print-vm.inc.php'; - $i++; } echo '
Server NamePower StatusOperating SystemMemoryCPU
'; - $pagetitle[] = 'Virtual Machines'; diff --git a/html/pages/devices.inc.php b/html/pages/devices.inc.php index 2e9c53815..6d446d5c1 100644 --- a/html/pages/devices.inc.php +++ b/html/pages/devices.inc.php @@ -51,7 +51,7 @@ foreach ($menu_options as $option => $text) { if ($vars['format'] == 'graph_'.$option) { echo(""); } - echo('' . $text . ''); + echo('' . $text . ''); if ($vars['format'] == 'graph_'.$option) { echo(""); } @@ -62,6 +62,21 @@ foreach ($menu_options as $option => $text) {
+ + - Status + Status Vendor Device diff --git a/html/pages/edituser.inc.php b/html/pages/edituser.inc.php index 036d66637..c07c48037 100644 --- a/html/pages/edituser.inc.php +++ b/html/pages/edituser.inc.php @@ -36,7 +36,7 @@ else { if ($vars['action'] == 'addifperm') { if (!dbFetchCell('SELECT COUNT(*) FROM ports_perms WHERE `port_id` = ? AND `user_id` = ?', array($vars['port_id'], $vars['user_id']))) { - dbInsert(array('port_id' => $vars['port_id'], 'user_id' => $vars['user_id']), 'ports_perms'); + dbInsert(array('port_id' => $vars['port_id'], 'user_id' => $vars['user_id'], 'access_level' => 0), 'ports_perms'); } } @@ -312,6 +312,10 @@ else { } } + if (!empty($vars['dashboard'])) { + dbUpdate(array('dashboard'=>$vars['dashboard']),'users','user_id = ?',array($vars['user_id'])); + } + echo "
@@ -374,6 +378,18 @@ if (passwordscanchange($users_details['username'])) {
"; } + echo " +
+ +
+
+
+ "; echo "
diff --git a/html/pages/front/default.php b/html/pages/front/default.php index 341f8f12e..1709f842a 100644 --- a/html/pages/front/default.php +++ b/html/pages/front/default.php @@ -33,7 +33,7 @@ echo '
'; $count_boxes = 0; // Device down boxes -if ($_SESSION['userlevel'] >= '10') { +if (is_admin() === true || is_read() === true) { $sql = "SELECT * FROM `devices` WHERE `status` = '0' AND `ignore` = '0' LIMIT ".$config['front_page_down_box_limit']; } else { @@ -50,7 +50,7 @@ foreach (dbFetchRows($sql) as $device) { ++$count_boxes; } -if ($_SESSION['userlevel'] >= '10') { +if (is_admin() === true || is_read() === true) { $sql = "SELECT * FROM `ports` AS I, `devices` AS D WHERE I.device_id = D.device_id AND ifOperStatus = 'down' AND ifAdminStatus = 'up' AND D.ignore = '0' AND I.ignore = '0' AND `D`.`status` = '1' LIMIT ".$config['front_page_down_box_limit']; } else { @@ -79,7 +79,7 @@ if ($config['warn']['ifdown']) { /* FIXME service permissions? seem nonexisting now.. */ // Service down boxes -if ($_SESSION['userlevel'] >= '10') { +if (is_admin() === true || is_read() === true) { $sql = "SELECT * FROM `services` AS S, `devices` AS D WHERE S.device_id = D.device_id AND service_status = 'down' AND D.ignore = '0' AND S.service_ignore = '0' AND `D`.`status` = '1' LIMIT ".$config['front_page_down_box_limit']; $param[] = ''; } @@ -101,7 +101,7 @@ foreach (dbFetchRows($sql, $param) as $service) { // BGP neighbour down boxes if (isset($config['enable_bgp']) && $config['enable_bgp']) { - if ($_SESSION['userlevel'] >= '10') { + if (is_admin() === true || is_read() === true) { $sql = "SELECT * FROM `devices` AS D, bgpPeers AS B WHERE bgpPeerAdminStatus != 'start' AND bgpPeerState != 'established' AND bgpPeerState != '' AND B.device_id = D.device_id AND D.ignore = 0 AND `D`.`status` = '1' LIMIT ".$config['front_page_down_box_limit']; } else { @@ -122,7 +122,7 @@ if (isset($config['enable_bgp']) && $config['enable_bgp']) { // Device rebooted boxes if (filter_var($config['uptime_warning'], FILTER_VALIDATE_FLOAT) !== false && $config['uptime_warning'] > 0) { - if ($_SESSION['userlevel'] >= '10') { + if (is_admin() === true || is_read() === true) { $sql = "SELECT * FROM `devices` AS D WHERE D.status = '1' AND D.uptime > 0 AND D.uptime < '".$config['uptime_warning']."' AND D.ignore = 0 LIMIT ".$config['front_page_down_box_limit']; } else { @@ -204,7 +204,7 @@ if ($config['enable_syslog']) { echo '
'; } else { - if ($_SESSION['userlevel'] >= '10') { + if (is_admin() === true || is_read() === true) { $query = "SELECT *,DATE_FORMAT(datetime, '".$config['dateformat']['mysql']['compact']."') as humandate FROM `eventlog` ORDER BY `datetime` DESC LIMIT 0,15"; $alertquery = 'SELECT devices.device_id,name,state,time_logged FROM alert_log LEFT JOIN devices ON alert_log.device_id=devices.device_id LEFT JOIN alert_rules ON alert_log.rule_id=alert_rules.id ORDER BY `time_logged` DESC LIMIT 0,15'; } diff --git a/html/pages/front/tiles.php b/html/pages/front/tiles.php index d8b082522..67b1b8f59 100644 --- a/html/pages/front/tiles.php +++ b/html/pages/front/tiles.php @@ -16,8 +16,13 @@ * Code for Gridster.sort_by_row_and_col_asc(serialization) call is from http://gridster.net/demos/grid-from-serialize.html */ -$no_refresh = true; -if (dbFetchCell('SELECT dashboard_id FROM dashboards WHERE user_id=?',array($_SESSION['user_id'])) == 0) { +$no_refresh = true; +$default_dash = 0; +if (($tmp = dbFetchCell('SELECT dashboard FROM users WHERE user_id=?',array($_SESSION['user_id']))) != 0) { + $default_dash = $tmp; +} +else if (dbFetchCell('SELECT dashboard_id FROM dashboards WHERE user_id=?',array($_SESSION['user_id'])) == 0) { + $tmp = dbInsert(array('dashboard_name'=>'Default','user_id'=>$_SESSION['user_id']),'dashboards'); $vars['dashboard'] = dbInsert(array('dashboard_name'=>'Default','user_id'=>$_SESSION['user_id']),'dashboards'); if (dbFetchCell('select 1 from users_widgets where user_id = ? && dashboard_id = ?',array($_SESSION['user_id'],0)) == 1) { dbUpdate(array('dashboard_id'=>$vars['dashboard']),'users_widgets','user_id = ? && dashboard_id = ?',array($_SESSION['user_id'],0)); @@ -31,7 +36,12 @@ if (!empty($vars['dashboard'])) { } } if (empty($vars['dashboard'])) { - $vars['dashboard'] = dbFetchRow('select * from dashboards where user_id = ? order by dashboard_id limit 1',array($_SESSION['user_id'])); + if ($default_dash != 0) { + $vars['dashboard'] = dbFetchRow('select * from dashboards where dashboard_id = ?',array($default_dash)); + } + else { + $vars['dashboard'] = dbFetchRow('select * from dashboards where user_id = ? order by dashboard_id limit 1',array($_SESSION['user_id'])); + } if (isset($orig)) { $msg_box[] = array('type' => 'error', 'message' => 'Dashboard #'.$orig.' does not exist! Loaded '.$vars['dashboard']['dashboard_name'].' instead.','title' => 'Requested Dashboard Not Found!'); } @@ -46,8 +56,9 @@ if (empty($data)) { $data = serialize(json_encode($data)); $dash_config = unserialize(stripslashes($data)); $dashboards = dbFetchRows("SELECT * FROM `dashboards` WHERE `user_id` = ? && `dashboard_id` != ? ORDER BY `dashboard_name`",array($_SESSION['user_id'],$vars['dashboard']['dashboard_id'])); -?> +if (empty($vars['bare']) || $vars['bare'] == "no") { +?>
@@ -187,19 +198,16 @@ foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widg

+ -
-
-
-
diff --git a/html/pages/notifications.inc.php b/html/pages/notifications.inc.php new file mode 100644 index 000000000..602338d91 --- /dev/null +++ b/html/pages/notifications.inc.php @@ -0,0 +1,240 @@ + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +/** + * Notification Page + * @author Daniel Preussker + * @copyright 2015 Daniel Preussker, QuxLabs UG + * @license GPL + * @package LibreNMS + * @subpackage Notifications + */ + +$notifications = new ObjCache('notifications'); +?> +
+
+
+

Notifications

+

Unread Notifications New' : ''); ?>

+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+

    Sticky by '.dbFetchCell('select username from users where user_id = ?',array($notif['user_id'])).'' : ''); ?>

+
+
+
+
+
+

+
Source:
+
+
+
+
+ + +
+ + +
+
+
+

+' : ''); ?> +  + + +

+
+
+
+
+
+

', $notif['body']); ?>

+
Source:
+
+
+
+
+ +
+ +
+
+ +
+
+
+

Archive

+
+
+ +
+
+
+

' : ''); ?> +

+
+
+
+
+

', $notif['body']); ?>

+
Source:
+
+
+
+
+ +
+ + diff --git a/html/pages/ports.inc.php b/html/pages/ports.inc.php index 9a310ea27..1e429b76b 100644 --- a/html/pages/ports.inc.php +++ b/html/pages/ports.inc.php @@ -338,17 +338,17 @@ foreach ($vars as $var => $value) { break; case 'state': if ($value == "down") { - $where .= "AND I.ifAdminStatus = ? AND I.ifOperStatus = ?"; + $where .= " AND I.ifAdminStatus = ? AND I.ifOperStatus = ?"; $param[] = "up"; $param[] = "down"; } elseif($value == "up") { - $where .= "AND I.ifAdminStatus = ? AND I.ifOperStatus = ? AND I.ignore = '0' AND D.ignore='0' AND I.deleted='0'"; + $where .= " AND I.ifAdminStatus = ? AND I.ifOperStatus = ?"; $param[] = "up"; $param[] = "up"; } elseif($value == "admindown") { - $where .= "AND I.ifAdminStatus = ? AND D.ignore = 0"; + $where .= " AND I.ifAdminStatus = ? AND D.ignore = 0"; $param[] = "down"; } break; diff --git a/html/pages/ripenccapi.inc.php b/html/pages/ripenccapi.inc.php new file mode 100644 index 000000000..fbcfbd864 --- /dev/null +++ b/html/pages/ripenccapi.inc.php @@ -0,0 +1,66 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ +$pagetitle[] = 'RIPE NCC - API Tools'; +?> +

RIPE NCC API Tools

+
+
+
+ +
+
+ +
+
+
+ + + + +
+
+
+ +
+ diff --git a/html/pages/routing/bgp.inc.php b/html/pages/routing/bgp.inc.php index 3268715ec..d70555c03 100644 --- a/html/pages/routing/bgp.inc.php +++ b/html/pages/routing/bgp.inc.php @@ -266,7 +266,7 @@ else { $peer_ip = $peer['bgpLocalAddr']; } - $localaddresslink = "', LEFT".$config['overlib_defaults'].');" onmouseout="return nd();">'.$peer_ip.''; + $localaddresslink = "
', LEFT".$config['overlib_defaults'].');" onmouseout="return nd();">'.$peer_ip.''; $graph_type = 'bgp_updates'; $peer_daily_url = 'graph.php?id='.$peer['bgpPeer_id'].'&type='.$graph_type.'&from='.$config['time']['day'].'&to='.$config['time']['now'].'&width=500&height=150'; @@ -277,7 +277,7 @@ else { $peer_ident = $peer['bgpPeerIdentifier']; } - $peeraddresslink = "', LEFT".$config['overlib_defaults'].');" onmouseout="return nd();">'.$peer_ident.''; + $peeraddresslink = "
', LEFT".$config['overlib_defaults'].');" onmouseout="return nd();">'.$peer_ident.''; echo ''; diff --git a/html/pages/search/arp.inc.php b/html/pages/search/arp.inc.php index 9f2ed062f..f6c6492d6 100644 --- a/html/pages/search/arp.inc.php +++ b/html/pages/search/arp.inc.php @@ -71,9 +71,9 @@ if ($_POST['searchby'] == 'ip') { ""+ "
"+ "
"+ - " "\" class=\"form-control input-sm\" placeholder=\"Address\" />"+ @@ -88,7 +88,7 @@ echo '"'.$_POST['address'].'"+'; id: "arp-search", device_id: '', searchby: '', - address: '' + searchPhrase: '' }; }, url: "ajax_table.php" diff --git a/html/pages/services.inc.php b/html/pages/services.inc.php index 0e4d2edfc..c71988413 100644 --- a/html/pages/services.inc.php +++ b/html/pages/services.inc.php @@ -8,7 +8,6 @@ echo "Services » "; $menu_options = array( 'basic' => 'Basic', - 'details' => 'Details', ); $sql_param = array(); @@ -68,9 +67,9 @@ echo '
Device Service - Status Changed Message + Description '; if ($_SESSION['userlevel'] >= '5') { $host_sql = 'SELECT * FROM devices AS D, services AS S WHERE D.device_id = S.device_id GROUP BY D.hostname ORDER BY D.hostname'; diff --git a/html/pages/settings.inc.php b/html/pages/settings.inc.php index 1271e8d22..27efd4f1d 100644 --- a/html/pages/settings.inc.php +++ b/html/pages/settings.inc.php @@ -53,31 +53,32 @@ echo $pagetitle[0]; @@ -90,33 +91,32 @@ else { * @return string */ - function a2t($a) { - $r = ""; - foreach( $a as $k=>$v ) { - if( !empty($v) ) { - $r .= ""; + function a2t($a) { + $r = "
".$k."".(is_array($v)?a2t($v):"".wordwrap($v,75,"
")."
")."
"; + foreach( $a as $k=>$v ) { + if( !empty($v) ) { + $r .= ""; + } + } + $r .= '
".$k."".(is_array($v)?a2t($v):"".wordwrap($v,75,"
")."
")."
'; + return $r; + } + echo "
".a2t($config)."
"; + + if ($_SESSION['userlevel'] >= '10') { + + if ($debug) { + echo("
");
+                print_r($config);
+                echo("
"); } } - $r .= ''; - return $r; - } - if( $_SESSION['userlevel'] >= 10 ) { - echo "
".a2t($config)."
"; - } - else { - include 'includes/error-no-perm.inc.php'; - } - - if ($_SESSION['userlevel'] >= '10') { - - if ($debug) { - echo("
");
-            print_r($config);
-            echo("
"); + else { + include 'includes/error-no-perm.inc.php'; } } - else { - include 'includes/error-no-perm.inc.php'; - } +} +else { + include 'includes/error-no-perm.inc.php'; } ?> diff --git a/html/pages/settings/alerting.inc.php b/html/pages/settings/alerting.inc.php index d76303183..195c22f9b 100644 --- a/html/pages/settings/alerting.inc.php +++ b/html/pages/settings/alerting.inc.php @@ -196,6 +196,10 @@ else { $callback = urlencode($callback); $general_conf = array( + array('name' => 'alert.disable', + 'descr' => 'Disable alerting', + 'type' => 'checkbox', + ), array('name' => 'alert.admins', 'descr' => 'Issue alerts to admins', 'type' => 'checkbox', @@ -287,7 +291,7 @@ echo '

- API transport + API transport

@@ -329,7 +333,7 @@ foreach ($api_urls as $api_url) {

- Pagerduty transport + Pagerduty transport

@@ -354,7 +358,7 @@ else {
@@ -373,7 +377,7 @@ else {

- IRC transport + IRC transport

@@ -391,7 +395,7 @@ else {

- Slack transport + Slack transport

@@ -457,7 +461,7 @@ foreach ($slack_urls as $slack_url) {

- Hipchat transport + Hipchat transport

@@ -553,7 +557,7 @@ foreach ($hipchat_urls as $hipchat_url) {

- Pushover transport + Pushover transport

@@ -634,7 +638,7 @@ echo '

- Boxcar transport + Boxcar transport

@@ -700,7 +704,7 @@ echo '

- Pushbullet + Pushbullet

@@ -716,6 +720,116 @@ echo '
+
+
+

+ VictorOps +

+
+
+
+
+ +
+
+ + +
+
+
+
+
'; + +$clickatell = get_config_by_name('alert.transports.clickatell.token'); +$mobiles = get_config_like_name('alert.transports.clickatell.to.%'); +$new_mobiles = array(); +foreach ($mobiles as $mobile) { + $new_mobiles[] = $mobile['config_value']; +} +$upd_mobiles = implode(PHP_EOL, $new_mobiles); + +echo ' +
+
+

+ Clickatell transport +

+
+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+
'; +$playsms_url = get_config_by_name('alert.transports.playsms.url'); +$playsms_user = get_config_by_name('alert.transports.playsms.user'); +$playsms_token = get_config_by_name('alert.transports.playsms.token'); +$playsms_from = get_config_by_name('alert.transports.playsms.from'); +$mobiles = get_config_like_name('alert.transports.playsms.to.%'); +$new_mobiles = array(); +foreach ($mobiles as $mobile) { + $new_mobiles[] = $mobile['config_value']; +} +$upd_mobiles = implode(PHP_EOL, $new_mobiles); +echo ' +
+
+

+ PlaySMS transport +

+
+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
'; diff --git a/html/pages/settings/external.inc.php b/html/pages/settings/external.inc.php index 2960b2e25..a912ce403 100644 --- a/html/pages/settings/external.inc.php +++ b/html/pages/settings/external.inc.php @@ -19,12 +19,40 @@ $oxidized_conf = array( ), ); +$unixagent_conf = array( + array('name' => 'unix-agent.port', + 'descr' => 'Default unix-agent port', + 'type' => 'text', + ), + array('name' => 'unix-agent.connection-timeout', + 'descr' => 'Connection timeout', + 'type' => 'text', + ), + array('name' => 'unix-agent.read-timeout', + 'descr' => 'Read timeout', + 'type' => 'text', + ), +); + +$rrdtool_conf = array( + array('name' => 'rrdtool', + 'descr' => 'Path to rrdtool binary', + 'type' => 'text', + ), + array('name' => 'rrdtool_tune', + 'descr' => 'Tune all rrd port files to use max values', + 'type' => 'checkbox', + ), +); + echo '
'; echo generate_dynamic_config_panel('Oxidized integration',true,$config_groups,$oxidized_conf); +echo generate_dynamic_config_panel('Unix-agent integration',true,$config_groups,$unixagent_conf); +echo generate_dynamic_config_panel('RRDTool Setup',true,$config_groups,$rrdtool_conf); echo '
diff --git a/includes/alerts.inc.php b/includes/alerts.inc.php index 85b897ee6..23a56932d 100644 --- a/includes/alerts.inc.php +++ b/includes/alerts.inc.php @@ -59,35 +59,28 @@ function GenSQL($rule) { $join = ""; while( $i < $x ) { if( isset($tables[$i+1]) ) { - if( dbFetchCell('SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_NAME = ? && COLUMN_NAME = ?',array($tables[$i+1],'device_id')) == 1 ) { - //Found valid glue in definition. - $join .= $tables[$i].".device_id = ".$tables[$i+1].".device_id && "; + $gtmp = ResolveGlues(array($tables[$i+1]),'device_id'); + if( $gtmp === false ) { + //Cannot resolve glue-chain. Rule is invalid. + return false; } - else { - //No valid glue, Resolve a glue-chain. - $gtmp = ResolveGlues(array($tables[$i+1]),'device_id'); - if( $gtmp === false ) { - //Cannot resolve glue-chain. Rule is invalid. - return false; + $last = ""; + $qry = ""; + foreach( $gtmp as $glue ) { + if( empty($last) ) { + list($tmp,$last) = explode('.',$glue); + $qry .= $glue.' = '; } - $last = ""; - $qry = ""; - foreach( $gtmp as $glue ) { - if( empty($last) ) { - list($tmp,$last) = explode('.',$glue); - $qry .= $glue.' = '; - } - else { - list($tmp,$new) = explode('.',$glue); - $qry .= $tmp.'.'.$last.' && '.$tmp.'.'.$new.' = '; - $last = $new; - } - if( !in_array($tmp, $tables) ) { - $tables[] = $tmp; - } + else { + list($tmp,$new) = explode('.',$glue); + $qry .= $tmp.'.'.$last.' && '.$tmp.'.'.$new.' = '; + $last = $new; + } + if( !in_array($tmp, $tables) ) { + $tables[] = $tmp; } - $join .= "( ".$qry.$tables[0].".device_id ) && "; } + $join .= "( ".$qry.$tables[0].".device_id ) && "; } $i++; } @@ -123,8 +116,11 @@ function ResolveGlues($tables,$target,$x=0,$hist=array(),$last=array()) { $glues = dbFetchRows('SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = ? && COLUMN_NAME LIKE "%\_id"',array($table)); if( sizeof($glues) == 1 && $glues[0]['COLUMN_NAME'] != $target ) { //Search for new candidates to expand - $tmp = dbFetchRows('SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME LIKE "'.substr($table,0,-1).'_%" && TABLE_NAME != "'.$table.'"'); $ntables = array(); + list($tmp) = explode('_',$glues[0]['COLUMN_NAME'],2); + $ntables[] = $tmp; + $ntables[] = $tmp.'s'; + $tmp = dbFetchRows('SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME LIKE "'.substr($table,0,-1).'_%" && TABLE_NAME != "'.$table.'"'); foreach( $tmp as $expand ) { $ntables[] = $expand['TABLE_NAME']; } @@ -211,7 +207,7 @@ function IsMaintenance( $device ) { $where .= " || alert_schedule_items.target = ?"; $params[] = 'g'.$group; } - return dbFetchCell('SELECT DISTINCT(alert_schedule.schedule_id) FROM alert_schedule LEFT JOIN alert_schedule_items ON alert_schedule.schedule_id=alert_schedule_items.schedule_id WHERE ( alert_schedule_items.target = ?'.$where.' ) && NOW() BETWEEN alert_schedule.start AND alert_schedule.end LIMIT 1',$params); + return dbFetchCell('SELECT alert_schedule.schedule_id FROM alert_schedule LEFT JOIN alert_schedule_items ON alert_schedule.schedule_id=alert_schedule_items.schedule_id WHERE ( alert_schedule_items.target = ?'.$where.' ) && NOW() BETWEEN alert_schedule.start AND alert_schedule.end LIMIT 1',$params); } /** diff --git a/includes/alerts/transport.clickatell.php b/includes/alerts/transport.clickatell.php new file mode 100644 index 000000000..02d1f5a91 --- /dev/null +++ b/includes/alerts/transport.clickatell.php @@ -0,0 +1,42 @@ +/* Copyright (C) 2015 Daniel Preussker + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +/** + * Clickatell REST-API Transport + * @author f0o + * @copyright 2015 f0o, LibreNMS + * @license GPL + * @package LibreNMS + * @subpackage Alerts + */ + +$data = array("api_id" => $opts['api_id'], "user" => $opts['user'], "password" => $opts['password'], "to" => implode(',',$opts['to']), "text" => $obj['title']); +if (!empty($opts['from'])) { + $data['from'] = $opts['from']; +} +$url = 'https://api.clickatell.com/http/sendmsg?'.http_build_query($data); +$curl = curl_init($url); + +curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST"); +curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + +$ret = curl_exec($curl); +$code = curl_getinfo($curl, CURLINFO_HTTP_CODE); +if( $code > 200 ) { + if( $debug ) { + var_dump($ret); + } + return false; +} +return true; diff --git a/includes/alerts/transport.hipchat.php b/includes/alerts/transport.hipchat.php index 4787458cf..5a209bbef 100644 --- a/includes/alerts/transport.hipchat.php +++ b/includes/alerts/transport.hipchat.php @@ -27,14 +27,20 @@ foreach($opts as $option) { $api = str_replace("%".$key, $method == "get" ? urlencode($value) : $value, $api); } $curl = curl_init(); - $data = array( - "message" => $obj["msg"], - "room_id" => $option["room_id"], - "from" => $option["from"], - "color" => $option["color"], - "notify" => $option["notify"], - "message_format" => $option["message_format"] - ); + + if (empty($option["message_format"])) { + $option["message_format"] = 'text'; + } + + $data[] = "message=".urlencode($obj["msg"]); + $data[] = "room_id=".urlencode($option["room_id"]); + $data[] = "from=".urlencode($option["from"]); + $data[] = "color=".urlencode($option["color"]); + $data[] = "notify=".urlencode($option["notify"]); + $data[] = "message_format=".urlencode($option["message_format"]); + + $data = implode('&', $data); + // Sane default of making the message color green if the message indicates // that the alert recovered. if(strstr($data["message"], "recovered")) { @@ -44,6 +50,9 @@ foreach($opts as $option) { curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); + curl_setopt($curl, CURLOPT_HTTPHEADER, array( + 'Content-Type: application/x-www-form-urlencoded', + )); $ret = curl_exec($curl); $code = curl_getinfo($curl, CURLINFO_HTTP_CODE); diff --git a/includes/alerts/transport.playsms.php b/includes/alerts/transport.playsms.php new file mode 100644 index 000000000..812ae4ffe --- /dev/null +++ b/includes/alerts/transport.playsms.php @@ -0,0 +1,42 @@ +/* Copyright (C) 2015 Daniel Preussker + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +/** + * PlaySMS API Transport + * @author f0o + * @copyright 2015 f0o, LibreNMS + * @license GPL + * @package LibreNMS + * @subpackage Alerts + */ + +$data = array("u" => $opts['user'], "h" => $opts['token'], "to" => implode(',',$opts['to']), "msg" => $obj['title']); +if (!empty($opts['from'])) { + $data["from"] = $opts['from']; +} +$url = $opts['url'].'&op=pv&'.http_build_query($data); +$curl = curl_init($url); + +curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET"); +curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + +$ret = curl_exec($curl); +$code = curl_getinfo($curl, CURLINFO_HTTP_CODE); +if( $code > 202 ) { + if( $debug ) { + var_dump($ret); + } + return false; +} +return true; diff --git a/includes/alerts/transport.victorops.php b/includes/alerts/transport.victorops.php new file mode 100644 index 000000000..7e1fd622a --- /dev/null +++ b/includes/alerts/transport.victorops.php @@ -0,0 +1,57 @@ +/* Copyright (C) 2015 Daniel Preussker + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +/** + * VictorOps Generic-API Transport - Based on PagerDuty transport + * @author f0o + * @author laf + * @copyright 2015 f0o, laf, LibreNMS + * @license GPL + * @package LibreNMS + * @subpackage Alerts + */ + +$url = $opts['url']; + +$protocol = array( + 'entity_id' => ($obj['id'] ? $obj['id'] : $obj['uid']), + 'state_start_time' => strtotime($obj['timestamp']), + 'monitoring_tool' => 'librenms', +); +if( $obj['state'] == 0 ) { + $protocol['message_type'] = 'recovery'; +} +elseif( $obj['state'] == 2 ) { + $protocol['message_type'] = 'acknowledgement'; +} +elseif ($obj['state'] == 1) { + $protocol['message_type'] = 'critical'; +} + +foreach( $obj['faults'] as $fault=>$data ) { + $protocol['state_message'] .= $data['string']; +} + +$curl = curl_init(); +curl_setopt($curl, CURLOPT_URL, $url ); +curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); +curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type'=> 'application/json')); +curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($protocol)); +$ret = curl_exec($curl); +$code = curl_getinfo($curl, CURLINFO_HTTP_CODE); +if( $code != 200 ) { + var_dump("VictorOps returned Error, retry later"); //FIXME: propper debuging + return false; +} +return true; diff --git a/includes/billing.php b/includes/billing.php index 9e7ef5edc..246d6dfeb 100644 --- a/includes/billing.php +++ b/includes/billing.php @@ -189,6 +189,8 @@ function getRates($bill_id, $datefrom, $dateto) { $data['total_data_in'] = $mtot_in; $data['total_data_out'] = $mtot_out; $data['rate_average'] = ($mtot / $ptot * 8); + $data['rate_average_in'] = ($mtot_in / $ptot * 8); + $data['rate_average_out'] = ($mtot_out / $ptot * 8); // print_r($data); return ($data); diff --git a/includes/caches/notifications.inc.php b/includes/caches/notifications.inc.php new file mode 100644 index 000000000..0716010a4 --- /dev/null +++ b/includes/caches/notifications.inc.php @@ -0,0 +1,47 @@ + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +/** + * Notification Cache + * @author Daniel Preussker + * @copyright 2015 Daniel Preussker, QuxLabs UG + * @license GPL + * @package LibreNMS + * @subpackage Notifications + */ + +$data['count'] = array( + 'query' => 'select count(notifications.notifications_id) from notifications where not exists( select 1 from notifications_attribs where notifications.notifications_id = notifications_attribs.notifications_id and notifications_attribs.user_id = ?)', + 'params' => array( $_SESSION['user_id'] ) +); + +$data['unread'] = array( + 'query' => 'select notifications.* from notifications where not exists( select 1 from notifications_attribs where notifications.notifications_id = notifications_attribs.notifications_id and notifications_attribs.user_id = ?) order by notifications.notifications_id desc', + 'params' => array( $_SESSION['user_id'] ) +); + +$data['sticky'] = array( + 'query' => 'select notifications.*,notifications_attribs.user_id from notifications inner join notifications_attribs on notifications.notifications_id = notifications_attribs.notifications_id where notifications_attribs.key = "sticky" && notifications_attribs.value = 1 order by notifications_attribs.attrib_id desc', +); + +$data['sticky_count'] = array( + 'query' => 'select count(notifications.notifications_id) from notifications inner join notifications_attribs on notifications.notifications_id = notifications_attribs.notifications_id where notifications_attribs.key = "sticky" && notifications_attribs.value = 1', +); + +$data['read'] = array( + 'query' => 'select notifications.* from notifications inner join notifications_attribs on notifications.notifications_id = notifications_attribs.notifications_id where notifications_attribs.user_id = ? && ( notifications_attribs.key = "read" && notifications_attribs.value = 1) && not exists( select 1 from notifications_attribs where notifications.notifications_id = notifications_attribs.notifications_id and notifications_attribs.key = "sticky" && notifications_attribs.value = "1") order by notifications_attribs.attrib_id desc', + 'params' => array( $_SESSION['user_id'] ) +); + diff --git a/includes/common.php b/includes/common.php index 248285600..de68cfd78 100644 --- a/includes/common.php +++ b/includes/common.php @@ -774,3 +774,36 @@ function can_ping_device($attribs) { return false; } } // end can_ping_device + +/** + * Constructs the path to an RRD for the Ceph application + * @param string $gtype The type of rrd we're looking for + * @return string +**/ +function ceph_rrd($gtype) { + global $device; + global $vars; + global $config; + + if ($gtype == "osd") { + $var = $vars['osd']; + } + else { + $var = $vars['pool']; + } + + $rrd = join('-', array('app', 'ceph', $vars['id'], $gtype, $var)).'.rrd'; + return join('/', array($config['rrd_dir'], $device['hostname'], $rrd)); +} + +/** + * Parse location field for coordinates + * @param string location The location field to look for coords in. + * @return array Containing the lat and lng coords +**/ +function parse_location($location) { + preg_match('/(\[)(-?[0-9\. ]+),[ ]*(-?[0-9\. ]+)(\])/', $location, $tmp_loc); + if (!empty($tmp_loc[2]) && !empty($tmp_loc[3])) { + return array('lat' => $tmp_loc[2], 'lng' => $tmp_loc[3]); + } +}//end parse_location() diff --git a/includes/dbFacile.mysql.php b/includes/dbFacile.mysql.php index bdcce1ac1..f2bb56c0b 100644 --- a/includes/dbFacile.mysql.php +++ b/includes/dbFacile.mysql.php @@ -28,7 +28,12 @@ function dbQuery($sql, $parameters=array()) { $fullSql = dbMakeQuery($sql, $parameters); if ($debug) { if (php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR'])) { - print $console_color->convert("\nSQL[%y".$fullSql.'%n] '); + if (preg_match('/(INSERT INTO `alert_log`).*(details)/i',$fullSql)) { + echo "\nINSERT INTO `alert_log` entry masked due to binary data\n"; + } + else { + print $console_color->convert("\nSQL[%y".$fullSql.'%n] '); + } } else { $sql_debug[] = $fullSql; diff --git a/includes/dbFacile.mysqli.php b/includes/dbFacile.mysqli.php index 9e49491a6..15a48962c 100644 --- a/includes/dbFacile.mysqli.php +++ b/includes/dbFacile.mysqli.php @@ -28,7 +28,12 @@ function dbQuery($sql, $parameters=array()) { $fullSql = dbMakeQuery($sql, $parameters); if ($debug) { if (php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR'])) { - print $console_color->convert("\nSQL[%y".$fullSql.'%n] '); + if (preg_match('/(INSERT INTO `alert_log`).*(details)/i',$fullSql)) { + echo "\nINSERT INTO `alert_log` entry masked due to binary data\n"; + } + else { + print $console_color->convert("\nSQL[%y".$fullSql.'%n] '); + } } else { $sql_debug[] = $fullSql; diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php index 7f1e7bd77..407402746 100644 --- a/includes/defaults.inc.php +++ b/includes/defaults.inc.php @@ -127,6 +127,7 @@ $config['page_title_prefix'] = ''; $config['page_title_suffix'] = $config['project_name']; $config['timestamp_format'] = 'd-m-Y H:i:s'; $config['page_gen'] = 0; +$config['enable_lazy_load'] = true; // display MySqL & PHP stats in footer? $config['login_message'] = 'Unauthorised access or use shall render the user liable to criminal and/or civil prosecution.'; $config['public_status'] = false; @@ -215,6 +216,8 @@ $config['autodiscovery']['nets-exclude'][] = '127.0.0.0/8'; $config['autodiscovery']['nets-exclude'][] = '169.254.0.0/16'; $config['autodiscovery']['nets-exclude'][] = '224.0.0.0/4'; $config['autodiscovery']['nets-exclude'][] = '240.0.0.0/4'; +// Autodiscover by IP +$config['discovery_by_ip'] = false;// Set to true if you want to enable auto discovery by IP. $config['alerts']['email']['enable'] = false; // Enable email alerts @@ -406,6 +409,8 @@ $config['network_map_vis_options'] = '{ // Device page options $config['show_overview_tab'] = true; +$config['cpu_details_overview'] = false; //By default show only average cpu in device overview + // The device overview page options $config['overview_show_sysDescr'] = true; @@ -529,7 +534,6 @@ $config['device_traffic_iftype'][] = '/ppp/'; $config['device_traffic_descr'][] = '/loopback/'; $config['device_traffic_descr'][] = '/vlan/'; $config['device_traffic_descr'][] = '/tunnel/'; -$config['device_traffic_descr'][] = '/:\d+/'; $config['device_traffic_descr'][] = '/bond/'; $config['device_traffic_descr'][] = '/null/'; $config['device_traffic_descr'][] = '/dummy/'; @@ -824,3 +828,9 @@ $config['summary_errors'] = 0; // Default width of the availability map's tiles $config['availability-map-width'] = 25; + +// Default notifications Feed +$config['notifications']['LibreNMS'] = 'http://www.librenms.org/notifications.rss'; + +// Update channel (Can be 'master' or 'release') +$config['update_channel'] = 'master'; diff --git a/includes/definitions.inc.php b/includes/definitions.inc.php index d8a4a12f0..066f5a2c1 100644 --- a/includes/definitions.inc.php +++ b/includes/definitions.inc.php @@ -107,6 +107,18 @@ $config['os'][$os]['over'][1]['text'] = 'Processor Usage'; $config['os'][$os]['over'][2]['graph'] = 'device_ucd_memory'; $config['os'][$os]['over'][2]['text'] = 'Memory Usage'; +$os = 'infinity'; +$config['os'][$os]['text'] = 'LigoWave Infinity'; +$config['os'][$os]['type'] = 'wireless'; +$config['os'][$os]['icon'] = 'ligowave'; +$config['os'][$os]['nobulk'] = 1; +$config['os'][$os]['over'][0]['graph'] = 'device_bits'; +$config['os'][$os]['over'][0]['text'] = 'Device Traffic'; +$config['os'][$os]['over'][1]['graph'] = 'device_processor'; +$config['os'][$os]['over'][1]['text'] = 'Processor Usage'; +$config['os'][$os]['over'][2]['graph'] = 'device_mempool'; +$config['os'][$os]['over'][2]['text'] = 'Memory Usage'; + // Ubiquiti $os = 'unifi'; $config['os'][$os]['text'] = 'Ubiquiti UniFi'; @@ -114,7 +126,11 @@ $config['os'][$os]['type'] = 'wireless'; $config['os'][$os]['icon'] = 'ubiquiti'; $config['os'][$os]['nobulk'] = 1; $config['os'][$os]['over'][0]['graph'] = 'device_bits'; +$config['os'][$os]['over'][0]['text'] = 'Device Traffic'; $config['os'][$os]['over'][1]['graph'] = 'device_processor'; +$config['os'][$os]['over'][1]['text'] = 'Processor Usage'; +$config['os'][$os]['over'][2]['graph'] = 'device_mempool'; +$config['os'][$os]['over'][2]['text'] = 'Memory Usage'; $os = 'airos'; $config['os'][$os]['text'] = 'Ubiquiti AirOS'; @@ -437,7 +453,6 @@ $os = 'nos'; $config['os'][$os]['text'] = 'Brocade NOS'; $config['os'][$os]['type'] = 'network'; $config['os'][$os]['ifname'] = 1; -$config['os'][$os]['descr_to_alias'] = 1; $config['os'][$os]['over'][0]['graph'] = 'device_bits'; $config['os'][$os]['over'][0]['text'] = 'Device Traffic'; $config['os'][$os]['over'][1]['graph'] = 'device_processor'; @@ -488,6 +503,14 @@ $config['os'][$os]['icon'] = 'siklu'; $config['os'][$os]['over'][0]['graph'] = 'device_bits'; $config['os'][$os]['over'][0]['text'] = 'Traffic'; +// Saf Wireless +$os = 'saf'; +$config['os'][$os]['text'] = 'SAF Wireless'; +$config['os'][$os]['type'] = 'wireless'; +$config['os'][$os]['icon'] = 'saf'; +$config['os'][$os]['over'][0]['graph'] = 'device_bits'; +$config['os'][$os]['over'][0]['text'] = 'Traffic'; + // Supermicro Switch $os = 'supermicro-switch'; $config['os'][$os]['group'] = 'supermicro'; @@ -505,6 +528,14 @@ $config['os'][$os]['bad_if'][] = 'cpu'; $config['os'][$os]['over'][0]['graph'] = 'device_bits'; $config['os'][$os]['over'][0]['text'] = 'Device Traffic'; +//Quanta switches +$os = 'quanta'; +$config['os'][$os]['text'] = 'Quanta'; +$config['os'][$os]['type'] = 'network'; +$config['os'][$os]['icon'] = 'quanta'; +$config['os'][$os]['over'][0]['graph'] = 'device_bits'; +$config['os'][$os]['over'][0]['text'] = 'Device Traffic'; + $os = 'netonix'; $config['os'][$os]['text'] = 'Netonix'; $config['os'][$os]['type'] = 'network'; @@ -776,6 +807,14 @@ $config['os'][$os]['text'] = 'D-Link Access Point'; $config['os'][$os]['type'] = 'wireless'; $config['os'][$os]['icon'] = 'dlink'; +// TP-Link +$os = 'tplink'; +$config['os'][$os]['text'] = 'TP-Link Switch'; +$config['os'][$os]['type'] = 'network'; +$config['os'][$os]['icon'] = 'tplink'; +$config['os'][$os]['over'][0]['graph'] = 'device_bits'; +$config['os'][$os]['over'][0]['text'] = 'Device Traffic'; + $os = 'axiscam'; $config['os'][$os]['text'] = 'AXIS Network Camera'; $config['os'][$os]['icon'] = 'axis'; @@ -1024,6 +1063,7 @@ $config['os'][$os]['icon'] = 'comet'; $config['os'][$os]['over'][0]['graph'] = 'device_temperature'; $config['os'][$os]['over'][0]['text'] = 'temperature'; + //printer $os = 'dell-laser'; $config['os'][$os]['group'] = 'printer'; $config['os'][$os]['text'] = 'Dell Laser'; @@ -1111,6 +1151,13 @@ $config['os'][$os]['over'][0]['text'] = 'Toner'; $config['os'][$os]['ifname'] = 1; $config['os'][$os]['type'] = 'printer'; +$os ='samsungprinter'; +$config['os'][$os]['group'] = 'printer'; +$config['os'][$os]['text'] = 'Samsung Printer'; +$config['os'][$os]['type'] = 'printer'; +$config['os'][$os]['over'][0]['graph'] = 'device_toner'; +$config['os'][$os]['over'][0]['text'] = 'Toner'; + $os = '3com'; $config['os'][$os]['text'] = '3Com'; $config['os'][$os]['over'][0]['graph'] = 'device_bits'; @@ -1209,6 +1256,8 @@ $os = 'canopy'; $config['os'][$os]['text'] = 'Cambium'; $config['os'][$os]['type'] = 'wireless'; $config['os'][$os]['icon'] = 'cambium'; +$config['os'][$os]['over'][0]['graph'] = 'device_bits'; +$config['os'][$os]['over'][0]['text'] = 'Device Traffic'; $os = 'datacom'; $config['os'][$os]['text'] = 'Datacom'; @@ -1237,6 +1286,10 @@ $config['os'][$os]['type'] = 'network'; $config['os'][$os]['ifXmcbc'] = 1; $config['os'][$os]['over'][0]['graph'] = 'device_bits'; $config['os'][$os]['over'][0]['text'] = 'Device Traffic'; +$config['os'][$os]['over'][1]['graph'] = 'device_processor'; +$config['os'][$os]['over'][1]['text'] = 'CPU Usage'; +$config['os'][$os]['over'][2]['graph'] = 'device_mempool'; +$config['os'][$os]['over'][2]['text'] = 'Memory Usage'; $config['os'][$os]['icon'] = 'pbn'; // Enterasys @@ -1339,6 +1392,14 @@ $config['os'][$os]['icon'] = 'riverbed'; $config['os'][$os]['over'][0]['graph'] = 'device_bits'; $config['os'][$os]['over'][0]['text'] = 'Traffic'; +// Ligowave LigoOS +$os = 'ligoos'; +$config['os'][$os]['text'] = 'LigoWave LigoOS'; +$config['os'][$os]['type'] = 'wireless'; +$config['os'][$os]['icon'] = 'ligowave'; +$config['os'][$os]['over'][0]['graph'] = 'device_bits'; +$config['os'][$os]['over'][0]['text'] = 'Traffic'; + // Appliances $os = 'fortios'; $config['os'][$os]['text'] = 'FortiOS'; @@ -1729,10 +1790,6 @@ if (isset($config['rrdgraph_def_text'])) { $config['rrd_opts_array'] = explode(' ', trim($config['rrdgraph_def_text'])); } -if (!isset($config['log_file'])) { - $config['log_file'] = $config['log_dir'].'/'.$config['project_id'].'.log'; -} - if (isset($config['cdp_autocreate'])) { $config['dp_autocreate'] = $config['cdp_autocreate']; } @@ -1801,7 +1858,7 @@ if (!isset($config['log_dir'])) { } if (!isset($config['log_file'])) { - $config['log_dir'].'/'.$config['project_id'].'.log'; + $config['log_file'] = $config['log_dir'].'/'.$config['project_id'].'.log'; } if (!isset($config['plugin_dir'])) { diff --git a/includes/device-groups.inc.php b/includes/device-groups.inc.php index a1573ec03..3624db490 100644 --- a/includes/device-groups.inc.php +++ b/includes/device-groups.inc.php @@ -31,7 +31,7 @@ * @param string $search What to searchid for * @return string */ -function GenGroupSQL($pattern, $search='') { +function GenGroupSQL($pattern, $search='',$extra=0) { $pattern = RunGroupMacros($pattern); if ($pattern === false) { return false; @@ -47,6 +47,9 @@ function GenGroupSQL($pattern, $search='') { } } + $pattern = rtrim($pattern, '&&'); + $pattern = rtrim($pattern, '||'); + $tables = array_keys(array_flip($tables)); $x = sizeof($tables); $i = 0; @@ -63,7 +66,11 @@ function GenGroupSQL($pattern, $search='') { $search .= ' &&'; } - $sql = 'SELECT DISTINCT('.str_replace('(', '', $tables[0]).'.device_id) FROM '.implode(',', $tables).' WHERE '.$search.' ('.str_replace(array('%', '@', '!~', '~'), array('', '.*', 'NOT REGEXP', 'REGEXP'), $pattern).')'; + $sql_extra = ''; + if ($extra === 1) { + $sql_extra = ",`devices`.*"; + } + $sql = 'SELECT DISTINCT('.str_replace('(', '', $tables[0]).'.device_id)'.$sql_extra.' FROM '.implode(',', $tables).' WHERE '.$search.' ('.str_replace(array('%', '@', '!~', '~'), array('', '.*', 'NOT REGEXP', 'REGEXP'), $pattern).')'; return $sql; }//end GenGroupSQL() @@ -96,17 +103,21 @@ function GetDeviceGroups() { }//end GetDeviceGroups() - /** * Get all groups of Device * @param integer $device Device-ID * @return array */ -function GetGroupsFromDevice($device) { +function GetGroupsFromDevice($device,$extra=0) { $ret = array(); foreach (GetDeviceGroups() as $group) { - if (dbFetchCell(GenGroupSQL($group['pattern'], 'device_id=?').' LIMIT 1', array($device)) == $device) { - $ret[] = $group['id']; + if (dbFetchCell(GenGroupSQL($group['pattern'], 'device_id=?',$extra).' LIMIT 1', array($device)) == $device) { + if ($extra === 0) { + $ret[] = $group['id']; + } + else { + $ret[] = $group; + } } } diff --git a/includes/discovery/discovery-protocols.inc.php b/includes/discovery/discovery-protocols.inc.php index 0afe43311..5563da898 100644 --- a/includes/discovery/discovery-protocols.inc.php +++ b/includes/discovery/discovery-protocols.inc.php @@ -143,11 +143,24 @@ if ($device['os'] == 'pbn' && $config['autodiscovery']['xdp'] === true) { if (!$remote_device_id && is_valid_hostname($lldp['lldpRemSysName'])) { $remote_device_id = discover_new_device($lldp['lldpRemSysName'], $device, 'LLDP', $interface); } - + // normalize MAC address if present + if ($lldp['lldpRemChassisIdSubtype'] == 'macAddress') { + $remote_mac_address = str_replace(array(' ', ':', '-'), '', strtolower($lldp['lldpRemChassisId'])); + } + // get remote device hostname from db by MAC address and replace lldpRemSysName if absent + if (!$remote_device_id && $remote_mac_address) { + $remote_device_id = dbFetchCell('SELECT `device_id` FROM `ports` WHERE ifPhysAddress = ? AND `deleted` = ?', array($remote_mac_address, '0')); + if ($remote_device_id) { + $remote_device_hostname = dbFetchRow('SELECT `hostname` FROM `devices` WHERE `device_id` = ?', array($remote_device_id)); + } + if ($remote_device_hostname['hostname']) { + $lldp['lldpRemSysName'] = $remote_device_hostname['hostname']; + } + } if ($remote_device_id) { $if = $lldp['lldpRemPortDesc']; $id = $lldp['lldpRemPortId']; - $remote_port_id = dbFetchCell('SELECT `port_id` FROM `ports` WHERE (`ifDescr` = ? OR `ifName` = ? OR `ifDescr` = ? OR `ifName` = ?) AND `device_id` = ?', array($if, $if, $id, $id, $remote_device_id)); + $remote_port_id = dbFetchCell('SELECT `port_id` FROM `ports` WHERE (`ifDescr` = ? OR `ifName` = ? OR `ifDescr` = ? OR `ifName` = ? OR `ifPhysAddress` = ?) AND `device_id` = ?', array($if, $if, $id, $id, $remote_mac_address, $remote_device_id)); } else { $remote_port_id = '0'; @@ -162,7 +175,7 @@ if ($device['os'] == 'pbn' && $config['autodiscovery']['xdp'] === true) { }//end if }//end elseif -echo 'OSPF Discovery: '; +echo ' OSPF Discovery: '; if ($config['autodiscovery']['ospf'] === true) { echo "enabled\n"; diff --git a/includes/discovery/entity-physical.inc.php b/includes/discovery/entity-physical.inc.php index 812be65ff..caacb5be2 100644 --- a/includes/discovery/entity-physical.inc.php +++ b/includes/discovery/entity-physical.inc.php @@ -37,6 +37,9 @@ if ($config['enable_inventory']) { $entPhysicalIsFRU = $entry['jnxFruType']; $entPhysicalAlias = $entry['entPhysicalAlias']; $entPhysicalAssetID = $entry['entPhysicalAssetID']; + // fix for issue 1865, $entPhysicalIndex, as it contains a quad dotted number on newer Junipers + // using str_replace to remove all dots should fix this even if it changes in future + $entPhysicalIndex = str_replace('.','',$entPhysicalIndex); } else { $entPhysicalDescr = $entry['entPhysicalDescr']; @@ -127,18 +130,7 @@ if ($config['enable_inventory']) { echo '+'; }//end if - if ($device['os'] == 'junos') { - // $entPhysicalIndex appears as a numeric OID fragment - // (string), so convert it to an "integer" for the - // validation step below since it is stored in the DB as - // an integer. This should be fixed. - list($first,$second) = explode('.', $entPhysicalIndex); - $entPhysicalIndexNoDots = $first.$second; - $valid[$entPhysicalIndexNoDots] = 1; - } - else { - $valid[$entPhysicalIndex] = 1; - } + $valid[$entPhysicalIndex] = 1; }//end if }//end foreach } diff --git a/includes/discovery/functions.inc.php b/includes/discovery/functions.inc.php index dbe5d08dd..a90a65d41 100644 --- a/includes/discovery/functions.inc.php +++ b/includes/discovery/functions.inc.php @@ -34,6 +34,13 @@ function discover_new_device($hostname, $device='', $method='', $interface='') { return false; } } + elseif (filter_var($dst_host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === true || filter_var($dst_host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === true){ + // gethostbyname returned a valid $ip, was $dst_host an IP? + if ($config['discovery_by_ip'] === false) { + d_echo('Discovery by IP disabled, skipping ' . $dst_host); + return false; + } + } d_echo("ip lookup result: $ip\n"); diff --git a/includes/discovery/mempools/hrstorage.inc.php b/includes/discovery/mempools/hrstorage.inc.php index acef0138f..5a853245a 100644 --- a/includes/discovery/mempools/hrstorage.inc.php +++ b/includes/discovery/mempools/hrstorage.inc.php @@ -31,6 +31,10 @@ if (is_array($storage_array)) { break; } + if ($device['os'] == 'vmware' && $descr == 'Real Memory') { + $deny = 0; + } + if ($device['os'] == 'routeros' && $descr == 'main memory') { $deny = 0; } diff --git a/includes/discovery/mempools/infinity.inc.php b/includes/discovery/mempools/infinity.inc.php new file mode 100644 index 000000000..a6734cb31 --- /dev/null +++ b/includes/discovery/mempools/infinity.inc.php @@ -0,0 +1,22 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +if ($device['os'] == 'infinity') { + echo 'INFINITY-MEMORY-POOL: '; + + $total = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.1.1.0', '-OvQ'); + $free = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.1.2.0', '-OvQ'); + + if (is_numeric($total) && is_numeric($free)) { + discover_mempool($valid_mempool, $device, 0, 'infinity', 'Memory', '1', null, null); + } +} diff --git a/includes/discovery/mempools/nos.inc.php b/includes/discovery/mempools/nos.inc.php new file mode 100644 index 000000000..a801e52af --- /dev/null +++ b/includes/discovery/mempools/nos.inc.php @@ -0,0 +1,15 @@ +\d+)/', $device['version'], $version); + d_echo($version); + + // specified MIB supported since build 16607 + if ($version[build] >= 16607) { + + $usage = snmp_get($device, 'NMS-MEMORY-POOL-MIB::nmsMemoryPoolUtilization.0', '-OUvQ'); + + if (is_numeric($usage)) { + discover_mempool($valid_mempool, $device, 0, 'pbn-mem', 'Main Memory', '100', null, null); + } + } +} diff --git a/includes/discovery/mempools/unifi.inc.php b/includes/discovery/mempools/unifi.inc.php new file mode 100644 index 000000000..26704f422 --- /dev/null +++ b/includes/discovery/mempools/unifi.inc.php @@ -0,0 +1,22 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +if ($device['os'] == 'unifi') { + echo 'UNIFI-MEMORY-POOL: '; + + $total = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.1.1.0', '-OvQ'); + $free = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.1.2.0', '-OvQ'); + + if (is_numeric($total) && is_numeric($free)) { + discover_mempool($valid_mempool, $device, 0, 'unifi', 'Memory', '1', null, null); + } +} diff --git a/includes/discovery/mempools/vrp.inc.php b/includes/discovery/mempools/vrp.inc.php index ca06a851e..794b36a3b 100644 --- a/includes/discovery/mempools/vrp.inc.php +++ b/includes/discovery/mempools/vrp.inc.php @@ -3,9 +3,9 @@ // Huawei VRP mempools if ($device['os'] == 'vrp') { echo 'VRP : '; - $mempools_array = snmpwalk_cache_multi_oid($device, 'hwEntityMemUsage', $mempools_array, 'HUAWEI-ENTITY-EXTENT-MIB', $config['install_dir'].'/mibs'); - $mempools_array = snmpwalk_cache_multi_oid($device, 'hwEntityMemSize', $mempools_array, 'HUAWEI-ENTITY-EXTENT-MIB', $config['install_dir'].'/mibs'); - $mempools_array = snmpwalk_cache_multi_oid($device, 'hwEntityBomEnDesc', $mempools_array, 'HUAWEI-ENTITY-EXTENT-MIB', $config['install_dir'].'/mibs'); + $mempools_array = snmpwalk_cache_multi_oid($device, 'hwEntityMemUsage', $mempools_array, 'HUAWEI-ENTITY-EXTENT-MIB', $config['mib_dir'].':'.$config['mib_dir'].'/huawei'); + $mempools_array = snmpwalk_cache_multi_oid($device, 'hwEntityMemSize', $mempools_array, 'HUAWEI-ENTITY-EXTENT-MIB', $config['mib_dir'].':'.$config['mib_dir'].'/huawei'); + $mempools_array = snmpwalk_cache_multi_oid($device, 'hwEntityBomEnDesc', $mempools_array, 'HUAWEI-ENTITY-EXTENT-MIB', $config['mib_dir'].':'.$config['mib_dir'].'/huawei'); d_echo($mempools_array); if (is_array($mempools_array)) { diff --git a/includes/discovery/os/ciscosb.inc.php b/includes/discovery/os/ciscosb.inc.php index ce35a8ff8..03d942b21 100644 --- a/includes/discovery/os/ciscosb.inc.php +++ b/includes/discovery/os/ciscosb.inc.php @@ -1,5 +1,8 @@ + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +if (!$os) { + if (preg_match('/^NFT 2N/', $sysDescr)) { + $os = 'infinity'; + } +} diff --git a/includes/discovery/os/ligoos.inc.php b/includes/discovery/os/ligoos.inc.php new file mode 100644 index 000000000..08d0a3c2e --- /dev/null +++ b/includes/discovery/os/ligoos.inc.php @@ -0,0 +1,17 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +if (!$os) { + if (preg_match('/^LigoPTP/', $sysDescr)) { + $os = 'ligoos'; + } +} diff --git a/includes/discovery/os/netonix.inc.php b/includes/discovery/os/netonix.inc.php index 04f977230..46ee5b89e 100644 --- a/includes/discovery/os/netonix.inc.php +++ b/includes/discovery/os/netonix.inc.php @@ -1,7 +1,6 @@ Num CPUs in the device + if ($device['os'] == 'fortigate') { - echo 'Fortigate : '; + echo 'Fortigate : '; - $descr = 'Processor'; - $usage = snmp_get($device, '.1.3.6.1.4.1.12356.101.4.1.3.0', '-Ovq'); +// Forti have logical CPU numbering - start at 1 and increment to $num_cpu in the box. +$num_cpu = snmp_get($device, 'FORTINET-FORTIGATE-MIB::fgProcessorCount.0', '-Ovq'); - if (is_numeric($usage)) { - discover_processor($valid['processor'], $device, '.1.3.6.1.4.1.12356.101.4.1.3.0', '0', 'fortigate-fixed', $descr, '1', $usage, null, null); - } -} +print "Forti-found $num_cpu CPUs\n"; + +for($i = 1; $i <= $num_cpu; $i++) { + // HERP DERP IM A FORTIGATE AND I PUT NON NUMERIC VALUES IN A GAUGE + $cpu_usage = snmp_get($device, "FORTINET-FORTIGATE-MIB::fgProcessorUsage.$i", '-Ovq'); + $usage = trim ( str_replace(" %", "", $cpu_usage ) ) ; + $descr = snmp_get($device, "FORTINET-FORTIGATE-MIB::fgProcModDescr.$i", '-Ovq'); + print "CPU: $num_cpu - USAGE: $cpu_usage - TYPE $descr\n"; + if (is_numeric($usage)) { + discover_processor($valid['processor'], $device, "FORTINET-FORTIGATE-MIB::fgProcessorUsage." . $num_cpu, '0', 'fortigate-fixed', $descr, '1', $usage, null, null); + } +} // END For loop for CPU discovery + +} // END if device is Fortigate unset($processors_array); diff --git a/includes/discovery/processors/infinity.inc.php b/includes/discovery/processors/infinity.inc.php new file mode 100644 index 000000000..ee7779dd9 --- /dev/null +++ b/includes/discovery/processors/infinity.inc.php @@ -0,0 +1,24 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +if ($device['os'] == 'infinity') { + echo 'LigoWave Infinity: '; + + $descr = 'CPU'; + $usage = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.4.2.1.3.2', '-Ovqn'); + + if (is_numeric($usage)) { + discover_processor($valid['processor'], $device, '.1.3.6.1.4.1.10002.1.1.1.4.2.1.3.2', '0', 'infinity', $descr, '1', $usage, null, null); + } +} + +unset($processors_array); diff --git a/includes/discovery/processors/nos.inc.php b/includes/discovery/processors/nos.inc.php new file mode 100644 index 000000000..c0051e466 --- /dev/null +++ b/includes/discovery/processors/nos.inc.php @@ -0,0 +1,14 @@ +\d+)/', $device['version'], $version); + d_echo($version); + + // specified MIB supported since build 16607 + if ($version[build] >= 16607) { + + echo 'PBN : '; + + $descr = 'Processor'; + $usage = snmp_get($device, 'NMS-PROCESS-MIB::nmspmCPUTotal5min.1', '-OUvQ'); + + if (is_numeric($usage)) { + discover_processor($valid['processor'], $device, 'NMS-PROCESS-MIB::nmspmCPUTotal5min', '0', 'pbn-cpu', $descr, '100', $usage, null, null); + } + } +} diff --git a/includes/discovery/processors/unifi.inc.php b/includes/discovery/processors/unifi.inc.php new file mode 100644 index 000000000..0d463d669 --- /dev/null +++ b/includes/discovery/processors/unifi.inc.php @@ -0,0 +1,24 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +if ($device['os'] == 'unifi') { + echo 'Ubiquiti UniFi: '; + + $descr = 'CPU'; + $usage = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.4.2.1.3.2', '-Ovqn'); + + if (is_numeric($usage)) { + discover_processor($valid['processor'], $device, '.1.3.6.1.4.1.10002.1.1.1.4.2.1.3.2', '0', 'unifi', $descr, '1', $usage, null, null); + } +} + +unset($processors_array); diff --git a/includes/discovery/processors/vrp.inc.php b/includes/discovery/processors/vrp.inc.php index 3cdbcdf2e..3b37b8e91 100644 --- a/includes/discovery/processors/vrp.inc.php +++ b/includes/discovery/processors/vrp.inc.php @@ -3,9 +3,9 @@ // Huawei VRP Processors if ($device['os'] == 'vrp') { echo 'Huawei VRP '; - $processors_array = snmpwalk_cache_multi_oid($device, 'hwEntityCpuUsage', $processors_array, 'HUAWEI-ENTITY-EXTENT-MIB', '+'.$config['install_dir'].'/mibs'); - $processors_array = snmpwalk_cache_multi_oid($device, 'hwEntityMemSize', $processors_array, 'HUAWEI-ENTITY-EXTENT-MIB', '+'.$config['install_dir'].'/mibs'); - $processors_array = snmpwalk_cache_multi_oid($device, 'hwEntityBomEnDesc', $processors_array, 'HUAWEI-ENTITY-EXTENT-MIB', '+'.$config['install_dir'].'/mibs'); + $processors_array = snmpwalk_cache_multi_oid($device, 'hwEntityCpuUsage', $processors_array, 'HUAWEI-ENTITY-EXTENT-MIB', $config['mib_dir'].':'.$config['mib_dir'].'/huawei'); + $processors_array = snmpwalk_cache_multi_oid($device, 'hwEntityMemSize', $processors_array, 'HUAWEI-ENTITY-EXTENT-MIB', $config['mib_dir'].':'.$config['mib_dir'].'/huawei'); + $processors_array = snmpwalk_cache_multi_oid($device, 'hwEntityBomEnDesc', $processors_array, 'HUAWEI-ENTITY-EXTENT-MIB', $config['mib_dir'].':'.$config['mib_dir'].'/huawei'); d_echo($processors_array); if (is_array($processors_array)) { diff --git a/includes/discovery/storage/hrstorage.inc.php b/includes/discovery/storage/hrstorage.inc.php index 46907e10a..04012237b 100644 --- a/includes/discovery/storage/hrstorage.inc.php +++ b/includes/discovery/storage/hrstorage.inc.php @@ -33,6 +33,13 @@ if (is_array($hrstorage_array)) { break; } + if ($device['os'] == 'vmware' && $descr == 'Real Memory') { + $old_rrdfile = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename('storage-hrstorage-'.safename($descr).'.rrd'); + $new_rrdfile = $config['rrd_dir'].'/'.$device['hostname'].'/'.safename('mempool-hrstorage-'.$storage['hrStorageIndex'].'.rrd'); + rename($old_rrdfile, $new_rrdfile); + $deny = 1; + } + foreach ($config['ignore_mount'] as $bi) { if ($bi == $descr) { $deny = 1; diff --git a/includes/functions.php b/includes/functions.php index 11411158a..11b3a503d 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -1285,3 +1285,31 @@ function host_exists($hostname) { return false; } } + +/** + * Check the innodb buffer size + * + * @return array including the current set size and the currently used buffer +**/ +function innodb_buffer_check() { + $pool['size'] = dbFetchCell('SELECT @@innodb_buffer_pool_size'); + // The following query is from the excellent mysqltuner.pl by Major Hayden https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl + $pool['used'] = dbFetchCell('SELECT SUM(DATA_LENGTH+INDEX_LENGTH) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ("information_schema", "performance_schema", "mysql") AND ENGINE = "InnoDB" GROUP BY ENGINE ORDER BY ENGINE ASC'); + return $pool; +} + +/** + * Print warning about InnoDB buffer size + * + * @param array $innodb_buffer An array that contains the used and current size + * + * @return string $output +**/ +function warn_innodb_buffer($innodb_buffer) { + $output = 'InnoDB Buffersize too small.'.PHP_EOL; + $output .= 'Current size: '.($innodb_buffer['size'] / 1024 / 1024).' MiB'.PHP_EOL; + $output .= 'Minimum Required: '.($innodb_buffer['used'] / 1024 / 1024).' MiB'.PHP_EOL; + $output .= 'To ensure integrity, we\'re not going to pull any updates until the buffersize has been adjusted.'.PHP_EOL; + $output .= 'Config proposal: "innodb_buffer_pool_size = '.pow(2,ceil(log(($innodb_buffer['used'] / 1024 / 1024),2))).'M"'.PHP_EOL; + return $output; +} diff --git a/includes/object-cache.inc.php b/includes/object-cache.inc.php index 61cea5323..dfb81621e 100644 --- a/includes/object-cache.inc.php +++ b/includes/object-cache.inc.php @@ -95,7 +95,10 @@ class ObjCache implements ArrayAccess { return $GLOBALS['_ObjCache'][$this->obj][$obj]['value']; } else { - $GLOBALS['_ObjCache'][$this->obj][$obj]['value'] = dbFetchCell($this->data[$obj]['query'], $this->data[$obj]['params']); + $GLOBALS['_ObjCache'][$this->obj][$obj]['value'] = dbFetchRows($this->data[$obj]['query'], $this->data[$obj]['params']); + if (sizeof($GLOBALS['_ObjCache'][$this->obj][$obj]['value']) == 1 && sizeof($GLOBALS['_ObjCache'][$this->obj][$obj]['value'][0]) == 1) { + $GLOBALS['_ObjCache'][$this->obj][$obj]['value'] = current($GLOBALS['_ObjCache'][$this->obj][$obj]['value'][0]); + } return $GLOBALS['_ObjCache'][$this->obj][$obj]['value']; } } diff --git a/includes/polling/applications/ceph.inc.php b/includes/polling/applications/ceph.inc.php new file mode 100644 index 000000000..b3ae5ced7 --- /dev/null +++ b/includes/polling/applications/ceph.inc.php @@ -0,0 +1,71 @@ +', $section); + if ($section == "poolstats") { + foreach (explode("\n", $data) as $line) { + if (empty($line)) + continue; + list($pool,$ops,$wrbytes,$rbytes) = explode(':', $line); + $ceph_rrd = $ceph_rrddir.'/app-ceph-'.$app['app_id'].'-pool-'.$pool.'.rrd'; + if (!is_file($ceph_rrd)) { + rrdtool_create( + $ceph_rrd, + '--step 300 + DS:ops:GAUGE:600:0:U + DS:wrbytes:GAUGE:600:0:U + DS:rbytes:GAUGE:600:0:U '.$config['rrd_rra'] + ); + } + + print "Ceph Pool: $pool, IOPS: $ops, Wr bytes: $wrbytes, R bytes: $rbytes\n"; + rrdtool_update($ceph_rrd, array("ops" => $ops, "wrbytes" => $wrbytes, "rbytes" => $rbytes)); + } + } + elseif ($section == "osdperformance") { + foreach (explode("\n", $data) as $line) { + if (empty($line)) + continue; + list($osd,$apply,$commit) = explode(':', $line); + $ceph_rrd = $ceph_rrddir.'/app-ceph-'.$app['app_id'].'-osd-'.$osd.'.rrd'; + if (!is_file($ceph_rrd)) { + rrdtool_create( + $ceph_rrd, + '--step 300 + DS:apply_ms:GAUGE:600:0:U + DS:commit_ms:GAUGE:600:0:U '.$config['rrd_rra'] + ); + } + + print "Ceph OSD: $osd, Apply: $apply, Commit: $commit\n"; + rrdtool_update($ceph_rrd, array("apply_ms" => $apply, "commit_ms" => $commit)); + } + } + elseif ($section == "df") { + foreach (explode("\n", $data) as $line) { + if (empty($line)) + continue; + list($pool,$avail,$used,$objects) = explode(':', $line); + $ceph_rrd = $ceph_rrddir.'/app-ceph-'.$app['app_id'].'-df-'.$pool.'.rrd'; + if (!is_file($ceph_rrd)) { + rrdtool_create( + $ceph_rrd, + '--step 300 + DS:avail:GAUGE:600:0:U + DS:used:GAUGE:600:0:U + DS:objects:GAUGE:600:0:U '.$config['rrd_rra'] + ); + } + + print "Ceph Pool DF: $pool, Avail: $avail, Used: $used, Objects: $objects\n"; + rrdtool_update($ceph_rrd, array("avail" => $avail, "used" => $used, "objects" => $objects)); + } + } + } +} diff --git a/includes/polling/applications/mysql.inc.php b/includes/polling/applications/mysql.inc.php index 5931f4fdc..2d0804991 100644 --- a/includes/polling/applications/mysql.inc.php +++ b/includes/polling/applications/mysql.inc.php @@ -109,6 +109,7 @@ $mapping = array( ); $values = array(); +unset($fields); foreach ($mapping as $k => $v) { $fields[$k] = isset($map[$v]) ? $map[$v] : (-1); } diff --git a/includes/polling/applications/ntpd-server.inc.php b/includes/polling/applications/ntpd-server.inc.php index 1e70e69c3..a54ae0da5 100644 --- a/includes/polling/applications/ntpd-server.inc.php +++ b/includes/polling/applications/ntpd-server.inc.php @@ -4,8 +4,9 @@ $rrd_filename = $config['rrd_dir'].'/'.$device['hostname'].'/app-ntpdserver-'.$app['app_id'].'.rrd'; $options = '-O qv'; $oid = 'nsExtendOutputFull.10.110.116.112.100.115.101.114.118.101.114'; +$mib = 'NET-SNMP-EXTEND-MIB'; -$ntpdserver = snmp_get($device, $oid, $options); +$ntpdserver = snmp_get($device, $oid, $options, $mib); echo ' ntpd-server'; diff --git a/includes/polling/applications/powerdns.inc.php b/includes/polling/applications/powerdns.inc.php index f836b5015..f34e9423e 100644 --- a/includes/polling/applications/powerdns.inc.php +++ b/includes/polling/applications/powerdns.inc.php @@ -6,7 +6,12 @@ $options = '-O qv'; $mib = 'NET-SNMP-EXTEND-MIB'; $oid = 'nsExtendOutputFull.8.112.111.119.101.114.100.110.115'; -$powerdns = snmp_get($device, $oid, $options, $mib); +if ($agent_data['app']['powerdns']) { + $powerdns = $agent_data['app']['powerdns']; +} +else { + $powerdns = snmp_get($device, $oid, $options, $mib); +} echo ' powerdns'; diff --git a/includes/polling/applications/proxmox.inc.php b/includes/polling/applications/proxmox.inc.php index 37f8d8cd4..c1e366b36 100644 --- a/includes/polling/applications/proxmox.inc.php +++ b/includes/polling/applications/proxmox.inc.php @@ -41,16 +41,16 @@ function proxmox_vm_exists($i, $c, &$pmxcache) { $pmxlines = explode("\n", $proxmox); -if (count($pmxlines) > 2) { - $pmxcluster = array_shift($pmxlines); +$pmxcluster = array_shift($pmxlines); - $pmxcdir = join('/', array($config['rrd_dir'],'proxmox',$pmxcluster)); - if (!is_dir($pmxcdir)) { - mkdir($pmxcdir, 0775, true); - } +$pmxcdir = join('/', array($config['rrd_dir'],'proxmox',$pmxcluster)); +if (!is_dir($pmxcdir)) { + mkdir($pmxcdir, 0775, true); +} - dbUpdate(array('device_id' => $device['device_id'], 'app_type' => 'proxmox', 'app_instance' => $pmxcluster), 'applications', '`device_id` = ? AND `app_type` = ?', array($device['device_id'], 'proxmox')); +dbUpdate(array('device_id' => $device['device_id'], 'app_type' => 'proxmox', 'app_instance' => $pmxcluster), 'applications', '`device_id` = ? AND `app_type` = ?', array($device['device_id'], 'proxmox')); +if (count($pmxlines) > 0) { $pmxcache = []; foreach ($pmxlines as $vm) { @@ -68,7 +68,9 @@ if (count($pmxlines) > 2) { DS:OUTOCTETS:DERIVE:600:0:12500000000 '.$config['rrd_rra']); } - rrdtool_update($rrd_filename, 'N:'.$vmpin.':'.$vmpout); + rrdtool_update($rrd_filename, array("INOCTETS" => $vmpin, "OUTOCTETS" => $vmpout)); + print "Proxmox ($pmxcluster): $vmdesc: $vmpin/$vmpout/$vmport\n"; + if (proxmox_vm_exists($vmid, $pmxcluster, $pmxcache) === true) { dbUpdate(array('device_id' => $device['device_id'], 'last_seen' => array('NOW()'), 'description' => $vmdesc), 'proxmox', '`vmid` = ? AND `cluster` = ?', array($vmid, $pmxcluster)); } @@ -84,10 +86,11 @@ if (count($pmxlines) > 2) { } } - - unset($pmxlines); - unset($pmxcluster); - unset($pmxcdir); - unset($proxmox); - unset($pmxcache); } + + +unset($pmxlines); +unset($pmxcluster); +unset($pmxcdir); +unset($proxmox); +unset($pmxcache); diff --git a/includes/polling/functions.inc.php b/includes/polling/functions.inc.php index c6cff3c9c..d678e3688 100644 --- a/includes/polling/functions.inc.php +++ b/includes/polling/functions.inc.php @@ -122,7 +122,7 @@ function poll_sensor($device, $class, $unit) { log_event(ucfirst($class).' '.$sensor['sensor_descr'].' above threshold: '.$sensor_value." $unit (> ".$sensor['sensor_limit']." $unit)", $device, $class, $sensor['sensor_id']); } - dbUpdate(array('sensor_current' => $sensor_value), 'sensors', '`sensor_class` = ? AND `sensor_id` = ?', array($class, $sensor['sensor_id'])); + dbUpdate(array('sensor_current' => $sensor_value, 'lastupdate' => array('NOW()')), 'sensors', '`sensor_class` = ? AND `sensor_id` = ?', array($class, $sensor['sensor_id'])); }//end foreach }//end poll_sensor() @@ -462,7 +462,10 @@ function location_to_latlng($device) { if (!empty($device_location)) { $new_device_location = preg_replace("/ /","+",$device_location); // We have a location string for the device. - $loc = dbFetchRow("SELECT `lat`,`lng` FROM `locations` WHERE `location`=? LIMIT 1", array($device_location)); + $loc = parse_location($device_location); + if (!is_array($loc)) { + $loc = dbFetchRow("SELECT `lat`,`lng` FROM `locations` WHERE `location`=? LIMIT 1", array($device_location)); + } if (is_array($loc) === false) { // Grab data from which ever Geocode service we use. switch ($config['geoloc']['engine']) { diff --git a/includes/polling/ipmi.inc.php b/includes/polling/ipmi.inc.php index 9ede1c0bb..cfbc5bf7b 100644 --- a/includes/polling/ipmi.inc.php +++ b/includes/polling/ipmi.inc.php @@ -53,7 +53,7 @@ if ($ipmi['host'] = get_dev_attrib($device, 'ipmi_hostname')) { influx_update($device,'ipmi',$tags,$fields); // FIXME warnings in event & mail not done here yet! - dbUpdate(array('sensor_current' => $sensor), 'sensors', 'poller_type = ? AND sensor_class = ? AND sensor_id = ?', array('ipmi', $ipmisensors['sensor_class'], $ipmisensors['sensor_id'])); + dbUpdate(array('sensor_current' => $sensor, 'lastupdate' => array('NOW()')), 'sensors', 'poller_type = ? AND sensor_class = ? AND sensor_id = ?', array('ipmi', $ipmisensors['sensor_class'], $ipmisensors['sensor_id'])); } unset($ipmi_sensor); diff --git a/includes/polling/mempools/infinity.inc.php b/includes/polling/mempools/infinity.inc.php new file mode 100644 index 000000000..94e3e9dd1 --- /dev/null +++ b/includes/polling/mempools/infinity.inc.php @@ -0,0 +1,17 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +$total = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.1.1.0', '-OvQ'); +$free = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.1.2.0', '-OvQ'); +$mempool['total'] = $total * 1024; +$mempool['free'] = $free * 1024; +$mempool['used'] = ($mempool['total'] - $mempool['free']); diff --git a/includes/polling/mempools/nos.inc.php b/includes/polling/mempools/nos.inc.php new file mode 100644 index 000000000..418830263 --- /dev/null +++ b/includes/polling/mempools/nos.inc.php @@ -0,0 +1,7 @@ +\d+)/', $device['version'], $version); + d_echo($version); + + // specified MIB supported since build 16607 + if ($version[build] >= 16607) { + $perc = snmp_get($device, "NMS-MEMORY-POOL-MIB::nmsMemoryPoolUtilization.0", '-OUvQ'); + $memory_available = snmp_get($device, "NMS-MEMORY-POOL-MIB::nmsMemoryPoolTotalMemorySize.0", '-OUvQ'); + $mempool['total'] = $memory_available; + + if (is_numeric($perc)) { + $mempool['used'] = ($memory_available / 100 * $perc); + $mempool['free'] = ($memory_available - $mempool['used']); + } + + echo "PERC " .$perc."%\n"; + echo "Avail " .$mempool['total']."\n"; + } +} diff --git a/includes/polling/mempools/unifi.inc.php b/includes/polling/mempools/unifi.inc.php new file mode 100644 index 000000000..05611285d --- /dev/null +++ b/includes/polling/mempools/unifi.inc.php @@ -0,0 +1,17 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +$total = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.1.1.0', '-OvQ'); +$free = snmp_get($device, '.1.3.6.1.4.1.10002.1.1.1.1.2.0', '-OvQ'); +$mempool['total'] = $total * 1024; +$mempool['free'] = $free * 1024; +$mempool['used'] = ($mempool['total'] - $mempool['free']); diff --git a/includes/polling/mempools/vrp.inc.php b/includes/polling/mempools/vrp.inc.php index 5693a0e9a..b43469977 100644 --- a/includes/polling/mempools/vrp.inc.php +++ b/includes/polling/mempools/vrp.inc.php @@ -8,8 +8,8 @@ if (!is_array($mempool_cache['vrp'])) { d_echo('caching'); $mempool_cache['vrp'] = array(); - $mempool_cache['vrp'] = snmpwalk_cache_multi_oid($device, 'hwEntityMemSize', $mempool_cache['vrp'], 'HUAWEI-ENTITY-EXTENT-MIB', $config['install_dir'].'/mibs'); - $mempool_cache['vrp'] = snmpwalk_cache_multi_oid($device, 'hwEntityMemUsage', $mempool_cache['vrp'], 'HUAWEI-ENTITY-EXTENT-MIB', $config['install_dir'].'/mibs'); + $mempool_cache['vrp'] = snmpwalk_cache_multi_oid($device, 'hwEntityMemSize', $mempool_cache['vrp'], 'HUAWEI-ENTITY-EXTENT-MIB', $config['mib_dir'].':'.$config['mib_dir'].'/huawei'); + $mempool_cache['vrp'] = snmpwalk_cache_multi_oid($device, 'hwEntityMemUsage', $mempool_cache['vrp'], 'HUAWEI-ENTITY-EXTENT-MIB', $config['mib_dir'].':'.$config['mib_dir'].'/huawei'); d_echo($mempool_cache); } diff --git a/includes/polling/os/fortigate.inc.php b/includes/polling/os/fortigate.inc.php index f8626710b..51b8891c3 100644 --- a/includes/polling/os/fortigate.inc.php +++ b/includes/polling/os/fortigate.inc.php @@ -36,24 +36,3 @@ if (is_numeric($sessions)) { $graphs['fortigate_sessions'] = true; } -$cpurrd = $config['rrd_dir'].'/'.$device['hostname'].'/fortigate_cpu.rrd'; -$cpu_usage = snmp_get($device, 'FORTINET-FORTIGATE-MIB::fgSysCpuUsage.0', '-Ovq'); - -if (is_numeric($cpu_usage)) { - if (!is_file($cpurrd)) { - rrdtool_create($cpurrd, ' --step 300 DS:LOAD:GAUGE:600:-1:100 '.$config['rrd_rra']); - } - - echo "CPU: $cpu_usage%\n"; - - $fields = array( - 'LOAD' => $cpu_usage, - ); - - rrdtool_update($cpurrd, $fields); - - $tags = array(); - influx_update($device,'fortigate_cpu',$tags,$fields); - - $graphs['fortigate_cpu'] = true; -} diff --git a/includes/polling/os/infinity.inc.php b/includes/polling/os/infinity.inc.php new file mode 100644 index 000000000..ddebce091 --- /dev/null +++ b/includes/polling/os/infinity.inc.php @@ -0,0 +1,15 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +$version = snmp_get($device, 'SNMPv2-MIB::sysDescr.0', '-Ovq'); +$version = explode(' ', $version)[2]; +$hardware = snmp_get($device, 'IEEE802dot11-MIB::dot11manufacturerProductName.5', '-Ovq'); diff --git a/includes/polling/os/ligoos.inc.php b/includes/polling/os/ligoos.inc.php new file mode 100644 index 000000000..66f7b195f --- /dev/null +++ b/includes/polling/os/ligoos.inc.php @@ -0,0 +1,15 @@ + + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. + */ + +list($hardware,$version) = explode(',', $poll_device['sysDescr']); +preg_match('/(v[0-9\-\.]+)/', $version, $tmp_version); +$version = rtrim($tmp_version[0],'.'); diff --git a/includes/polling/os/nos.inc.php b/includes/polling/os/nos.inc.php index 74363298d..bdf1702fe 100644 --- a/includes/polling/os/nos.inc.php +++ b/includes/polling/os/nos.inc.php @@ -1,6 +1,5 @@ + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. Please see LICENSE.txt at the top level of + * the source code distribution for details. +*/ + +list(,$version,,$hardware,$serial,,) = explode(";", $poll_device['sysDescr']); +list(,$hardware) = explode(":", $hardware); +list(,$serial) = explode(":", $serial); + diff --git a/includes/polling/os/samsungprinter.inc.php b/includes/polling/os/samsungprinter.inc.php new file mode 100644 index 000000000..ca4152621 --- /dev/null +++ b/includes/polling/os/samsungprinter.inc.php @@ -0,0 +1,12 @@ + // -- i can make it a function, so that you don't know what it's doing. // -- $ports = adamasMagicFunction($ports_db); ? -$ports_db = dbFetchRows('SELECT * FROM `ports` WHERE `device_id` = ?', array($device['device_id'])); +// select * doesn't do what we want if multiple tables have the same column name -- last one wins :/ +$ports_db = dbFetchRows('SELECT *, `ports_statistics`.`port_id` AS `ports_statistics_port_id`, `ports`.`port_id` AS `port_id` FROM `ports` LEFT OUTER JOIN `ports_statistics` ON `ports`.`port_id` = `ports_statistics`.`port_id` WHERE `ports`.`device_id` = ?', array($device['device_id'])); + foreach ($ports_db as $port) { $ports[$port['ifIndex']] = $port; } @@ -214,6 +229,7 @@ foreach ($port_stats as $ifIndex => $port) { echo 'valid'; if (!is_array($ports[$port['ifIndex']])) { $port_id = dbInsert(array('device_id' => $device['device_id'], 'ifIndex' => $ifIndex), 'ports'); + dbInsert(array('port_id' => $port_id), 'ports_statistics'); $ports[$port['ifIndex']] = dbFetchRow('SELECT * FROM `ports` WHERE `port_id` = ?', array($port_id)); echo 'Adding: '.$port['ifName'].'('.$ifIndex.')('.$ports[$port['ifIndex']]['port_id'].')'; // print_r($ports); @@ -222,6 +238,10 @@ foreach ($port_stats as $ifIndex => $port) { dbUpdate(array('deleted' => '0'), 'ports', '`port_id` = ?', array($ports[$ifIndex]['port_id'])); $ports[$ifIndex]['deleted'] = '0'; } + if ($ports[$ifIndex]['ports_statistics_port_id'] === null) { + // in case the port was created before we created the table + dbInsert(array('port_id' => $ports[$ifIndex]['port_id']), 'ports_statistics'); + } } else { if ($ports[$port['ifIndex']]['deleted'] != '1') { @@ -247,6 +267,7 @@ foreach ($ports as $port) { $polled_period = ($polled - $port['poll_time']); $port['update'] = array(); + $port['update_extended'] = array(); $port['state'] = array(); if ($config['slow_statistics'] == true) { @@ -262,13 +283,37 @@ foreach ($ports as $port) { $this_port['ifOutOctets'] = $this_port['ifHCOutOctets']; } + if ($device['os'] === 'airos-af' && $port['ifAlias'] === 'eth0') { + $airos_stats = snmpwalk_cache_oid($device, '.1.3.6.1.4.1.41112.1.3.3.1', $airos_stats, 'UBNT-AirFIBER-MIB'); + $this_port['ifInOctets'] = $airos_stats[1]['rxOctetsOK']; + $this_port['ifOutOctets'] = $airos_stats[1]['txOctetsOK']; + $this_port['ifInErrors'] = $airos_stats[1]['rxErroredFrames']; + $this_port['ifOutErrors'] = $airos_stats[1]['txErroredFrames']; + $this_port['ifInBroadcastPkts'] = $airos_stats[1]['rxValidBroadcastFrames']; + $this_port['ifOutBroadcastPkts'] = $airos_stats[1]['txValidBroadcastFrames']; + $this_port['ifInMulticastPkts'] = $airos_stats[1]['rxValidMulticastFrames']; + $this_port['ifOutMulticastPkts'] = $airos_stats[1]['txValidMulticastFrames']; + $this_port['ifInUcastPkts'] = $airos_stats[1]['rxValidUnicastFrames']; + $this_port['ifOutUcastPkts'] = $airos_stats[1]['txValidUnicastFrames']; + $ports['update']['ifInOctets'] = $airos_stats[1]['rxOctetsOK']; + $ports['update']['ifOutOctets'] = $airos_stats[1]['txOctetsOK']; + $ports['update']['ifInErrors'] = $airos_stats[1]['rxErroredFrames']; + $ports['update']['ifOutErrors'] = $airos_stats[1]['txErroredFrames']; + $ports['update']['ifInBroadcastPkts'] = $airos_stats[1]['rxValidBroadcastFrames']; + $ports['update']['ifOutBroadcastPkts'] = $airos_stats[1]['txValidBroadcastFrames']; + $ports['update']['ifInMulticastPkts'] = $airos_stats[1]['rxValidMulticastFrames']; + $ports['update']['ifOutMulticastPkts'] = $airos_stats[1]['txValidMulticastFrames']; + $ports['update']['ifInUcastPkts'] = $airos_stats[1]['rxValidUnicastFrames']; + $ports['update']['ifOutUcastPkts'] = $airos_stats[1]['txValidUnicastFrames']; + } + // rewrite the ifPhysAddress if (strpos($this_port['ifPhysAddress'], ':')) { list($a_a, $a_b, $a_c, $a_d, $a_e, $a_f) = explode(':', $this_port['ifPhysAddress']); $this_port['ifPhysAddress'] = zeropad($a_a).zeropad($a_b).zeropad($a_c).zeropad($a_d).zeropad($a_e).zeropad($a_f); } - if (is_numeric($this_port['ifHCInBroadcastPkts']) && is_numeric($this_port['ifHCOutBroadcastPkts']) && is_numeric($this_port['ifHCInMulticastPkts']) && is_numeric($this_port['ifHCOutMulticastPkts'])) { + if (is_numeric($this_port['ifHCInBroadcastPkts']) && is_numeric($this_port['ifHCOutBroadcastPkts']) && is_numeric($this_port['ifHCInMulticastPkts']) && is_numeric($this_port['ifHCOutMulticastPkts']) && $device['os'] !== 'ciscosb') { echo 'HC '; $this_port['ifInBroadcastPkts'] = $this_port['ifHCInBroadcastPkts']; $this_port['ifOutBroadcastPkts'] = $this_port['ifHCOutBroadcastPkts']; @@ -309,12 +354,13 @@ foreach ($ports as $port) { echo 'VLAN == '.$this_port['ifVlan']; // When devices do not provide ifAlias data, populate with ifDescr data if configured - if (($this_port['ifAlias'] == '' || $this_port['ifAlias'] == NULL) || $config['os'][$device['os']]['descr_to_alias'] == 1) { + if ($this_port['ifAlias'] == '' || $this_port['ifAlias'] == NULL) { $this_port['ifAlias'] = $this_port['ifDescr']; d_echo('Using ifDescr as ifAlias'); } // Update IF-MIB data + $tune_port = false; foreach ($data_oids as $oid) { if ($oid == 'ifAlias') { @@ -334,6 +380,15 @@ foreach ($ports as $port) { } } else if ($port[$oid] != $this_port[$oid]) { + $port_tune = get_dev_attrib($device, 'ifName_tune:'.$port['ifName']); + $device_tune = get_dev_attrib($device,'override_rrdtool_tune'); + if ($port_tune == "true" || + ($device_tune == "true" && $port_tune != 'false') || + ($config['rrdtool_tune'] == "true" && $port_tune != 'false' && $device_tune != 'false')) { + if ($oid == 'ifSpeed') { + $tune_port = true; + } + } $port['update'][$oid] = $this_port[$oid]; log_event($oid.': '.$port[$oid].' -> '.$this_port[$oid], $device, 'interface', $port['port_id']); if ($debug) { @@ -377,10 +432,17 @@ foreach ($ports as $port) { // End parse ifAlias // Update IF-MIB metrics - foreach ($stat_oids_db as $oid) { + $_stat_oids = array_merge($stat_oids_db, $stat_oids_db_extended); + foreach ($_stat_oids as $oid) { + $port_update = 'update'; + $extended_metric = !in_array($oid, $stat_oids_db, true); + if ($extended_metric) { + $port_update = 'update_extended'; + } + if ($config['slow_statistics'] == true) { - $port['update'][$oid] = $this_port[$oid]; - $port['update'][$oid.'_prev'] = $port[$oid]; + $port[$port_update][$oid] = $this_port[$oid]; + $port[$port_update][$oid.'_prev'] = $port[$oid]; } $oid_prev = $oid.'_prev'; @@ -396,8 +458,8 @@ foreach ($ports as $port) { $port['stats'][$oid.'_diff'] = $oid_diff; if ($config['slow_statistics'] == true) { - $port['update'][$oid.'_rate'] = $oid_rate; - $port['update'][$oid.'_delta'] = $oid_diff; + $port[$port_update][$oid.'_rate'] = $oid_rate; + $port[$port_update][$oid.'_delta'] = $oid_diff; } d_echo("\n $oid ($oid_diff B) $oid_rate Bps $polled_period secs\n"); @@ -477,6 +539,9 @@ foreach ($ports as $port) { 'OUTMULTICASTPKTS' => $this_port['ifOutMulticastPkts'], ); + if ($tune_port === true) { + rrdtool_tune('port',$rrdfile,$this_port['ifSpeed']); + } rrdtool_update("$rrdfile", $fields); $fields['ifInUcastPkts_rate'] = $port['ifInUcastPkts_rate']; @@ -533,6 +598,8 @@ foreach ($ports as $port) { // Update Database if (count($port['update'])) { $updated = dbUpdate($port['update'], 'ports', '`port_id` = ?', array($port['port_id'])); + // do we want to do something else with this? + $updated += dbUpdate($port['update_extended'], 'ports_statistics', '`port_id` = ?', array($port['port_id'])); d_echo("$updated updated"); } diff --git a/includes/polling/processors/nos.inc.php b/includes/polling/processors/nos.inc.php new file mode 100644 index 000000000..158ad3ce9 --- /dev/null +++ b/includes/polling/processors/nos.inc.php @@ -0,0 +1,3 @@ +\d+)/', $device['version'], $version); + d_echo($version); + + // specified MIB supported since build 16607 + if ($version[build] >= 16607) { + + $usage = snmp_get($device, 'NMS-PROCESS-MIB::nmspmCPUTotal5min.1', '-OUvQ'); + + if (is_numeric($usage)) { + $proc = ($usage * 100); + } + } +} diff --git a/includes/polling/unix-agent.inc.php b/includes/polling/unix-agent.inc.php index 8563f01ed..4e412e7e7 100644 --- a/includes/polling/unix-agent.inc.php +++ b/includes/polling/unix-agent.inc.php @@ -3,14 +3,22 @@ if ($device['os_group'] == 'unix') { echo $config['project_name'].' UNIX Agent: '; - // FIXME - this should be in config and overridable in database - $agent_port = '6556'; + $agent_port = get_dev_attrib($device,'override_Unixagent_port'); + if (empty($agent_port)) { + $agent_port = $config['unix-agent']['port']; + } + if (empty($config['unix-agent']['connection-timeout'])) { + $config['unix-agent']['connection-timeout'] = $config['unix-agent-connection-time-out']; + } + if (empty($config['unix-agent']['read-timeout'])) { + $config['unix-agent']['read-timeout'] = $config['unix-agent-read-time-out']; + } $agent_start = utime(); - $agent = fsockopen($device['hostname'], $agent_port, $errno, $errstr, $config['unix-agent-connection-time-out']); + $agent = fsockopen($device['hostname'], $agent_port, $errno, $errstr, $config['unix-agent']['connection-timeout']); // Set stream timeout (for timeouts during agent fetch - stream_set_timeout($agent, $config['unix-agent-read-time-out']); + stream_set_timeout($agent, $config['unix-agent']['read-timeout']); $agentinfo = stream_get_meta_data($agent); if (!$agent) { @@ -55,9 +63,11 @@ if ($device['os_group'] == 'unix') { $agentapps = array( "apache", + "ceph", "mysql", "nginx", "bind", + "powerdns", "proxmox", "tinydns"); @@ -108,10 +118,10 @@ if ($device['os_group'] == 'unix') { if (file_exists("includes/polling/applications/$key.inc.php")) { d_echo("Enabling $key for ".$device['hostname']." if not yet enabled\n"); - if (in_array($key, array('apache', 'mysql', 'nginx', 'proxmox'))) { + if (in_array($key, array('apache', 'mysql', 'nginx', 'proxmox', 'ceph', 'powerdns'))) { if (dbFetchCell('SELECT COUNT(*) FROM `applications` WHERE `device_id` = ? AND `app_type` = ?', array($device['device_id'], $key)) == '0') { echo "Found new application '$key'\n"; - dbInsert(array('device_id' => $device['device_id'], 'app_type' => $key), 'applications'); + dbInsert(array('device_id' => $device['device_id'], 'app_type' => $key, 'app_status' => '', 'app_instance' => ''), 'applications'); } } } @@ -123,7 +133,7 @@ if ($device['os_group'] == 'unix') { foreach ($agent_data['app']['memcached'] as $memcached_host => $memcached_data) { if (dbFetchCell('SELECT COUNT(*) FROM `applications` WHERE `device_id` = ? AND `app_type` = ? AND `app_instance` = ?', array($device['device_id'], 'memcached', $memcached_host)) == '0') { echo "Found new application 'Memcached' $memcached_host\n"; - dbInsert(array('device_id' => $device['device_id'], 'app_type' => 'memcached', 'app_instance' => $memcached_host), 'applications'); + dbInsert(array('device_id' => $device['device_id'], 'app_type' => 'memcached', 'app_status' => '', 'app_instance' => $memcached_host), 'applications'); } } } @@ -137,7 +147,7 @@ if ($device['os_group'] == 'unix') { $agent_data['app']['drbd'][$drbd_dev] = $drbd_data; if (dbFetchCell('SELECT COUNT(*) FROM `applications` WHERE `device_id` = ? AND `app_type` = ? AND `app_instance` = ?', array($device['device_id'], 'drbd', $drbd_dev)) == '0') { echo "Found new application 'DRBd' $drbd_dev\n"; - dbInsert(array('device_id' => $device['device_id'], 'app_type' => 'drbd', 'app_instance' => $drbd_dev), 'applications'); + dbInsert(array('device_id' => $device['device_id'], 'app_type' => 'drbd', 'app_status' => '', 'app_instance' => $drbd_dev), 'applications'); } } } diff --git a/includes/rrdtool.inc.php b/includes/rrdtool.inc.php index b71eee7a0..956649744 100644 --- a/includes/rrdtool.inc.php +++ b/includes/rrdtool.inc.php @@ -166,7 +166,11 @@ function rrdtool_graph($graph_file, $options) { function rrdtool($command, $filename, $options) { global $config, $debug, $rrd_pipes, $console_color; - if ($config['rrdcached'] && ($config['rrdtool_version'] >= 1.5 || $command != "create")) { + if ($config['rrdcached'] && + (version_compare($config['rrdtool_version'], '1.5.5', '>=') || + (version_compare($config['rrdtool_version'], '1.5', '>=') && $command != "tune") || + ($command != "create" && $command != "tune")) + ) { if (isset($config['rrdcached_dir']) && $config['rrdcached_dir'] !== false) { $filename = str_replace($config['rrd_dir'].'/', './'.$config['rrdcached_dir'].'/', $filename); $filename = str_replace($config['rrd_dir'], './'.$config['rrdcached_dir'].'/', $filename); @@ -280,7 +284,8 @@ function rrdtool_lastupdate($filename, $options){ function rrdtool_escape($string, $maxlength=null){ $result = shorten_interface_type($string); - $result = str_replace('%', '%%', $result); + $result = str_replace("'", '', $result); # remove quotes + $result = str_replace('%', '%%', $result); # double percent signs if (is_numeric($maxlength)) { $extra = substr_count($string, ':', 0, $maxlength); $result = substr(str_pad($result, $maxlength), 0, ($maxlength + $extra)); @@ -289,7 +294,24 @@ function rrdtool_escape($string, $maxlength=null){ } } - $result = str_replace(':', '\:', $result); + $result = str_replace(':', '\:', $result); # escape colons return $result.' '; } + +function rrdtool_tune($type, $filename, $max) { + $fields = array(); + if ($type === 'port') { + if ($max < 10000000) { + return false; + } + $max = $max / 8; + $fields = array( +'INOCTETS','OUTOCTETS','INERRORS','OUTERRORS','INUCASTPKTS','OUTUCASTPKTS','INNUCASTPKTS','OUTNUCASTPKTS','INDISCARDS','OUTDISCARDS','INUNKNOWNPROTOS','INBROADCASTPKTS','OUTBROADCASTPKTS','INMULTICASTPKTS','OUTMULTICASTPKTS' + ); + } + if (count($fields) > 0) { + $options = "--maximum " . implode(":$max --maximum ", $fields). ":$max"; + rrdtool('tune', $filename, $options); + } +} diff --git a/includes/services/ssl_cert/check.inc b/includes/services/ssl_cert/check.inc index 1f0cb9d7b..3c21078dd 100644 --- a/includes/services/ssl_cert/check.inc +++ b/includes/services/ssl_cert/check.inc @@ -9,7 +9,7 @@ if( !empty($service['service_ip']) ) { $cmd .= " ".$service['service_param']; $check = shell_exec($cmd); -list($check, $time) = split("\|", $check); +list($check, $time) = explode("\|", $check); if(strstr($check, "SSL_CERT OK")) { $status = '1'; diff --git a/lib/gridster/.gitignore b/lib/gridster/.gitignore index 440a178da..c5f40aab3 100644 --- a/lib/gridster/.gitignore +++ b/lib/gridster/.gitignore @@ -4,4 +4,8 @@ gh-pages/ demo/ .idea .DS_Store -.idea +*.iml +vendor +*.gem +*.css.map +demos/assets/css/demo.css diff --git a/lib/gridster/.jshintrc b/lib/gridster/.jshintrc new file mode 100644 index 000000000..9c9093da7 --- /dev/null +++ b/lib/gridster/.jshintrc @@ -0,0 +1,103 @@ +{ + // http://www.jshint.com/docs/ + // Based on node-jshint@2.x.x + + // ENFORCING OPTIONS + // These options tell JSHint to be more strict towards your code. Use them if + // you want to allow only a safe subset of JavaScript—very useful when your + // codebase is shared with a big number of developers with different skill + // levels. + + "bitwise": true, //prohibits the use of bitwise operators such as ^ (XOR), | (OR) and others + "camelcase": false, //force all variable names to use either camelCase style or UPPER_CASE with underscores + "curly": true, //requires you to always put curly braces around blocks in loops and conditionals + "eqeqeq": true, //prohibits the use of == and != in favor of === and !== + "es3": false, //tells JSHint that your code needs to adhere to ECMAScript 3 specification + "forin": false, //requires all `for in` loops to filter object's items with `hasOwnProperty()` + "immed": true, //prohibits the use of immediate function invocations without wrapping them in parentheses + "indent": 2, //enforces specific tab width + "latedef": true, //prohibits the use of a variable before it was defined + "newcap": true, //requires you to capitalize names of constructor functions + "noarg": true, //prohibits the use of `arguments.caller` and `arguments.callee` + "noempty": true, //warns when you have an empty block in your code + "nonew": true, //prohibits the use of constructor functions for side-effects + "plusplus": false, //prohibits the use of unary increment and decrement operators + "quotmark": true, //enforces the consistency of quotation marks used throughout your code + "undef": true, //prohibits the use of explicitly undeclared variables + "unused": "vars", //warns when you define and never use your variables + "strict": true, //requires all functions to run in ECMAScript 5's strict mode + "trailing": true, //makes it an error to leave a trailing whitespace in your code + "maxparams": false, //set the max number of formal parameters allowed per function + "maxdepth": 6, //control how nested do you want your blocks to be + "maxstatements": false, //set the max number of statements allowed per function + "maxcomplexity": false, //control cyclomatic complexity throughout your code + + // RELAXING OPTIONS + // These options allow you to suppress certain types of warnings. Use them + // only if you are absolutely positive that you know what you are doing. + + "asi": false, //suppresses warnings about missing semicolons + "boss": false, //suppresses warnings about the use of assignments in cases where comparisons are expected + "debug": false, //suppresses warnings about the debugger statements in your code + "eqnull": false, //suppresses warnings about == null comparisons + "esnext": false, //your code uses ES.next specific features such as const + "evil": false, //suppresses warnings about the use of eval + "expr": true, //suppresses warnings about the use of expressions where normally you would expect to see assignments or function calls + "funcscope": false, //suppresses warnings about declaring variables inside of control structures while accessing them later from the outside + "globalstrict": false, //suppresses warnings about the use of global strict mode + "iterator": false, //suppresses warnings about the `__iterator__` property + "lastsemic": false, //suppresses warnings about missing semicolons, but only when the semicolon is omitted for the last statement in a one-line block + "laxbreak": false, //suppresses most of the warnings about possibly unsafe line breakings in your code + "laxcomma": false, //suppresses warnings about comma-first coding style + "loopfunc": false, //suppresses warnings about functions inside of loops + "moz": false, //tells JSHint that your code uses Mozilla JavaScript extensions + "multistr": false, //suppresses warnings about multi-line strings + "proto": false, //suppresses warnings about the `__proto__` property + "scripturl": false, //suppresses warnings about the use of script-targeted URLs—such as `javascript:...` + "smarttabs": false, //suppresses warnings about mixed tabs and spaces when the latter are used for alignmnent only + "shadow": false, //suppresses warnings about variable shadowing + "sub": false, //suppresses warnings about using `[]` notation when it can be expressed in dot notation + "supernew": false, //suppresses warnings about "weird" constructions like `new function () { ... }` and `new Object;` + "validthis": false, //suppresses warnings about possible strict violations when the code is running in strict mode and you use `this` in a non-constructor function + + // ENVIRONMENTS + // These options pre-define global variables that are exposed by popular + // JavaScript libraries and runtime environments—such as browser or node.js. + // Essentially they are shortcuts for explicit declarations like + // /*global $:false, jQuery:false */ + + "browser": true, //defines globals exposed by modern browsers + "couch": false, //defines globals exposed by CouchDB + "devel": true, //defines globals that are usually used for logging poor-man's debugging: `console`, `alert`, etc. + "dojo": false, //defines globals exposed by the Dojo Toolkit + "jquery": true, //defines globals exposed by the jQuery JavaScript library + "mootools": false, //defines globals exposed by the MooTools JavaScript framework + "node": true, //defines globals available when your code is running inside of the Node runtime environment + "nonstandard": false, //defines non-standard but widely adopted globals such as `escape` and `unescape` + "phantom": false, //defines globals available when your core is running inside of the PhantomJS runtime environment + "qunit": true, //defines globals available when your core is running inside of the Qqunit runtime environment + "prototypejs": false, //defines globals exposed by the Prototype JavaScript framework + "rhino": false, //defines globals available when your code is running inside of the Rhino runtime environment + "worker": true, //defines globals available when your code is running inside of a Web Worker + "wsh": false, //defines globals available when your code is running as a script for the Windows Script Host + "yui": false, //defines globals exposed by the YUI JavaScript framework + + "globals": { + "define": false, + "throttle": false, + "delay": false, + "debounce": false, + "jQuery": true, + "require": false, + "Gridster": false + }, + + // LEGACY + // These options are legacy from JSLint. Aside from bug fixes they will not + // be improved in any way and might be removed at any point. + + "nomen": false, //disallows the use of dangling `_` in variables + "onevar": false, //allows only one `var` statement per function + "passfail": false, //makes JSHint stop on the first error or warning + "white": false //make JSHint check your source code against Douglas Crockford's JavaScript coding style +} diff --git a/lib/gridster/.npmignore b/lib/gridster/.npmignore new file mode 100644 index 000000000..b348df9ef --- /dev/null +++ b/lib/gridster/.npmignore @@ -0,0 +1,4 @@ +* +!README.md +!LICENSE +!dist/**/* \ No newline at end of file diff --git a/lib/gridster/.travis.yml b/lib/gridster/.travis.yml new file mode 100644 index 000000000..3a76b5f7a --- /dev/null +++ b/lib/gridster/.travis.yml @@ -0,0 +1,10 @@ +language: node_js +node_js: + - "0.10" +install: + - npm install + - npm install -g bower grunt-cli +before_script: + - bower install +script: + - grunt build --verbose \ No newline at end of file diff --git a/lib/gridster/CHANGELOG.md b/lib/gridster/CHANGELOG.md index 6d6f1a22f..7bdaffd7e 100644 --- a/lib/gridster/CHANGELOG.md +++ b/lib/gridster/CHANGELOG.md @@ -1,3 +1,105 @@ + +### v0.6.10 (2015-05-31) + * Add Ruby on Rails support + + +### v0.6.9 (2015-05-27) + * bug fixes for positions and overlap + * dist modified to support webpack deployements + * new 'sticky' layout option which allows widgets to be places absolutely into a position on the grid. + + +### v0.6.8 (2015-04-28) + + +#### Bug Fixes + +* **gridster:** + * responsive width now resizes based off wrapper not window ([e69c3e8f](http://github.com/dsmorse/gridster.js/commit/e69c3e8f64aa4557ef032e4d0d8185e83b1aed21)) + * ensure coords instances are destroyed on widgets ([576b5ae3](http://github.com/dsmorse/gridster.js/commit/576b5ae3f0461b048d8ff9463509b860ffa8b194)) + * `resize_widget` also accepts HTMLElements ([cda560f4](http://github.com/dsmorse/gridster.js/commit/cda560f4f3ca616d03d1e3230cd2ef4e69876d9c)) + * changed "instanceof jQuery" to "instanceof $" ([c6226306](http://github.com/dsmorse/gridster.js/commit/c6226306c2ce9aa7d45d774d7de19088acba0c66)) + * wrong addition solved in add_faux_rows/cols by adding parseInt ([d9471752](http://github.com/dsmorse/gridster.js/commit/d947175257d686801154a403016fd2ec7e6d40c2), closes [#426](http://github.com/dsmorse/gridster.js/issues/426), [#425](http://github.com/dsmorse/gridster.js/issues/425)) + * preventing gridster from adding extra resize handles ([9d077da6](http://github.com/dsmorse/gridster.js/commit/9d077da676826606243c2552dc9997c492687203)) + * destroy resize_api ([b1629326](http://github.com/dsmorse/gridster.js/commit/b16293268c6aa4be2ba0c8fb1b9806e590227606), closes [#473](http://github.com/dsmorse/gridster.js/issues/473)) + * ensure widget dimensions and coords are always ints ([595a94f1](http://github.com/dsmorse/gridster.js/commit/595a94f1bdfaa4905ff51d9044e74105c81e6ff3)) + + +#### Features + +* **draggable:** autoscrolling ([d3f25f3f](http://github.com/dsmorse/gridster.js/commit/d3f25f3fbbcc738d8b3702d122533e64f37acd29)) +* **gridster:** + * add config to set custom show/hide widget methods ([7de5bbab](http://github.com/dsmorse/gridster.js/commit/7de5bbabc0a01e8188a56881782dc74d6bf111d3)) + * browserify compatibility ([43148b87](http://github.com/dsmorse/gridster.js/commit/43148b87e523352a7f9d01479c6fed3e87f46ba0)) + * Common.js support ([446852a2](http://github.com/dsmorse/gridster.js/commit/446852a260aab2e7caf772a62fbde8b518c38816), closes [#434](http://github.com/dsmorse/gridster.js/issues/434)) +* **gridster.css:** remove possible default pading ([2002c455](http://github.com/dsmorse/gridster.js/commit/2002c455957016cb441a317dbbb6e5f6662cb35a)) + + +### v0.6.7 (2015-04-16) + + +### v0.6.6 (2015-04-08) + + +### v0.6.5 (2015-04-06) + + +#### Bug Fixes + +* **gridster:** fixed bugs in centering_widgets (widgets were getting smushed when being resized ([86053f8b](http://github.com/DecksterTeam/gridster.js/commit/86053f8be3d73a9db3d7eabc595324123dbcff13)) + + +### v0.6.4 (2015-03-19) + + +#### Bug Fixes + +* **gridster:** + * added ability to center widgets in grid + + +### v0.6.3 (2015-03-06) + + +#### Bug Fixes + +* **gridster:** + * fixing resize limits when in fixed width mode feature(gridster): added fix_to_co ([6bb47dc1](http://github.com/DecksterTeam/gridster.js/commit/6bb47dc1ce36aef670b2acb7c244ec5f4ea440e0)) + + +### v0.6.2 (2015-02-23) + + +#### Bug Fixes + +* **gridster:** forcing height of gridster container to auto when in collapsed mode ([749f37a5](http://github.com/DecksterTeam/gridster.js/commit/749f37a52074bd16362528f94ab28ec314379ee3)) + + +### v0.6.1 (2015-02-21) + + +#### Bug Fixes + +* **gridster:** + * fixed expand_widget bug not expanding full width of window fix(gridster): user c ([dbc226d4](http://github.com/DecksterTeam/gridster.js/commit/dbc226d46c8224f753c07af6aff259785c60425f)) + * fixing drag limit issues when using autogrow_cols ([afd83fea](http://github.com/DecksterTeam/gridster.js/commit/afd83fead8c719615ae01ef7b5d3863701ff2243)) + * changed the way widgets were getting positioned so that margins are actually the ([a3913043](http://github.com/DecksterTeam/gridster.js/commit/a3913043579bae9f5ef28e34524ad7a8ae7dcafd)) + + +## v0.6.0 (2015-02-18) + + +#### Bug Fixes + +* **gridster:** changed the way widgets were getting positioned so that margins are actually the ([a3913043](http://github.com/DecksterTeam/gridster.js/commit/a3913043579bae9f5ef28e34524ad7a8ae7dcafd)) + +#### Features + +* **gridster:** make grid responsive ([a3913043](http://github.com/DecksterTeam/gridster.js/commit/a3913043579bae9f5ef28e34524ad7a8ae7dcafd)) + + +### v0.5.7 (2015-02-17) + ### v0.5.6 (2014-09-25) @@ -183,3 +285,60 @@ * **gridster:** drag-and-drop widget resizing ([e1924053](http://github.com/ducksboard/gridster.js/commit/e19240532de0bad35ffe6e5fc63934819390adc5)) * **utils:** add delay helper to utils ([faa6c5db](http://github.com/ducksboard/gridster.js/commit/faa6c5db0002feccf681e9f919ed583eef152773)) +dustmoo Modifications +=========== +Changelog 2013-04-3 + +Fork now handles standard behavior properly with swap allowing larger widgets to shift down. + +Changelog 2013-04-2 + +Added Demo to Repository. + +Changelog 2013-02-27 + +Added "Static widget support" Static Items default to the "static" class. + +You can customize this class by using the code below: + + $.gridster({ + static_class: 'custom_class', + draggable: { + items: ".gs_w:not(.custom_class)" + } + }); + +I have also added functions creating a much more thourough check of whether the player can occupy the space you are moving it too. +This version is much more reliable in swapping space with widgets. + +There are also new options for Maximum Rows and Maximum Columns: + + $.gridster({ + max_rows: map_rows, + max_cols: map_cols, + shift_larger_widgets_down: false + }); + +Setting the maximum amount of rows only completely works if you disable shifting larger widgets down at the moment. + + +Changelog 11-26-2012 + +Reworked swapping functionality to better handle large to small widget handling. + +--- + +Widgets of smaller or equal size to the dragged widget (player) +will swap places with the original widget. + +This causes tiles to swap left and right as well as up and down. + +By default smaller players will shift larger widgets down. + +I have added an option to prevent this behavior: + + $.gridster({ + shift_larger_widgets_down: false + }); + +By setting shift_larger_widgets_down to false, smaller widgets will not displace larger ones. diff --git a/lib/gridster/CONTRIBUTING.md b/lib/gridster/CONTRIBUTING.md index 032a9fae0..6fb9fe4c5 100644 --- a/lib/gridster/CONTRIBUTING.md +++ b/lib/gridster/CONTRIBUTING.md @@ -141,3 +141,60 @@ included in the project: **IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the same license as that used by the project. + + +#commit Message Guidelines +We use [automatic changelog creation](https://github.com/ajoslin/conventional-changelog), so it best if your commit messages follow the following conventions: + +### Commit Message Format +Each commit message consists of a **header**, a **body** and a **footer**. The header has a special +format that includes a **type**, a **scope** and a **subject**: + +``` +(): + + + +