This commit is contained in:
laf
2015-09-21 10:17:48 +00:00
126 changed files with 9220 additions and 574 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ nbproject
.alerts.lock
.ircbot.alert
.metadata_never_index
*.swp

View File

@ -50,6 +50,9 @@ Contributors to LibreNMS:
- Mark Schouten <mark@tuxis.nl> (tuxis-ie)
- Todd Eddy <vr@vrillusions.com> (vrillusions)
- Arjit Chaudhary (arjit.c@gmail.com) (arjitc)
- Sergiusz Paprzycki <serek@walcz.net> (spaprzycki)
- Juho Vanhanen <juho@vanhanen.me> (juhovan)
- Bart de Bruijn <bart_de_bruijn@yahoo.com> (bartdebruijn)
- Christophe Martinet <martinet.christophe@gmail.com> (chrisgfx)
[1]: http://observium.org/ "Observium web site"

View File

@ -96,24 +96,14 @@ function IssueAlert($alert) {
return true;
}
$default_tpl = "%title\r\nSeverity: %severity\r\n{if %state == 0}Time elapsed: %elapsed\r\n{/if}Timestamp: %timestamp\r\nUnique-ID: %uid\r\nRule: {if %name}%name{else}%rule{/if}\r\n{if %faults}Faults:\r\n{foreach %faults} #%key: %value.string\r\n{/foreach}{/if}Alert sent to: {foreach %contacts}%value <%key> {/foreach}";
// FIXME: Put somewhere else?
if ($config['alert']['fixed-contacts'] == false) {
$alert['details']['contacts'] = GetContacts($alert['details']['rule']);
}
$obj = DescribeAlert($alert);
if (is_array($obj)) {
$tpl = dbFetchRow('SELECT `template` FROM `alert_templates` JOIN `alert_template_map` ON `alert_template_map`.`alert_templates_id`=`alert_templates`.`id` WHERE `alert_template_map`.`alert_rule_id`=?', array($alert['rule_id']));
if (isset($tpl['template'])) {
$tpl = $tpl['template'];
}
else {
$tpl = $default_tpl;
}
echo 'Issuing Alert-UID #'.$alert['id'].'/'.$alert['state'].': ';
$msg = FormatAlertTpl($tpl, $obj);
$msg = FormatAlertTpl($obj);
$obj['msg'] = $msg;
if (!empty($config['alert']['transports'])) {
ExtTransports($obj);
@ -193,7 +183,7 @@ function RunFollowUp() {
$state = 4;
}
if ($state > 0) {
if ($state > 0 && $n > 0) {
$alert['details']['rule'] = $chk;
if (dbInsert(array('state' => $state, 'device_id' => $alert['device_id'], 'rule_id' => $alert['rule_id'], 'details' => gzcompress(json_encode($alert['details']), 9)), 'alert_log')) {
dbUpdate(array('state' => $state, 'open' => 1, 'alerted' => 1), 'alerts', 'rule_id = ? && device_id = ?', array($alert['rule_id'], $alert['device_id']));
@ -238,7 +228,7 @@ function RunAlerts() {
if (!empty($rextra['count']) && empty($rextra['interval'])) {
// This check below is for compat-reasons
if (!empty($rextra['delay'])) {
if ((time() - strtotime($alert['time_logged']) + $config['alert']['tolerance-window']) < $rextra['delay'] || (!empty($alert['details']['delay']) && (time() - $alert['details']['delay'] + $config['alert']['tolerance-window']) < $rextra['delay'])) {
if ((time() - strtotime($alert['time_logged']) + $config['alert']['tolerance_window']) < $rextra['delay'] || (!empty($alert['details']['delay']) && (time() - $alert['details']['delay'] + $config['alert']['tolerance_window']) < $rextra['delay'])) {
continue;
}
else {
@ -258,12 +248,12 @@ function RunAlerts() {
}
else {
// This is the new way
if (!empty($rextra['delay']) && (time() - strtotime($alert['time_logged']) + $config['alert']['tolerance-window']) < $rextra['delay']) {
if (!empty($rextra['delay']) && (time() - strtotime($alert['time_logged']) + $config['alert']['tolerance_window']) < $rextra['delay']) {
continue;
}
if (!empty($rextra['interval'])) {
if (!empty($alert['details']['interval']) && (time() - $alert['details']['interval'] + $config['alert']['tolerance-window']) < $rextra['interval']) {
if (!empty($alert['details']['interval']) && (time() - $alert['details']['interval'] + $config['alert']['tolerance_window']) < $rextra['interval']) {
continue;
}
else {
@ -326,7 +316,7 @@ function ExtTransports($obj) {
foreach ($config['alert']['transports'] as $transport => $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').' };');
eval('$tmp = function($obj,$opts) { global $config; '.file_get_contents($config['install_dir'].'/includes/alerts/transport.'.$transport.'.php').' return false; };');
$tmp = $tmp($obj,$opts);
$prefix = array( 0=>"recovery", 1=>$obj['severity']." alert", 2=>"acknowledgment" );
$prefix[3] = &$prefix[0];
@ -349,11 +339,11 @@ function ExtTransports($obj) {
/**
* Format Alert
* @param string $tpl Template
* @param array $obj Alert-Array
* @return string
*/
function FormatAlertTpl($tpl, $obj) {
function FormatAlertTpl($obj) {
$tpl = $obj["template"];
$msg = '$ret .= "'.str_replace(array('{else}', '{/if}', '{/foreach}'), array('"; } else { $ret .= "', '"; } $ret .= "', '"; } $ret .= "'), addslashes($tpl)).'";';
$parsed = $msg;
$s = strlen($msg);
@ -426,11 +416,23 @@ function DescribeAlert($alert) {
$obj = array();
$i = 0;
$device = dbFetchRow('SELECT hostname FROM devices WHERE device_id = ?', array($alert['device_id']));
$tpl = dbFetchRow('SELECT `template`,`title`,`title_rec` FROM `alert_templates` JOIN `alert_template_map` ON `alert_template_map`.`alert_templates_id`=`alert_templates`.`id` WHERE `alert_template_map`.`alert_rule_id`=?', array($alert['rule_id']));
$default_tpl = "%title\r\nSeverity: %severity\r\n{if %state == 0}Time elapsed: %elapsed\r\n{/if}Timestamp: %timestamp\r\nUnique-ID: %uid\r\nRule: {if %name}%name{else}%rule{/if}\r\n{if %faults}Faults:\r\n{foreach %faults} #%key: %value.string\r\n{/foreach}{/if}Alert sent to: {foreach %contacts}%value <%key> {/foreach}";
$obj['hostname'] = $device['hostname'];
$obj['device_id'] = $alert['device_id'];
$extra = $alert['details'];
if (!isset($tpl['template'])) {
$obj['template'] = $default_tpl;
} else {
$obj['template'] = $tpl['template'];
}
if ($alert['state'] >= 1) {
$obj['title'] = 'Alert for device '.$device['hostname'].' - '.($alert['name'] ? $alert['name'] : $alert['rule']);
if (!empty($tpl['title'])) {
$obj['title'] = $tpl['title'];
}
else {
$obj['title'] = 'Alert for device '.$device['hostname'].' - '.($alert['name'] ? $alert['name'] : $alert['rule']);
}
if ($alert['state'] == 2) {
$obj['title'] .= ' got acknowledged';
}
@ -458,7 +460,12 @@ function DescribeAlert($alert) {
}
$extra = json_decode(gzuncompress($id['details']), true);
$obj['title'] = 'Device '.$device['hostname'].' recovered from '.($alert['name'] ? $alert['name'] : $alert['rule']);
if (!empty($tpl['title_rec'])) {
$obj['title'] = $tpl['title_rec'];
}
else {
$obj['title'] = 'Device '.$device['hostname'].' recovered from '.($alert['name'] ? $alert['name'] : $alert['rule']);
}
$obj['elapsed'] = TimeFormat(strtotime($alert['time_logged']) - strtotime($id['time_logged']));
$obj['id'] = $id['id'];
$obj['faults'] = false;
@ -473,6 +480,9 @@ function DescribeAlert($alert) {
$obj['timestamp'] = $alert['time_logged'];
$obj['contacts'] = $extra['contacts'];
$obj['state'] = $alert['state'];
if (strstr($obj['title'],'%')) {
$obj['title'] = RunJail('$ret = "'.populate(addslashes($obj['title'])).'";', $obj);
}
return $obj;
}//end DescribeAlert()

View File

@ -14,7 +14,7 @@ if ($sql_fh === false) {
exit(1);
}
$database_link = mysqli_connect($config['db_host'], $config['db_user'], $config['db_pass']);
$database_link = mysqli_connect('p:'.$config['db_host'], $config['db_user'], $config['db_pass']);
if ($database_link === false) {
echo 'ERROR: Cannot connect to database: '.mysqli_error($database_link)."\n";
exit(1);
@ -26,8 +26,23 @@ if ($select === false) {
exit(1);
}
$limit = 0;
while (!feof($sql_fh)) {
$line = fgetss($sql_fh);
if (isset($_SESSION['stage']) ) {
$limit++;
if (isset($_SESSION['offset']) && $limit < $_REQUEST['offset']) {
continue;
}
elseif ( time()-$_SESSION['last'] > 45 ) {
$_SESSION['offset'] = $limit;
$GLOBALS['refresh'] = '<b>Installing, please wait..</b><sub>'.date('r').'</sub><script>window.location.href = "install.php?offset='.$limit.'";</script>';
return;
} else {
echo 'Step #'.$limit.' ...'.PHP_EOL;
}
}
if (!empty($line)) {
$creation = mysqli_query($database_link, $line);
if (!$creation) {

View File

@ -23,11 +23,11 @@ require 'includes/discovery/functions.inc.php';
$start = utime();
$runtime_stats = array();
// Observium Device Discovery
$options = getopt('h:m:i:n:d::a::q');
if (!isset($options['q'])) {
echo $config['project_name_version']." Discovery\n\n";
echo $config['project_name_version']." Discovery\n";
echo get_last_commit()."\n";
}
if (isset($options['h'])) {

View File

@ -17,6 +17,7 @@ Table of Content:
- [PagerDuty](#transports-pagerduty)
- [Pushover](#transports-pushover)
- [Boxcar](#transports-boxcar)
- [Pushbullet](#transports-pushbullet)
- [Entities](#entities)
- [Devices](#entity-devices)
- [BGP Peers](#entity-bgppeers)
@ -360,6 +361,17 @@ $config['alert']['transports']['boxcar'][] = array(
```
~~
## <a name="transports-pushbullet">Pushbullet</a>
Enabling Pushbullet is a piece of cake.
Get your Access Token from your Pushbullet's settings page and set it in your config like:
~~
```php
$config['alert']['transports']['pushbullet'] = 'MYFANCYACCESSTOKEN';
```
~~
# <a name="entities">Entities
Entities as described earlier are based on the table and column names within the database, if you are ensure of what the entity is you want then have a browse around inside MySQL using `show tables` and `desc <tablename>`.

View File

@ -0,0 +1,30 @@
# Device Groups
LibreNMS supports grouping your devices together in much the same way as you can configure alerts. This document will hopefully help you get started.
### Pattern
Patterns work in the same was as Entities within the alerting system, the format of the pattern is based on the MySQL structure your data is in such
as __tablename.columnname__. If you are ensure of what the entity is you want then have a browse around inside MySQL using `show tables` and `desc <tablename>`.
As a working example and a common question, let's assume you want to group devices by hostname. If you hostname format is dcX.[devicetype].example.com. You would use the pattern
devices.hostname. Select the condition which in this case would Like and then enter dc1.@.example.com. This would then match dc1.sw01.example.com, dc1.rtr01.example.com but not
dc2.sw01.example.com.
#### Wildcards
As used in the example above, wildcards are represented by the @ symbol. I.e @.example.com would match any hostnames under example.com.
A list of common entities is maintained in our [Alerting docs](http://docs.librenms.org/Extensions/Alerting/#entities).
### Conditions
Please see our [Alerting docs](http://docs.librenms.org/Extensions/Alerting/#syntax) for explanations.
### Connection
If you only want to group based on one pattern then select And. If however you want to build a group based on multiple patterns then you can build a SQL like
query using And / Or. As an example, we want to base our group on the devices hostname AND it's type. Use the pattern as before, devices.hostname, select the condition which in this case would Like and then enter dc1.@.example.com then click And. Now enter devices.type in the pattern, select Equals and enter firewall. This would then match dc1.fw01.example.com but not dc1.sw01.example.com as that is a network type.
You can now select this group from the Devices -> All Devices link in the navigation at the top. You can also use the group to map alert rules to by creating an alert mapping
Overview -> Alerts -> Rule Mapping.

View File

@ -2,7 +2,10 @@
#### Please see [The new alerting docs](http://docs.librenms.org/Extensions/Alerting/#transports-email)
Currently, the email alerts needs to be set up in the config. If you want to enable it, paste this in your config and change it:
> None of these configuration options will work on builds older than the 1st of August 2015.
~~Currently, the email alerts needs to be set up in the config. If you want to enable it, paste this in your config and change it:~~
```php
// Mailer backend Settings

View File

@ -0,0 +1,40 @@
# Oxidized integration
You can integrate LibreNMS with [Oxidized](https://github.com/ytti/oxidized-web) in two ways:
### Config viewing
This is a straight forward use of Oxidized, it relies on you having a working Oxidized setup which is already taking config snapshots for your devices.
When you have that, you only need the following config to enable the display of device configs within the device page itself:
```php
$config['oxidized']['enabled'] = TRUE;
$config['oxidized']['url'] = 'http://127.0.0.1:8888';
```
We also support config versioning within Oxidized, this will allow you to see the old configs stored.
```php
$config['oxidized']['features']['versioning'] = true;
```
### Feeding Oxidized
Oxidized has support for feeding devices into it via an API call, support for Oxidized has been added to the LibreNMS API. A sample config for Oxidized is provided below.
You will need to configure default credentials for your devices, LibreNMS doesn't provide login credentials at this time.
```bash
source:
default: http
debug: false
http:
url: https://librenms/api/v0/oxidized
scheme: https
delimiter: !ruby/regexp /:/
map:
name: hostname
model: os
headers:
X-Auth-Token: '01582bf94c03104ecb7953dsadsadwed'
```

View File

@ -0,0 +1,32 @@
# Poller Service
# WARNING: THIS IS HIGHLY EXPERIMENTAL AND MAY NOT WORK
The Poller service is an alternative to polling and discovery cron jobs and provides support for distributed polling without memcache. It is multi-threaded and runs continuously discovering and polling devices with the oldest data attempting to honor the polling frequency configured in `config.php`. This service replaces all the required cron jobs except for `/opt/librenms/daily.sh` and `/opt/librenms/alerts.php`.
Configure the maximum number of threads for the service in `$config['poller_service_workers']`. Configure the minimum desired polling frequency in `$config['poller_service_poll_frequency']` and the minimum desired discovery frequency in `$config['poller_service_discover_frequency']`. The service will not poll or discover devices which have data newer than this this configured age in seconds. Configure how frequently the service will attempt to poll devices which are down in `$config['poller_service_down_retry']`.
The poller service is designed to gracefully degrade. If not all devices can be polled within the configured frequency, the service will continuously poll devices refreshing as frequently as possible using the configured number of threads.
The service logs to syslog. A loglevel of INFO will print status updates every 5 minutes. Loglevel of DEBUG will print updates on every device as it is scanned.
## Configuration
```php
// Poller-Service settings
$config['poller_service_loglevel'] = "INFO";
$config['poller_service_workers'] = 16;
$config['poller_service_poll_frequency'] = 300;
$config['poller_service_discover_frequency'] = 21600;
$config['poller_service_down_retry'] = 60;
```
## Distributed Polling
Distributed polling is possible, and uses the same configuration options as are described for traditional distributed polling, except that the memcached options are not necessary. The database must be acessable from the distributed pollers, and properly configured. Remote access to the RRD directory must also be configured as described in the Distributed Poller documentation. Memcache is not required. Concurrency is managed using mysql GET_LOCK to ensure that devices are only being polled by one device at at time. The poller service is compatible with poller groups.
## Multi-Master MySQL considerations
Because locks are not replicated in Multi-Master MySQL configurations, if you are using such a configuration, you will need to make sure that all pollers are using the same MySQL server.
## Service Installation
An upstart configuration `poller-service.conf` is provided. To install run `ln -s /opt/librenms/poller-service.conf /etc/init/poller-service.conf`. The service will start on boot and can be started manually by running `start poller-service`. If you recieve an error that the service does not exist, run `initctl reload-configuration`. The service is configured to run as the user `librenms` and will fail if that user does not exist.
An LSB init script `poller-service.init` is also provided. To install run `ln -s /opt/librenms/poller-service.init /etc/init.d/poller-service && update-rc.d poller-service defaults`.

23
doc/Extensions/Proxmox.md Normal file
View File

@ -0,0 +1,23 @@
# 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.
The ultimate goal is to be able to create traffic bills for VMs, no matter on which physical machine that VM runs.
### Enabling Proxmox graphs
To enable Proxmox graphs, do the following:
In config.php, enable Proxmox:
```php
$config['enable_proxmox'] = 1
```
Then, install librenms-agent on the machines running Proxmox, and enable the Proxmox-plugin using:
```bash
mk_enplug proxmox
```
Then, enable the unix-agent on the machines running Proxmox.
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.

View File

@ -2,23 +2,30 @@
This document will explain how to setup RRDCached for LibreNMS.
### RRDCached installation
This example is based on a fresh LibreNMS install, on a minimimal CentOS installation.
In this example, we'll use the Repoforge repository.
> If you are using rrdtool / rrdcached version 1.5 or above then this now supports creating rrd files over rrdcached. To
enable this set the following config:
```php
$config['rrdtool_version'] = 1.5;
```
### RRDCached installation CentOS 6
This example is based on a fresh LibreNMS install, on a minimimal CentOS 6 installation.
In this example, we'll use the Repoforge repository.
```ssh
rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
vi /etc/yum.repos.d/rpmforge.repo
```
- Enable the Extra repo
```php
```ssh
yum update rrdtool
vi /etc/yum.repos.d/rpmforge.repo
```
- Disable the [rpmforge] and [rpmforge-extras] repos again
```php
```ssh
vi /etc/sysconfig/rrdcached
# Settings for rrdcached
@ -33,14 +40,73 @@ chkconfig rrdcached on
service rrdcached start
```
Edit config.php to include:
- Edit /opt/librenms/config.php to include:
```php
$config['rrdcached'] = "unix:/var/run/rrdcached/rrdcached.sock";
```
### RRDCached installation CentOS 7
This example is based on a fresh LibreNMS install, on a minimimal CentOS 7.x installation.
We'll use the epel-release and setup a RRDCached as a service.
It is recommended that you monitor your LibreNMS server with LibreNMS so you can view the disk I/O usage delta.
See [Installation (RHEL CentOS)][1] for localhost monitoring.
> If you are using rrdtool / rrdcached version 1.5 or above then this now supports creating rrd files over rrdcached. To
enable this set the following config:
```php
$config['rrdtool_version'] = 1.5;
- Install the EPEL and update the repos and RRDtool.
```ssh
yum install epel-release
yum update
yum update rrdtool
```
- Create the needed directories, set ownership and permissions.
```ssh
mkdir /var/run/rrdcached
chown librenms:librenms /var/run/rrdcached
chmod 755 /var/run/rrdcached
```
- Create an rrdcache service for easy daemon management.
```ssh
touch /etc/systemd/system/rrdcache.service
```
- Edit rrdcache.service and paste the example config:
```ssh
[Unit]
Description=RRDtool Cache
After=network.service
[Service]
Type=forking
PIDFile=/run/rrdcached.pid
ExecStart=/usr/bin/rrdcached -w 1800 -z 1800 -f 3600 -s librenms -j /var/tmp -l unix:/var/run/rrdcached/rrdcached.sock -t 4 -F -b /opt/librenms/rrd/
RRDC_USER=librenms
[Install]
WantedBy=default.target
```
- Restart the systemctl daemon so it can recognize the newly created rrdcache.service. Enable the rrdcache.service on boot, and start the service.
```ssh
systemctl daemon-reload
systemctl enable rrdcache.service
systemctl start rrdcache.service
```
- Edit /opt/librenms/config.php to include:
```ssh
$config['rrdcached'] = "unix:/var/run/rrdcached/rrdcached.sock";
```
- Restart Apache
```ssh
systemctl restart httpd
```
Check to see if the graphs are being drawn in LibreNMS. This might take a few minutes.
After at least one poll cycle (5 mins), check the LibreNMS disk I/O performance delta.
Disk I/O can be found under the menu Devices>All Devices>[localhost hostname]>Health>Disk I/O.
Depending on many factors, you should see the Ops/sec drop by ~30-40%.
[1]: http://librenms.readthedocs.org/Installation/Installation-(RHEL-CentOS)/#add-localhost
"Add localhost to LibreNMS"

53
doc/Extensions/Varnish.md Normal file
View File

@ -0,0 +1,53 @@
# Setting up Varnish
This document will explain how to setup Varnish for LibreNMS.
### Varnish installation
This example is based on a fresh LibreNMS install, on a minimimal CentOS installation.
In this example, we'll use the default package available through yum.
- Install Varnish
```ssh
yum install varnish
chkconfig varnish on
```
- Confirm that Varnish has been installed
```ssh
varnishd -V
varnishd (varnish-2.1.5 SVN )
```
- Change the webservers port to 8080, since we'll put Varnish in front(Or whatever you prefer)
- Point Varnish towards the webserver by editing the default.vcl
```ssh
vi /etc/varnish/default.vcl
backend default {
.host = "127.0.0.1";
.port = "8080";
}
```
- Change the default port Varnish listens on
```ssh
vi /etc/sysconfig/varnish
VARNISH_LISTEN_PORT=80
```
- Restart webserver(Apache in this case) and start Varnish afterwards
```ssh
service httpd restart
service varnish start
```
- Browse around the webui to build up the cache, verify that the cache is working afterwards
```ssh
varnishstat
```

View File

@ -1,3 +1,48 @@
### September 2015
#### Bug fixes
- Alerting:
- Process followups if there are changes (PR1817)
- Typo in alert_window setting (PR1841)
- Issue alert-trigger as test object (PR1850)
- WebUI:
- Fix permissions for World-map widget (PR1866)
- Clean up Gloabl / World Map name mixup (PR1874)
- Services:
- Honour IP field for DNS checks (PR1933)
- Discovery / Poller:
- Fix Huawei VRP os detection (PR1931)t
- General:
- Remove 'sh' from cronjob (PR1818)
- Remove MySQL Locks (PR1822,PR1826,PR1829,PR1836)
#### Improvements
- WebUI:
- Ability to edit ifAlias (PR1811)
- Honour Mouseout/Mouseleave on map widget (PR1814)
- Make syslog/eventlog responsive (PR1816)
- Reformat Proxmox UI (PR1825,PR1827)
- Misc Changes (PR1828,PR1830,PR1875,PR1885,PR1886,PR1887,PR1891,PR1896,PR1901,PR1913)
- Added support for Oxidized versioning (PR1842)
- Added graph widget + settings for widgets (PR1835,PR1861)
- Added Support for multiple dashboards (PR1869)
- Added settings page for Worldmap widget (PR1872)
- Added uptime to availability widget (PR1881)
- Added top devices and ports widgets (PR1903)
- Added support for saving notes for devices (PR1927)
- Added detection for:
- FortiOS (PR1815)
- Discovery / Poller:
- Added Proxmox support (PR1789)
- Documentation:
- Add varnish docs (PR1809)
- Added CentOS 7 RRCached docs (1893)
- General:
- Make installer more responsive (PR1832)
- Update fping millisec option to 200 default (PR1833)
- Reduced cleanup of device_perf (PR1837)
- Added support for negative values in munin-plugins (PR1907)
### August 2015
#### Bug fixes
@ -8,6 +53,9 @@
- Fixed Web installer due to code tidying update (PR1644)
- Updated gridster variable names to make unique (PR1646)
- Fixed issues with displaying devices with ' in location (PR1655)
- Fixes updating snmpv3 details in webui (PR1727)
- Check for user perms before listing neighbour ports (PR1749)
- Fixed Test-Transport button (PR1772)
- DB:
- Added proper indexes on device_perf table (PR1621)
- Fixed multiple mysql strict issues (PR1638, PR1659)
@ -17,8 +65,18 @@
- Fixed discovery-arp not running since code formatting update (PR1671)
- Correct the DSM upgrade OID (PR1696)
- Fix MySQL agent host variable usage (PR1710)
- Pass snmp-auth parameters enclosed by single-quotes (PR1730)
- Revert change which skips over down ports (PR1742)
- Stop PoE polling for each port (PR1747)
- Use ifHighSpeed if ifSpeed equals 0 (PR1750)
- Keep PHP Backwards compatibility (PR1766)
- False identification of Zyxel as Cisco (PR1776)
- Fix MySQL statement in poller-service.py (PR1794)
- Fix upstart script for poller-service.py (PR1812)
- General:
- Fixed path to defaults.inc.php in config.php.default (PR1673)
- Strip '::ffff:' from syslog input (PR1734)
- Fix RRA (PR1791)
#### Improvements
- WebUI Updates:
@ -32,29 +90,50 @@
- Added support for running under sub-directory (PR1667)
- Updated vis.js to latest version (PR1708)
- Added border on availability map (PR1713)
- Make new dashboard the default (PR1719)
- Rearrange about page (PR1735,PR1743)
- Center/Cleanup graphs (PR1736)
- Added Hover-Effect on devices table (PR1738)
- Show Test-Transport result (PR1777)
- Add arrows to the network map (PR1787)
- Add errored ports to summary widget (PR1788)
- Show message if no Device-Groups exist (PR1796)
- Misc UI fixes (Titles, Headers, ...) (PR1797,PR1798,PR1800,PR1801,PR1802,PR1803,PR1804,PR1805)
- Move packages to overview dropdown (PR1810)
- API Updates:
- Improvided billing support in API (PR1599)
- Extended support for list devices to support mac/ipv4 and ipv6 filtering (PR1744)
- Added detection for:
- Perle Media convertors (PR1607)
- Mac OSX 10 (PR1774)
- Improved detection for:
- Windows devices (PR1639)
- Zywall CPU, Version and Memory (PR1660)
- Zywall CPU, Version and Memory (PR1660,PR1784)
- Added LLDP support for PBN devices (PR1705)
- Netgear GS110TP (PR1751)
- Additional Sensors:
- Added Compressor state for PCOWEB (PR1600)
- Added dbm support for IOS-XR (PR1661)
- Added temperature support for DNOS (PR1782)
- Discovery / Poller:
- Updated autodiscovery function to log new type (PR1623)
- Improve application polling (PR1724)
- Improve debug output (PR1756)
- DB:
- Added MySQLi support (PR1647)
- Documentation:
- Added docs on MySQL strict mode (PR1635)
- Updated billing docs to use librenms user in cron (PR1676)
- Updated LDAP docs to indicate php-ldap module needs installing (PR1716)
- Typo/Spellchecks (PR1731,PR1806)
- Improved Alerting and Device-Groups (PR1781)
- Alerting:
- Reformatted eventlog message to show state for alerts (PR1685)
- Add basic Pushbullet transport (PR1721)
- Allow custom titles (PR1807)
- General:
- Added more debugging and checks to discovery-protocols (PR1590)
- Cleanup debug statements (PR1725,PR1737)
### July 2015

View File

@ -170,7 +170,7 @@ project.
Proposed workflow for submitting pull requests
----------------------------------------------
Please see the new [Using Git](http://doc.librenms.org/Developing/Using-Git/) document which gives you step-by-step
Please see the new [Using Git](http://docs.librenms.org/Developing/Using-Git/) document which gives you step-by-step
instructions on using git to submit a pull request.
[1]: http://www.gnu.org/licenses/license-list.html

View File

@ -27,14 +27,13 @@ service mariadb start
Now continue with the installation:
```bash
yum install net-snmp mysql-server
service snmpd start
chkconfig snmpd on
mysql_secure_installation
mysql -uroot -p
```
Enter the MySQL root password to enter the MySQL command-line interface.
Enter the MySQL/MariaDB root password to enter the command-line interface.
Create database.

View File

@ -50,7 +50,7 @@ $config['fping6'] = "/usr/bin/fping6";
$config['fping_options']['retries'] = 3;
$config['fping_options']['timeout'] = 500;
$config['fping_options']['count'] = 3;
$config['fping_options']['millisec'] = 5;
$config['fping_options']['millisec'] = 200;
```
fping configuration options, this includes setting the timeout and retry options.
@ -143,6 +143,7 @@ $config['show_locations'] = 1; # Enable Locations on menu
$config['show_locations_dropdown'] = 1; # Enable Locations dropdown on menu
$config['show_services'] = 0; # Enable Services on menu
$config['int_customers'] = 1; # Enable Customer Port Parsing
$config['summary_errors'] = 0; # Show Errored ports in summary boxes on the dashboard
$config['customers_descr'] = 'cust'; // The description to look for in ifDescr. Can be an array as well array('cust','cid');
$config['transit_descr'] = ""; // Add custom transit descriptions (can be an array)
$config['peering_descr'] = ""; // Add custom peering descriptions (can be an array)

View File

@ -30,20 +30,30 @@ $type = mres($_POST['type']);
if ($type == 'placeholder') {
$output = 'Please add a Widget to get started';
$status = 'ok';
$title = 'Placeholder';
}
elseif (is_file('includes/common/'.$type.'.inc.php')) {
$results_limit = 10;
$no_form = true;
$results_limit = 10;
$no_form = true;
$title = ucfirst($type);
$unique_id = str_replace(array("-","."),"_",uniqid($type,true));
$widget_id = mres($_POST['id']);
$widget_settings = json_decode(dbFetchCell('select settings from users_widgets where user_widget_id = ?',array($widget_id)),true);
$widget_dimensions = $_POST['dimensions'];
if( !empty($_POST['settings']) ) {
define('show_settings',true);
}
include 'includes/common/'.$type.'.inc.php';
$output = implode('', $common_output);
$status = 'ok';
$title = $widget_settings['title'] ?: $title;
}
$response = array(
'status' => $status,
'html' => $output,
'title' => $title,
);
echo _json_encode($response);

View File

@ -96,23 +96,22 @@ if (isset($_REQUEST['search'])) {
}//end if
$json = json_encode($device);
print_r($json);
exit;
die($json);
}
else if ($_REQUEST['type'] == 'ports') {
// Search ports
if (is_admin() === true || is_read() === true) {
$results = dbFetchRows("SELECT `ports`.*,`devices`.* FROM `ports` LEFT JOIN `devices` ON `ports`.`device_id` = `devices`.`device_id` WHERE `ifAlias` LIKE '%".$search."%' OR `ifDescr` LIKE '%".$search."%' ORDER BY ifDescr LIMIT 8");
$results = dbFetchRows("SELECT `ports`.*,`devices`.* FROM `ports` LEFT JOIN `devices` ON `ports`.`device_id` = `devices`.`device_id` WHERE `ifAlias` LIKE '%".$search."%' OR `ifDescr` LIKE '%".$search."%' OR `ifName` LIKE '%".$search."%' ORDER BY ifDescr LIMIT 8");
}
else {
$results = dbFetchRows("SELECT DISTINCT(`I`.`port_id`), `I`.*, `D`.`hostname` FROM `ports` AS `I`, `devices` AS `D`, `devices_perms` AS `P`, `ports_perms` AS `PP` WHERE ((`P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id`) OR (`PP`.`user_id` = ? AND `PP`.`port_id` = `I`.`port_id` AND `I`.`device_id` = `D`.`device_id`)) AND `D`.`device_id` = `I`.`device_id` AND (`ifAlias` LIKE '%".$search."%' OR `ifDescr` LIKE '%".$search."%') ORDER BY ifDescr LIMIT 8", array($_SESSION['user_id'], $_SESSION['user_id']));
$results = dbFetchRows("SELECT DISTINCT(`I`.`port_id`), `I`.*, `D`.`hostname` FROM `ports` AS `I`, `devices` AS `D`, `devices_perms` AS `P`, `ports_perms` AS `PP` WHERE ((`P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id`) OR (`PP`.`user_id` = ? AND `PP`.`port_id` = `I`.`port_id` AND `I`.`device_id` = `D`.`device_id`)) AND `D`.`device_id` = `I`.`device_id` AND (`ifAlias` LIKE '%".$search."%' OR `ifDescr` LIKE '%".$search."%' OR `ifName` LIKE '%".$search."%') ORDER BY ifDescr LIMIT 8", array($_SESSION['user_id'], $_SESSION['user_id']));
}
if (count($results)) {
$found = 1;
foreach ($results as $result) {
$name = $result['ifDescr'];
$name = $result['ifDescr'] == $result['ifAlias'] ? $result['ifName'] : $result['ifDescr'];
$description = $result['ifAlias'];
if ($result['deleted'] == 0 && ($result['ignore'] == 0 || $result['ignore'] == 0) && ($result['ifInErrors_delta'] > 0 || $result['ifOutErrors_delta'] > 0)) {
@ -143,13 +142,13 @@ if (isset($_REQUEST['search'])) {
'description' => $description,
'colours' => $highlight_colour,
'hostname' => $result['hostname'],
'port_id' => $result['port_id'],
);
}//end foreach
}//end if
$json = json_encode($ports);
print_r($json);
exit;
die($json);
}
else if ($_REQUEST['type'] == 'bgp') {
// Search bgp peers
@ -204,8 +203,121 @@ if (isset($_REQUEST['search'])) {
}//end if
$json = json_encode($bgp);
print_r($json);
exit;
die($json);
}
else if ($_REQUEST['type'] == 'applications') {
// Device search
if (is_admin() === true || is_read() === true) {
$results = dbFetchRows("SELECT * FROM `applications` INNER JOIN `devices` ON devices.device_id = applications.device_id WHERE `app_type` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%' ORDER BY hostname LIMIT 8");
}
else {
$results = dbFetchRows("SELECT * FROM `applications` INNER JOIN `devices` AS `D` ON `D`.`device_id` = `applications`.`device_id` INNER JOIN `devices_perms` AS `P` ON `P`.`device_id` = `D`.`device_id` WHERE `P`.`user_id` = ? AND (`app_type` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%') ORDER BY hostname LIMIT 8", array($_SESSION['user_id']));
}
if (count($results)) {
$found = 1;
$devices = count($results);
foreach ($results as $result) {
$name = $result['app_type'];
if ($result['disabled'] == 1) {
$highlight_colour = '#808080';
}
else if ($result['ignored'] == 1 && $result['disabled'] == 0) {
$highlight_colour = '#000000';
}
else if ($result['status'] == 0 && $result['ignore'] == 0 && $result['disabled'] == 0) {
$highlight_colour = '#ff0000';
}
else if ($result['status'] == 1 && $result['ignore'] == 0 && $result['disabled'] == 0) {
$highlight_colour = '#008000';
}
$device[] = array(
'name' => $name,
'hostname' => $result['hostname'],
'app_id' => $result['app_id'],
'device_id' => $result['device_id'],
'colours' => $highlight_colour,
'device_image' => getImageSrc($result),
'device_hardware' => $result['hardware'],
'device_os' => $config['os'][$result['os']]['text'],
'version' => $result['version'],
'location' => $result['location'],
);
}//end foreach
}//end if
$json = json_encode($device);
die($json);
}
else if ($_REQUEST['type'] == 'munin') {
// Device search
if (is_admin() === true || is_read() === true) {
$results = dbFetchRows("SELECT * FROM `munin_plugins` INNER JOIN `devices` ON devices.device_id = munin_plugins.device_id WHERE `mplug_type` LIKE '%".$search."%' OR `mplug_title` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%' ORDER BY hostname LIMIT 8");
}
else {
$results = dbFetchRows("SELECT * FROM `munin_plugins` INNER JOIN `devices` AS `D` ON `D`.`device_id` = `munin_plugins`.`device_id` INNER JOIN `devices_perms` AS `P` ON `P`.`device_id` = `D`.`device_id` WHERE `P`.`user_id` = ? AND (`mplug_type` LIKE '%".$search."%' OR `mplug_title` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%') ORDER BY hostname LIMIT 8", array($_SESSION['user_id']));
}
if (count($results)) {
$found = 1;
$devices = count($results);
foreach ($results as $result) {
$name = $result['mplug_title'];
if ($result['disabled'] == 1) {
$highlight_colour = '#808080';
}
else if ($result['ignored'] == 1 && $result['disabled'] == 0) {
$highlight_colour = '#000000';
}
else if ($result['status'] == 0 && $result['ignore'] == 0 && $result['disabled'] == 0) {
$highlight_colour = '#ff0000';
}
else if ($result['status'] == 1 && $result['ignore'] == 0 && $result['disabled'] == 0) {
$highlight_colour = '#008000';
}
$device[] = array(
'name' => $name,
'hostname' => $result['hostname'],
'device_id' => $result['device_id'],
'colours' => $highlight_colour,
'device_image' => getImageSrc($result),
'device_hardware' => $result['hardware'],
'device_os' => $config['os'][$result['os']]['text'],
'version' => $result['version'],
'location' => $result['location'],
'plugin' => $result['mplug_type'],
);
}//end foreach
}//end if
$json = json_encode($device);
die($json);
}
else if ($_REQUEST['type'] == 'iftype') {
// Device search
if (is_admin() === true || is_read() === true) {
$results = dbFetchRows("SELECT `ports`.ifType FROM `ports` WHERE `ifType` LIKE '%".$search."%' GROUP BY ifType ORDER BY ifType LIMIT 8");
}
else {
$results = dbFetchRows("SELECT `I`.ifType FROM `ports` AS `I`, `devices` AS `D`, `devices_perms` AS `P`, `ports_perms` AS `PP` WHERE ((`P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id`) OR (`PP`.`user_id` = ? AND `PP`.`port_id` = `I`.`port_id` AND `I`.`device_id` = `D`.`device_id`)) AND `D`.`device_id` = `I`.`device_id` AND (`ifType` LIKE '%".$search."%') GROUP BY ifType ORDER BY ifType LIMIT 8", array($_SESSION['user_id'], $_SESSION['user_id']));
}
if (count($results)) {
$found = 1;
$devices = count($results);
foreach ($results as $result) {
$device[] = array(
'filter' => $result['ifType'],
);
}//end foreach
}//end if
$json = json_encode($device);
die($json);
}//end if
}//end if
}//end if

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
html/images/os/fortios.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,50 @@
<?php
/*
* Copyright (C) 2015 Mark Schouten <mark@tuxis.nl>
*
* 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; version 2 dated June,
* 1991.
*
* 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.
*
* See http://www.gnu.org/licenses/gpl.txt for the full license
*/
/**
* Fetch all VM's in a Proxmox Cluster
* @param string $c Clustername
* @return array An array with all the VM's on this cluster
*/
function proxmox_cluster_vms($c) {
return dbFetchRows("SELECT * FROM proxmox WHERE cluster = ? ORDER BY vmid", array($c));
}
/**
* Fetch all VM's on a Proxmox node
* @param integer $n device_id
* @return array An array with all the VM's on this node
*/
function proxmox_node_vms($n) {
return dbFetchRows("SELECT * FROM proxmox WHERE device_id = ? ORDER BY vmid", array($n));
}
/**
* Fetch all info about a Proxmox VM
* @param integer $vmid Proxmox VM ID
* @param string $c Clustername
* @return array An array with all info of this VM on this cluster, including ports
*/
function proxmox_vm_info($vmid, $c) {
$vm = dbFetchRow("SELECT pm.*, d.hostname AS host, d.device_id FROM proxmox pm, devices d WHERE pm.device_id = d.device_id AND pm.vmid = ? AND pm.cluster = ?", array($vmid, $c));
$appid = dbFetchRow("SELECT app_id FROM applications WHERE device_id = ? AND app_type = ?", array($vm['device_id'], 'proxmox'));
$vm['ports'] = dbFetchRows("SELECT * FROM proxmox_ports WHERE vm_id = ?", array($vm['id']));
$vm['app_id'] = $appid['app_id'];
return $vm;
}

View File

@ -42,7 +42,7 @@ foreach(dbFetchRows($sql, $param) as $device) {
$temp_output[] = '<a href="' . generate_url(array(
'page' => 'device',
'device' => $device['device_id']
)) . '" role="button" class="btn ' . $btn_type . ' btn-xs" title="' . $device['hostname'] . '" style="min-height:25px; min-width:25px; border-radius:0px; margin:0; padding:0;"></a>';
)) . '" role="button" class="btn ' . $btn_type . ' btn-xs" title="' . $device['hostname'] . " - " . formatUptime($device['uptime']) . '" style="min-height:25px; min-width:25px; border-radius:0px; margin:0; padding:0;"></a>';
}
$temp_rows = count($temp_output);

View File

@ -12,6 +12,7 @@ $temp_output = '
<th>Down</th>
<th>Ignored</th>
<th>Disabled</th>
'.($config['summary_errors'] ? '<th>Errored</th>' : '').'
</tr>
</thead>
<tbody>
@ -22,6 +23,7 @@ $temp_output = '
<td><a href="devices/state=down/format=list_detail/"><span class="red"> '.$devices['down'].'</span></a></td>
<td><a href="devices/ignore=1/format=list_detail/"><span class="grey"> '.$devices['ignored'].'</span></a></td>
<td><a href="devices/disabled=1/format=list_detail/"><span class="black"> '.$devices['disabled'].'</span></a></td>
'.($config['summary_errors'] ? '<td>-</td>' : '').'
</tr>
<tr class="active">
<td><a href="ports/">Ports</a></td>
@ -30,6 +32,7 @@ $temp_output = '
<td><a href="ports/format=list_detail/state=down/"><span class="red"> '.$ports['down'].'</span></a></td>
<td><a href="ports/format=list_detail/ignore=1/"><span class="grey"> '.$ports['ignored'].'</span></a></td>
<td><a href="ports/format=list_detail/state=admindown/"><span class="black"> '.$ports['shutdown'].'</span></a></td>
'.($config['summary_errors'] ? '<td><a href="ports/format=list_detail/errors=1/"><span class="black"> '.$ports['errored'].'</span></a></td>' : '').'
</tr>';
if ($config['show_services']) {
@ -41,6 +44,7 @@ $temp_output .= '
<td><a href="services/state=down/view=details/"><span class="red"> '.$services['down'].'</span></a></td>
<td><a href="services/ignore=1/view=details/"><span class="grey"> '.$services['ignored'].'</span></a></td>
<td><a href="services/disabled=1/view=details/"><span class="black"> '.$services['disabled'].'</span></a></td>
'.($config['summary_errors'] ? '<td>-</td>' : '').'
</tr>';
}
$temp_output .= '

View File

@ -83,6 +83,21 @@ if ($config['show_services']) {
}
if ($config['summary_errors']) {
$temp_output .= '
</tr>
<tr class="active">
<th><span class="black">Errored</span></th>
<td>-</td>
<td><a href="ports/format=list_detail/errors=1/"><span class="black"> '.$ports['errored'].'</span></a></td>
';
if ($config['show_services']) {
$temp_output .= '
<td>-</td>
';
}
}
$temp_output .= '
</tr>
<tr class="active">

View File

@ -1,17 +1,18 @@
<?php
$common_output[] = '
<table id="eventlog" class="table table-hover table-condensed table-striped">
<thead>
<tr>
<th data-column-id="datetime" data-order="desc">Datetime</th>
<th data-column-id="hostname">Hostname</th>
<th data-column-id="type">Type</th>
<th data-column-id="message">Message</th>
</tr>
</thead>
</table>
<div class="table-responsive">
<table id="eventlog" class="table table-hover table-condensed table-striped">
<thead>
<tr>
<th data-column-id="datetime" data-order="desc">Datetime</th>
<th data-column-id="hostname">Hostname</th>
<th data-column-id="type">Type</th>
<th data-column-id="message">Message</th>
</tr>
</thead>
</table>
</div>
<script>
var eventlog_grid = $("#eventlog").bootgrid({

View File

@ -0,0 +1,328 @@
<?php
/* Copyright (C) 2015 Daniel Preussker, QuxLabs UG <preussker@quxlabs.com>
* 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 <http://www.gnu.org/licenses/>. */
/**
* Generic Graph 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[] = '
<form class="form" onsubmit="widget_settings(this); return false;">
<div class="form-group">
<div class="col-sm-2">
<label for="graph_type" class="control-label">Graph: </label>
</div>
<div class="col-sm-8">
<select class="form-control" name="graph_type" id="select_'.$unique_id.'" onchange="switch_'.$unique_id.'($(this).val());">';
if (empty($widget_settings['graph_type'])) {
$common_output[] = '<option disabled selected>Select a Graph</option>';
}
$sub = '';
$old = '';
foreach (array('device','port','application','munin') as $type) {
$common_output[] = '<option disabled>'.nicecase($type).':</option>';
foreach (get_graph_subtypes($type) as $avail_type) {
$display_type = is_mib_graph($type, $avail_type) ? $avail_type : nicecase($avail_type);
if( strstr($display_type,'_') ) {
$sub = explode('_',$display_type,2);
$sub = array_shift($sub);
if( $sub != $old ) {
$old = $sub;
$common_output[] = '<option disabled>&nbsp;&nbsp;&nbsp;'.nicecase($sub).':</option>';
}
$display_type = str_replace($sub.'_','',$display_type);
$space = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
} else {
$space = '&nbsp;&nbsp;&nbsp;';
}
$common_output[] = '<option value="'.$type.'_'.$avail_type.'"';
if ($type.'_'.$avail_type == $widget_settings['graph_type']) {
$common_output[] = " selected";
}
$common_output[] = '>'.$space.nicecase($display_type).'</option>';
}
$common_output[] = '<option disabled></option>';
}
$common_output[] = '
</select>
</div>
<div class="col-sm-offset-10 col-sm-2">
<div class="checkbox input-sm">
<label class="control-label">
<input type="checkbox" name="graph_legend" class="widget_setting" value="1" '.($widget_settings['graph_legend'] ? 'checked' : '').'> Legend
</label>
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="form-group">
<div class="col-sm-2">
<label for="graph_range" class="control-label">Range: </label>
</div>
<div class="col-sm-10">
<select class="form-control" name="graph_range">';
$checked = '';
foreach( array_diff_key($config['time'],array('now'=>'')) as $k=>$v ) {
if ($widget_settings['graph_range'] == $k) {
$checked = ' selected';
} else {
$checked = '';
}
$common_output[] = '<option value="'.$k.'"'.$checked.'>'.nicecase($k).'</option>';
}
$common_output[] = '
</select>
</div>
</div>
<div class="form-group input_'.$unique_id.'" id="input_'.$unique_id.'_device">
<div class="col-sm-2">
<label for="graph_device" class="control-label">Device: </label>
</div>
<div class="col-sm-10">
<input type="text" class="form-control input_'.$unique_id.'_device" name="graph_device" placeholder="Device Name" value="'.htmlspecialchars($widget_settings['graph_device']).'">
</div>
</div>
<div class="form-group input_'.$unique_id.'" id="input_'.$unique_id.'_port">
<div class="col-sm-2">
<label for="graph_port" class="control-label">Port: </label>
</div>
<div class="col-sm-10">
<input type="text" class="form-control input_'.$unique_id.'_port" name="graph_port" placeholder="Port" value="'.htmlspecialchars($widget_settings['graph_port']).'">
</div>
</div>
<div class="form-group input_'.$unique_id.'" id="input_'.$unique_id.'_application">
<div class="col-sm-2">
<label for="graph_application" class="control-label">Application: </label>
</div>
<div class="col-sm-10">
<input type="text" class="form-control input_'.$unique_id.'_application" name="graph_application" placeholder="Application" value="'.htmlspecialchars($widget_settings['graph_application']).'">
</div>
</div>
<div class="form-group input_'.$unique_id.'" id="input_'.$unique_id.'_munin">
<div class="col-sm-2">
<label for="graph_munin" class="control-label">Munin Plugin: </label>
</div>
<div class="col-sm-10">
<input type="text" class="form-control input_'.$unique_id.'_munin" name="graph_munin" placeholder="Munin Plugin" value="'.htmlspecialchars($widget_settings['graph_munin']).'">
</div>
</div>
<div class="form-group">
<div class="col-sm-2">
<button type="submit" class="btn btn-default">Set</button>
</div>
</div>
</form>
<style>
.twitter-typeahead {
width: 100%;
}
</style>
<script>
function '.$unique_id.'() {
var '.$unique_id.'_device = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace("name"),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "ajax_search.php?search=%QUERY&type=device",
filter: function (output) {
return $.map(output, function (item) {
return {
device_id: item.device_id,
device_image: item.device_image,
name: item.name,
device_os: item.device_os,
version: item.version,
device_hardware: item.device_hardware,
device_ports: item.device_ports,
location: item.location
};
});
},
wildcard: "%QUERY"
}
});
'.$unique_id.'_device.initialize();
$(".input_'.$unique_id.'_device").typeahead({
hint: true,
highlight: true,
minLength: 1,
classNames: {
menu: "typeahead-left"
}
},
{
source: '.$unique_id.'_device.ttAdapter(),
async: false,
templates: {
header: "<h5><strong>&nbsp;Devices</strong></h5>",
suggestion: Handlebars.compile(\'<p><img src="{{device_image}}" border="0"> <small><strong>{{name}}</strong> | {{device_os}} | {{version}} | {{device_hardware}} with {{device_ports}} port(s) | {{location}}</small></p>\')
}
});
var '.$unique_id.'_port = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace("port_id"),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "ajax_search.php?search=%QUERY&type=ports",
filter: function (output) {
return $.map(output, function (item) {
return {
name: item.name,
description: item.description,
hostname: item.hostname,
port_id: item.port_id
};
});
},
wildcard: "%QUERY"
}
});
'.$unique_id.'_port.initialize();
$(".input_'.$unique_id.'_port").typeahead({
hint: true,
highlight: true,
minLength: 1,
classNames: {
menu: "typeahead-left"
}
},
{
source: '.$unique_id.'_port.ttAdapter(),
async: false,
templates: {
header: "<h5><strong>&nbsp;Ports</strong></h5>",
suggestion: Handlebars.compile(\'<p><small><img src="images/icons/port.png" /> <strong>{{name}}</strong> {{hostname}} - <i>{{description}}</i></small></p>\')
}
});
var '.$unique_id.'_application = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace("app_id"),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "ajax_search.php?search=%QUERY&type=applications",
filter: function (output) {
return $.map(output, function (item) {
return {
name: item.name,
hostname: item.hostname,
app_id: item.app_id
};
});
},
wildcard: "%QUERY"
}
});
'.$unique_id.'_application.initialize();
$(".input_'.$unique_id.'_application").typeahead({
hint: true,
highlight: true,
minLength: 1,
classNames: {
menu: "typeahead-left"
}
},
{
source: '.$unique_id.'_application.ttAdapter(),
async: false,
templates: {
header: "<h5><strong>&nbsp;Applications</strong></h5>",
suggestion: Handlebars.compile(\'<p><small><img src="images/icons/port.png" /> <strong>{{name}}</strong> {{hostname}}</small></p>\')
}
});
var '.$unique_id.'_munin = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace("munin"),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "ajax_search.php?search=%QUERY&type=munin",
filter: function (output) {
return $.map(output, function (item) {
return {
desc: item.name,
name: item.plugin,
hostname: item.hostname,
plugin: item.plugin,
device_id: item.device_id,
};
});
},
wildcard: "%QUERY"
}
});
'.$unique_id.'_munin.initialize();
$(".input_'.$unique_id.'_munin").typeahead({
hint: true,
highlight: true,
minLength: 1,
classNames: {
menu: "typeahead-left"
}
},
{
source: '.$unique_id.'_munin.ttAdapter(),
async: false,
templates: {
header: "<h5><strong>&nbsp;Munin</strong></h5>",
suggestion: Handlebars.compile(\'<p><small><img src="images/icons/port.png" /> <strong>{{plugin}}</strong> {{hostname}}</small></p>\')
}
});
switch_'.$unique_id.'($("#select_'.$unique_id.'").val());
}
function switch_'.$unique_id.'(data) {
$(".input_'.$unique_id.'").fadeOut();
if (data != undefined && data != "") {
data = data.split("_");
type = data.shift();
data = data.join("_");
$("#input_'.$unique_id.'_"+type).fadeIn();
}
}
</script>
<script id="js_'.$unique_id.'">
$(function() {
$("#js_'.$unique_id.'").parent().parent().data("settings","1");
'.$unique_id.'();
});
</script>';
}
else {
$widget_settings['title'] = "";
$type = explode('_',$widget_settings['graph_type'],2);
$type = array_shift($type);
$widget_settings['graph_'.$type] = json_decode($widget_settings['graph_'.$type],true);
if ($type == 'device') {
$widget_settings['title'] = $widget_settings['graph_device']['name']." / ".$widget_settings['graph_type'];
$param = 'device='.$widget_settings['graph_device']['device_id'];
}
elseif ($type == 'application') {
$param = 'id='.$widget_settings['graph_'.$type]['app_id'];
}
elseif ($type == 'munin') {
$param = 'device='.$widget_settings['graph_'.$type]['device_id'].'&plugin='.$widget_settings['graph_'.$type]['name'];
}
else {
$param = 'id='.$widget_settings['graph_'.$type][$type.'_id'];
}
if (empty($widget_settings['title'])) {
$widget_settings['title'] = $widget_settings['graph_'.$type]['hostname']." / ".$widget_settings['graph_'.$type]['name']." / ".$widget_settings['graph_type'];
}
$common_output[] = '<img class="minigraph-image" src="graph.php?'.$param.'&from='.$config['time'][$widget_settings['graph_range']].'&to='.$config['time']['now'].'&width='.$widget_dimensions['x'].'&height='.$widget_dimensions['y'].'&type='.$widget_settings['graph_type'].'&legend='.($widget_settings['graph_legend'] == 1 ? 'yes' : 'no').'&absolute=1"/>';
}

View File

@ -1,17 +1,18 @@
<?php
$common_output[] = '
<table id="syslog" class="table table-hover table-condensed table-striped">
<thead>
<tr>
<th data-column-id="timestamp" data-order="desc">Datetime</th>
<th data-column-id="device_id">Hostname</th>
<th data-column-id="program">Program</th>
<th data-column-id="msg">Message</th>
</tr>
</thead>
</table>
<div class="table-responsive">
<table id="syslog" class="table table-hover table-condensed table-striped">
<thead>
<tr>
<th data-column-id="timestamp" data-order="desc">Datetime</th>
<th data-column-id="device_id">Hostname</th>
<th data-column-id="program">Program</th>
<th data-column-id="msg">Message</th>
</tr>
</thead>
</table>
</div>
<script>
var syslog_grid = $("#syslog").bootgrid({

View File

@ -0,0 +1,124 @@
<?php
/* Copyright (C) 2015 Sergiusz Paprzycki <serek@walcz.net>
*
* This widget is based on legacy frontpage module created by Paul Gear.
*
* 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 <http://www.gnu.org/licenses/>. */
/**
* Top devices by traffic
* @author Sergiusz Paprzycki
* @copyright 2015 Sergiusz Paprzycki <serek@walcz.net>
* @license GPL
* @package LibreNMS
* @subpackage Widgets
*/
if( defined('show_settings') || empty($widget_settings) ) {
$common_output[] = '
<form class="form" onsubmit="widget_settings(this); return false;">
<div class="form-group">
<div class="col-sm-6">
<label for="graph_type" class="control-label">Number of Devices: </label>
</div>
<div class="col-sm-4">
<input class="form-control" name="device_count" id="input_count_'.$unique_id.'" placeholder="ie. 5" value="'.$widget_settings['device_count'].'">
</div>
</div>
<div class="clearfix"></div>
<div class="form-group">
<div class="col-sm-6">
<label for="graph_type" class="control-label">Time interval (minutes): </label>
</div>
<div class="col-sm-4">
<input class="form-control" name="time_interval" id="input_time_'.$unique_id.'" placeholder="ie. 15" value="'.$widget_settings['time_interval'].'">
</div>
</div>
<div class="form-group">
<div class="col-sm-2">
<button type="submit" class="btn btn-default">Set</button>
</div>
</div>
</form>
';
}
else {
$interval = $widget_settings['time_interval'];
(integer) $interval_seconds = ($interval * 60);
(integer) $device_count = $widget_settings['device_count'];
$common_output[] = '
<h4>Top '.$device_count.' devices (last '.$interval.' minutes)</h4>
';
$params = array('user' => $_SESSION['user_id'], 'interval' => array($interval_seconds), 'count' => array($device_count));
if (is_admin() || is_read()) {
$query = '
SELECT *, sum(p.ifInOctets_rate + p.ifOutOctets_rate) as total
FROM ports as p, devices as d
WHERE d.device_id = p.device_id
AND unix_timestamp() - p.poll_time < :interval
AND ( p.ifInOctets_rate > 0
OR p.ifOutOctets_rate > 0 )
GROUP BY d.device_id
ORDER BY total desc
LIMIT :count
';
}
else {
$query = '
SELECT *, sum(p.ifInOctets_rate + p.ifOutOctets_rate) as total
FROM ports as p, devices as d, `devices_perms` AS `P`
WHERE `P`.`user_id` = :user AND `P`.`device_id` = `d`.`device_id` AND
d.device_id = p.device_id
AND unix_timestamp() - p.poll_time < :interval
AND ( p.ifInOctets_rate > 0
OR p.ifOutOctets_rate > 0 )
GROUP BY d.device_id
ORDER BY total desc
LIMIT :count
';
}
$common_output[] = '
<div class="table-responsive">
<table class="table table-hover table-condensed table-striped bootgrid-table">
<thead>
<tr>
<th class="text-left">Device</th>
<th class="text-left">Total traffic</a></th>
</tr>
</thead>
<tbody>
';
foreach (dbFetchRows($query, $params) as $result) {
$common_output[] = '
<tr>
<td class="text-left">'.generate_device_link($result, shorthost($result['hostname'])).'</td>
<td class="text-left">'.generate_device_link(
$result,
generate_minigraph_image(
$result, $config['time']['day'],
$config['time']['now'],
'device_bits',
'no', 150, 21),
array(), 0, 0, 0).'
</td>
</tr>
';
}
$common_output[] = '
</tbody>
</table>
</div>
';
}

View File

@ -0,0 +1,160 @@
<?php
/* Copyright (C) 2015 Sergiusz Paprzycki <serek@walcz.net>
*
* This widget is based on legacy frontpage module created by Paul Gear.
*
* 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 <http://www.gnu.org/licenses/>. */
/**
* Top interfaces by traffic
* @author Sergiusz Paprzycki
* @copyright 2015 Sergiusz Paprzycki <serek@walcz.net>
* @license GPL
* @package LibreNMS
* @subpackage Widgets
*/
if( defined('show_settings') || empty($widget_settings) ) {
$common_output[] = '
<form class="form-horizontal" onsubmit="widget_settings(this); return false;">
<div class="form-group">
<label for="interface_count" class="col-sm-5 control-label">Number of Interfaces: </label>
<div class="col-sm-7">
<input class="form-control" type="number" min="0" step="1" name="interface_count" id="input_count_'.$unique_id.'" placeholder="ie. 5" value="'.$widget_settings['interface_count'].'">
</div>
</div>
<div class="form-group">
<label for="time_interval" class="col-sm-5 control-label">Last Polled within (minutes): </label>
<div class="col-sm-7">
<input class="form-control" type="number" min="5" step="1" name="time_interval" id="input_time_'.$unique_id.'" placeholder="ie. 15" value="'.$widget_settings['time_interval'].'">
</div>
</div>
<div class="form-group">
<label for="interface_filter" class="col-sm-5 control-label">Interface Type: </label>
<div class="col-sm-7">
<input class="form-control" name="interface_filter" id="input_filter_'.$unique_id.'" placeholder="Any" value="'.$widget_settings['interface_filter'].'">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-5 col-sm-7">
<button type="submit" class="btn btn-default">Set</button>
</div>
</div>
</form>
<script>
$(function() {
var '.$unique_id.'_filter = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace("name"),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "ajax_search.php?search=%QUERY&type=iftype",
filter: function (output) {
return $.map(output, function (item) {
return {
filter: item.filter
};
});
},
wildcard: "%QUERY"
}
});
'.$unique_id.'_filter.initialize();
$("#input_filter_'.$unique_id.'").typeahead({
hint: true,
highlight: true,
minLength: 1,
classNames: {
menu: "typeahead-left"
}
},
{
source: '.$unique_id.'_filter.ttAdapter(),
async: false,
display: "filter",
templates: {
header: "<h5><strong>&nbsp;Interface Types</strong></h5>",
suggestion: Handlebars.compile("<p>{{filter}}</p>")
}
});
});
</script>
<style>
.twitter-typeahead {
width: 100%;
}
</style>
';
}
else {
$interval = $widget_settings['time_interval'];
(integer) $lastpoll_seconds = ($interval * 60);
(integer) $interface_count = $widget_settings['interface_count'];
$params = array('user' => $_SESSION['user_id'], 'lastpoll' => array($lastpoll_seconds), 'count' => array($interface_count), 'filter' => ($widget_settings['interface_filter']?:(int)1));
if (is_admin() || is_read()) {
$query = '
SELECT *, p.ifInOctets_rate + p.ifOutOctets_rate as total
FROM ports as p
INNER JOIN devices ON p.device_id = devices.device_id
AND unix_timestamp() - p.poll_time <= :lastpoll
AND ( p.ifType = :filter || 1 = :filter )
AND ( p.ifInOctets_rate > 0 || p.ifOutOctets_rate > 0 )
ORDER BY total DESC
LIMIT :count
';
}
else {
$query = '
SELECT ports.*, devices.hostname, ports.ifInOctets_rate + ports.ifOutOctets_rate as total
FROM ports
INNER JOIN devices ON ports.device_id = devices.device_id
LEFT JOIN ports_perms ON ports.port_id = ports_perms.port_id
LEFT JOIN devices_perms ON devices.device_id = devices_perms.device_id
WHERE ( ports_perms.user_id = :user || devices_perms.user_id = :user )
AND unix_timestamp() - ports.poll_time <= :lastpoll
AND ( ports.ifType = :filter || 1 = :filter )
AND ( ports.ifInOctets_rate > 0 || ports.ifOutOctets_rate > 0 )
GROUP BY ports.port_id
ORDER BY total DESC
LIMIT :count
';
}
$common_output[] = '
<h4>Top '.$interface_count.' interfaces polled within '.$interval.' minutes</h4>
<div class="table-responsive">
<table class="table table-hover table-condensed table-striped bootgrid-table">
<thead>
<tr>
<th class="text-left">Device</th>
<th class="text-left">Interface</th>
<th class="text-left">Total traffic</a></th>
</tr>
</thead>
<tbody>
';
foreach (dbFetchRows($query, $params) as $result) {
$common_output[] = '
<tr>
<td class="text-left">'.generate_device_link($result, shorthost($result['hostname'])).'</td>
<td class="text-left">'.generate_port_link($result).'</td>
<td class="text-left">'.generate_port_link($result, generate_port_thumbnail($result)).'</td>
</tr>
';
}
$common_output[] = '
</tbody>
</table>
</div>
';
}

View File

@ -23,19 +23,72 @@
*/
if ($config['map']['engine'] == 'leaflet') {
$temp_output = '
if ((defined('show_settings') || empty($widget_settings)) && $config['front_page'] == "pages/front/tiles.php") {
$temp_output = '
<form class="form" onsubmit="widget_settings(this); return false;">
<div class="form-group">
<div class="col-sm-4">
<label for="init_lat" class="control-label">Initial Latitude: </label>
</div>
<div class="col-sm-6">
<input class="form-control" name="init_lat" id="input_lat_'.$unique_id.'" value="'.$widget_settings['init_lat'].'" placeholder="ie. 51.4800 for Greenwich">
</div>
</div>
<div class="form-group">
<div class="col-sm-4">
<label for="init_lng" class="control-label">Initial Longitude: </label>
</div>
<div class="col-sm-6">
<input class="form-control" name="init_lng" id="input_lng_'.$unique_id.'" value="'.$widget_settings['init_lng'].'" placeholder="ie. 0 for Greenwich">
</div>
</div>
<div class="form-group">
<div class="col-sm-4">
<label for="init_zoom" class="control-label">Initial Zoom: </label>
</div>
<div class="col-sm-4">
<select class="form-control" name="init_zoom" id="select_zoom'.$unique_id.'">
';
for ($i=0; $i<19; $i++) {
if ($i == $widget_settings['init_zoom']) {
$temp_output .= '<option selected value="'.$i.'">'.$i.'</option>';
}
else {
$temp_output .= '<option value="'.$i.'">'.$i.'</option>';
}
}
$temp_output .= '
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-2">
<button type="submit" class="btn btn-default">Set</button>
</div>
</div>
</form>
';
}
else {
$temp_output = '
<script src="js/leaflet.js"></script>
<script src="js/leaflet.markercluster-src.js"></script>
<script src="js/leaflet.awesome-markers.min.js"></script>
<div id="leaflet-map"></div>
<script>
';
$map_init = "[" . $config['leaflet']['default_lat'] . ", " . $config['leaflet']['default_lng'] . "], " . sprintf("%01.0f", $config['leaflet']['default_zoom']);
$temp_output .= 'var map = L.map(\'leaflet-map\').setView('.$map_init.');
';
if (!empty($widget_settings)) {
$init_lat = $widget_settings['init_lat'];
$init_lng = $widget_settings['init_lng'];
$init_zoom = $widget_settings['init_zoom'];
}
elseif (isset($config['leaflet'])) {
$init_lat = $config['leaflet']['default_lat'];
$init_lng = $config['leaflet']['default_lng'];
$init_zoom = $config['leaflet']['default_zoom'];
}
$map_init = "[" . $init_lat . ", " . $init_lng . "], " . sprintf("%01.0f", $init_zoom);
$temp_output .= 'var map = L.map(\'leaflet-map\').setView('.$map_init.');
L.tileLayer(\'//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\', {
attribution: \'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors\'
}).addTo(map);
@ -49,24 +102,49 @@ var greenMarker = L.AwesomeMarkers.icon({
icon: \'server\',
markerColor: \'green\', prefix: \'fa\', iconColor: \'white\'
});
';
foreach (dbFetchRows("SELECT `device_id`,`hostname`,`os`,`status`,`lat`,`lng` FROM `devices` LEFT JOIN `locations` ON `devices`.`location`=`locations`.`location` WHERE `disabled`=0 AND `ignore`=0 AND `lat` != '' AND `lng` != '' ORDER BY `status` ASC, `hostname`") as $map_devices) {
$icon = 'greenMarker';
if ($map_devices['status'] == 0) {
$icon = 'redMarker';
}
$temp_output .= "var title = '<a href=\"" . generate_device_url($map_devices) . "\"><img src=\"".getImageSrc($map_devices)."\" width=\"32\" height=\"32\" alt=\"\">".$map_devices['hostname']."</a>';
var marker = L.marker(new L.LatLng(".$map_devices['lat'].", ".$map_devices['lng']."), {title: title, icon: $icon});
marker.bindPopup(title);
markers.addLayer(marker);\n";
}
$temp_output .= 'map.addLayer(markers);
';
// Checking user permissions
if (is_admin() || is_read()) {
// Admin or global read-only - show all devices
$sql = "SELECT `device_id`,`hostname`,`os`,`status`,`lat`,`lng` FROM `devices`
LEFT JOIN `locations` ON `devices`.`location`=`locations`.`location`
WHERE `disabled`=0 AND `ignore`=0 AND `lat` != '' AND `lng` != ''
ORDER BY `status` ASC, `hostname`";
}
else {
// Normal user - grab devices that user has permissions to
$sql = "SELECT `devices`.`device_id` as `device_id`,`hostname`,`os`,`status`,`lat`,`lng`
FROM `devices_perms`, `devices`
LEFT JOIN `locations` ON `devices`.`location`=`locations`.`location`
WHERE `disabled`=0 AND `ignore`=0 AND `lat` != '' AND `lng` != ''
AND `devices`.`device_id` = `devices_perms`.`device_id`
AND `devices_perms`.`user_id` = ?
ORDER BY `status` ASC, `hostname`";
}
foreach (dbFetchRows($sql, array($_SESSION['user_id'])) as $map_devices) {
$icon = 'greenMarker';
if ($map_devices['status'] == 0) {
$icon = 'redMarker';
}
$temp_output .= "var title = '<a href=\"" . generate_device_url($map_devices) . "\"><img src=\"".getImageSrc($map_devices)."\" width=\"32\" height=\"32\" alt=\"\">".$map_devices['hostname']."</a>';
var marker = L.marker(new L.LatLng(".$map_devices['lat'].", ".$map_devices['lng']."), {title: title, icon: $icon});
marker.bindPopup(title);
markers.addLayer(marker);\n";
}
$temp_output .= 'map.addLayer(markers);
map.scrollWheelZoom.disable();
$(document).ready(function(){
$("#leaflet-map").on("click", function(event) {
map.scrollWheelZoom.enable();
});
$("#leaflet-map").mouseleave(function(event) {
map.scrollWheelZoom.disable();
});
});
</script>';
} else {
}
}
else {
$temp_output = 'Mapael engine not supported here';
}

View File

@ -0,0 +1,41 @@
<?php
/* Copyright (C) 2015 Daniel Preussker, QuxLabs UG <preussker@quxlabs.com>
* 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 <http://www.gnu.org/licenses/>. */
/**
* Create Dashboards
* @author Daniel Preussker
* @copyright 2015 Daniel Preussker, QuxLabs UG
* @license GPL
* @package LibreNMS
* @subpackage Dashboards
*/
$status = 'error';
$message = 'unknown error';
if (isset($_REQUEST['dashboard_name']) && ($dash_id = dbInsert(array('dashboard_name'=>$_REQUEST['dashboard_name'],'user_id'=>$_SESSION['user_id']),'dashboards'))) {
$status = 'ok';
$message = 'Created';
}
else {
$status = 'error';
$message = 'ERROR: Could not create';
}
die(json_encode(array(
'status' => $status,
'message' => $message,
'dashboard_id' => $dash_id
)));

View File

@ -52,7 +52,7 @@ if(!empty($name)) {
elseif( $_REQUEST['template'] && is_numeric($_REQUEST['template_id']) ) {
//Update template-text
if($ret = dbUpdate(array('template' => $_REQUEST['template'], 'name' => $name), "alert_templates", "id = ?", array($_REQUEST['template_id']))) {
if($ret = dbUpdate(array('template' => $_REQUEST['template'], 'name' => $name, 'title' => $_REQUEST['title'], 'title_rec' => $_REQUEST['title_rec']), "alert_templates", "id = ?", array($_REQUEST['template_id']))) {
$ok = "Updated template";
}
else {
@ -62,7 +62,7 @@ if(!empty($name)) {
elseif( $_REQUEST['template'] ) {
//Create new template
if(dbInsert(array('template' => $_REQUEST['template'], 'name' => $name), "alert_templates")) {
if(dbInsert(array('template' => $_REQUEST['template'], 'name' => $name, 'title' => $_REQUEST['title'], 'title_rec' => $_REQUEST['title_rec']), "alert_templates")) {
$ok = "Alert template has been created.";
}
else {

View File

@ -0,0 +1,45 @@
<?php
/* Copyright (C) 2015 Daniel Preussker, QuxLabs UG <preussker@quxlabs.com>
* 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 <http://www.gnu.org/licenses/>. */
/**
* Delete Dashboards
* @author Daniel Preussker
* @copyright 2015 Daniel Preussker, QuxLabs UG
* @license GPL
* @package LibreNMS
* @subpackage Dashboards
*/
$status = 'error';
$message = 'unknown error';
if (isset($_REQUEST['dashboard_id'])) {
dbDelete('users_widgets','user_id = ? && dashboard_id = ?',array($_SESSION['user_id'],$_REQUEST['dashboard_id']));
if (dbDelete('dashboards','user_id = ? && dashboard_id = ?',array($_SESSION['user_id'],$_REQUEST['dashboard_id']))) {
$status = 'ok';
$message = 'Deleted dashboard';
}
else {
$message = 'ERROR: Could not delete dashboard '.$_REQUEST['dashboard_id'];
}
}
else {
$message = 'ERROR: Not enough params';
}
die(json_encode(array(
'status' => $status,
'message' => $message,
)));

View File

@ -0,0 +1,44 @@
<?php
/* Copyright (C) 2015 Daniel Preussker, QuxLabs UG <preussker@quxlabs.com>
* 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 <http://www.gnu.org/licenses/>. */
/**
* Edit Dashboards
* @author Daniel Preussker
* @copyright 2015 Daniel Preussker, QuxLabs UG
* @license GPL
* @package LibreNMS
* @subpackage Dashboards
*/
$status = 'error';
$message = 'unknown error';
if (isset($_REQUEST['dashboard_id']) && isset($_REQUEST['dashboard_name']) && isset($_REQUEST['access'])) {
if(dbUpdate(array('dashboard_name'=>$_REQUEST['dashboard_name'],'access'=>$_REQUEST['access']),'dashboards','(user_id = ? || access = 2) && dashboard_id = ?',array($_SESSION['user_id'],$_REQUEST['dashboard_id']))) {
$status = 'ok';
$message = 'Updated dashboard';
}
else {
$message = 'ERROR: Could not update dashboard '.$_REQUEST['dashboard_id'];
}
}
else {
$message = 'ERROR: Not enough params';
}
die(json_encode(array(
'status' => $status,
'message' => $message,
)));

View File

@ -21,8 +21,10 @@ $template_id = ($_POST['template_id']);
if (is_numeric($template_id) && $template_id > 0) {
$template = dbFetchRow('SELECT * FROM `alert_templates` WHERE `id` = ? LIMIT 1', array($template_id));
$output = array(
'template' => $template['template'],
'name' => $template['name'],
'template' => $template['template'],
'name' => $template['name'],
'title' => $template['title'],
'title_rec' => $template['title_rec'],
);
echo _json_encode($output);
}

View File

@ -18,31 +18,32 @@ if (is_admin() === false) {
$transport = mres($_POST['transport']);
require_once $config['install_dir'].'/includes/alerts.inc.php';
$tmp = array(dbFetchRow('select device_id,hostname from devices order by device_id asc limit 1'));
$tmp['contacts'] = GetContacts($tmp);
$obj = array(
'contacts' => $config['alert']['default_mail'],
'title' => 'Testing transport from ' . $config['project_name'],
'msg' => 'This is a test alert',
'severity' => 'critical',
'state' => 'critical',
'hostname' => 'testing',
'name' => 'Testing rule',
"hostname" => $tmp[0]['hostname'],
"device_id" => $tmp[0]['device_id'],
"title" => "Testing transport from ".$config['project_name'],
"elapsed" => "11s",
"id" => "000",
"faults" => false,
"uid" => "000",
"severity" => "critical",
"rule" => "%macros.device = 1",
"name" => "Test-Rule",
"timestamp" => date("Y-m-d H:i:s"),
"contacts" => $tmp['contacts'],
"state" => "1",
"msg" => "This is a test alert",
);
unset($obj);
$obj['contacts'] = 'test';
$obj['title'] = 'test';
$obj['msg'] = 'test';
$obj['severity'] = 'test';
$obj['state'] = 'test';
$obj['hostname'] = 'test';
$obj['name'] = 'test';
$status = 'error';
if (file_exists($config['install_dir']."/includes/alerts/transport.$transport.php")) {
if (file_exists($config['install_dir']."/includes/alerts/transport.".$transport.".php")) {
$opts = $config['alert']['transports'][$transport];
if ($opts) {
eval('$tmp = function($obj,$opts) { global $config; '.file_get_contents($config['install_dir'].'/includes/alerts/transport.'.$transport.'.php').' };');
eval('$tmp = function($obj,$opts) { global $config; '.file_get_contents($config['install_dir'].'/includes/alerts/transport.'.$transport.'.php').' return false; };');
$tmp = $tmp($obj,$opts);
if ($tmp) {
$status = 'ok';

View File

@ -6,49 +6,65 @@ $message = 'Error updating user dashboard config';
$data = json_decode($_POST['data'],true);
$sub_type = mres($_POST['sub_type']);
$widget_id = mres($_POST['widget_id']);
$dasboard_id = mres($_POST['dashboard_id']);
if ($sub_type == 'remove' && is_numeric($widget_id)) {
if ($widget_id == 0 || dbDelete('users_widgets','`user_id`=? AND `user_widget_id`=?', array($_SESSION['user_id'],$widget_id))) {
$status = 'ok';
$message = '';
if (dbFetchCell('select 1 from dashboards where (user_id = ? || access = 2) && dashboard_id = ?',array($_SESSION['user_id'],$dasboard_id)) == 1) {
if ($widget_id == 0 || dbDelete('users_widgets','`user_widget_id`=? AND `dashboard_id`=?', array($widget_id,$dasboard_id))) {
$status = 'ok';
$message = '';
}
}
else {
$status = 'error';
$message = 'ERROR: You have no write access.';
}
}
elseif ($sub_type == 'remove-all') {
if (dbDelete('users_widgets','`user_id`=?', array($_SESSION['user_id']))) {
$status = 'ok';
$message = '';
if (dbFetchCell('select 1 from dashboards where (user_id = ? || access = 2) && dashboard_id = ?',array($_SESSION['user_id'],$dasboard_id)) == 1) {
if (dbDelete('users_widgets','`dashboard_id`=?', array($dasboard_id))) {
$status = 'ok';
$message = '';
}
}
else {
$status = 'error';
$message = 'ERROR: You have no write access.';
}
}
elseif ($sub_type == 'add' && is_numeric($widget_id)) {
$dupe_check = dbFetchCEll('SELECT `user_widget_id` FROM `users_widgets` WHERE `user_id`=? AND `widget_id`=?',array($_SESSION['user_id'],$widget_id));
if (is_numeric($dupe_check)) {
$message = 'This widget has already been added';
}
else {
if (dbFetchCell('select 1 from dashboards where (user_id = ? || access = 2) && dashboard_id = ?',array($_SESSION['user_id'],$dasboard_id)) == 1) {
$widget = dbFetchRow('SELECT * FROM `widgets` WHERE `widget_id`=?', array($widget_id));
if (is_array($widget)) {
list($x,$y) = explode(',',$widget['base_dimensions']);
$item_id = dbInsert(array('user_id'=>$_SESSION['user_id'],'widget_id'=>$widget_id, 'col'=>1,'row'=>1,'refresh'=>60,'title'=>$widget['widget_title'],'size_x'=>$x,'size_y'=>$y),'users_widgets');
$item_id = dbInsert(array('user_id'=>$_SESSION['user_id'],'widget_id'=>$widget_id, 'col'=>1,'row'=>1,'refresh'=>60,'title'=>$widget['widget_title'],'size_x'=>$x,'size_y'=>$y,'settings'=>'','dashboard_id'=>$dasboard_id),'users_widgets');
if (is_numeric($item_id)) {
$extra = array('widget_id'=>$item_id,'title'=>$widget['widget_title'],'widget'=>$widget['widget'],'size_x'=>$x,'size_y'=>$y);
$extra = array('user_widget_id'=>$item_id,'widget_id'=>$item_id,'title'=>$widget['widget_title'],'widget'=>$widget['widget'],'refresh'=>60,'size_x'=>$x,'size_y'=>$y);
$status = 'ok';
$message = '';
}
}
}
else {
$status = 'error';
$message = 'ERROR: You have no write access.';
}
}
else {
$status = 'ok';
$message = '';
foreach ($data as $line) {
if (is_array($line)) {
$update = array('col'=>$line['col'],'row'=>$line['row'],'size_x'=>$line['size_x'],'size_y'=>$line['size_y']);
dbUpdate($update, 'users_widgets', '`user_widget_id`=?', array($line['id']));
if (dbFetchCell('select 1 from dashboards where (user_id = ? || access = 2) && dashboard_id = ?',array($_SESSION['user_id'],$dasboard_id)) == 1) {
$status = 'ok';
$message = '';
foreach ($data as $line) {
if (is_array($line)) {
$update = array('col'=>$line['col'],'row'=>$line['row'],'size_x'=>$line['size_x'],'size_y'=>$line['size_y']);
dbUpdate($update, 'users_widgets', '`user_widget_id`=? AND `dashboard_id`=?', array($line['id'],$dasboard_id));
}
}
}
else {
$status = 'error';
$message = 'ERROR: You have no write access.';
}
}
$response = array(

View File

@ -0,0 +1,48 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
*
* 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.
*/
$status = 'error';
$descr = mres($_POST['descr']);
$device_id = mres($_POST['device_id']);
$ifName = mres($_POST['ifName']);
$port_id = mres($_POST['port_id']);
logfile($descr . ','. $device_id . ','. $ifName. ','. $port_id);
if (!empty($ifName) && is_numeric($port_id)) {
// We have ifName and port id so update ifAlias
if (empty($descr)) {
$descr = 'repoll';
// Set to repoll so we avoid using ifDescr on port poll
}
if (dbUpdate(array('ifAlias'=>$descr), 'ports', '`port_id`=?', array($port_id)) > 0) {
$device = device_by_id_cache($device_id);
if ($descr === 'repoll') {
del_dev_attrib($device, 'ifName');
}
else {
set_dev_attrib($device, 'ifName', $ifName);
}
$status = 'ok';
}
else {
$status = 'na';
}
}
$response = array(
'status' => $status,
);
echo _json_encode($response);

View File

@ -0,0 +1,32 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2015 Søren Friis Rosiak <sorenrosiak@gmail.com>
* 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.
*/
$status = 'error';
$message = 'unknown error';
$device_id = mres($_POST['device_id']);
$notes = mres($_POST['notes']);
if (isset($notes) && (dbUpdate(array('notes' => $notes), 'devices', 'device_id = ?', array($device_id)))) {
$status = 'ok';
$message = 'Updated';
}
else {
$status = 'error';
$message = 'ERROR: Could not update';
}
die(json_encode(array(
'status' => $status,
'message' => $message,
'notes' => $notes,
'device_id' => $device_id
)));

View File

@ -0,0 +1,57 @@
<?php
/* Copyright (C) 2015 Daniel Preussker, QuxLabs UG <preussker@quxlabs.com>
* 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 <http://www.gnu.org/licenses/>. */
/**
* Store per-widget settings
* @author Daniel Preussker
* @copyright 2015 Daniel Preussker, QuxLabs UG
* @license GPL
* @package LibreNMS
* @subpackage Widgets
*/
$status = 'error';
$message = 'unknown error';
$widget_id = (int) $_REQUEST['id'];
if ($widget_id < 1) {
$status = 'error';
$message = 'ERROR: malformed widget ID.';
}
else {
$widget_settings = $_REQUEST['settings'];
if (!is_array($widget_settings)) {
$widget_settings = array();
}
if (dbFetchCell('select 1 from users_widgets inner join dashboards on users_widgets.dashboard_id = dashboards.dashboard_id where user_widget_id = ? && (users_widgets.user_id = ? || dashboards.access = 2)',array($widget_id,$_SESSION['user_id'])) == 1) {
if (dbUpdate(array('settings'=>json_encode($widget_settings)),'users_widgets','user_widget_id=?',array($widget_id))) {
$status = 'ok';
$message = 'Updated';
}
else {
$status = 'error';
$message = 'ERROR: Could not update';
}
}
else {
$status = 'error';
$message = 'ERROR: You have no write-access to this dashboard';
}
}
die(json_encode(array(
'status' => $status,
'message' => $message
)));

View File

@ -12,6 +12,35 @@
* @copyright (C) 2013 LibreNMS Group
*/
/**
* Compare $t with the value of $vars[$v], if that exists
* @param string $v Name of the var to test
* @param string $t Value to compare $vars[$v] to
* @return boolean true, if values are the same, false if $vars[$v] is unset or values differ
*/
function var_eq($v, $t) {
global $vars;
if (isset($vars[$v]) && $vars[$v] == $t) {
return true;
}
return false;
}
/**
* Get the value of $vars[$v], if it exists
* @param string $v Name of the var to get
* @return string|boolean The value of $vars[$v] if it exists, false if it does not exist
*/
function var_get($v) {
global $vars;
if (isset($vars[$v])) {
return $vars[$v];
}
return false;
}
function data_uri($file, $mime) {
$contents = file_get_contents($file);
@ -152,8 +181,8 @@ function get_percentage_colours($percentage) {
}//end get_percentage_colours()
function generate_minigraph_image($device, $start, $end, $type, $legend='no', $width=275, $height=100, $sep='&amp;', $class='minigraph-image') {
return '<img class="'.$class.'" src="graph.php?'.implode($sep, array('device='.$device['device_id'], "from=$start", "to=$end", "width=$width", "height=$height", "type=$type", "legend=$legend")).'">';
function generate_minigraph_image($device, $start, $end, $type, $legend='no', $width=275, $height=100, $sep='&amp;', $class='minigraph-image',$absolute_size=0) {
return '<img class="'.$class.'" src="graph.php?'.implode($sep, array('device='.$device['device_id'], "from=$start", "to=$end", "width=$width", "height=$height", "type=$type", "legend=$legend", "absolute=$absolute_size")).'">';
}//end generate_minigraph_image()

View File

@ -3,7 +3,12 @@
if (is_numeric($vars['id']) && ($auth || application_permitted($vars['id']))) {
$app = get_application_by_id($vars['id']);
$device = device_by_id_cache($app['device_id']);
$title = generate_device_link($device);
$title .= $graph_subtype;
if ($app['app_type'] != 'proxmox') {
$title = generate_device_link($device);
$title .= $graph_subtype;
}
else {
$title = $vars['port'].'@'.$vars['hostname'].' on '.generate_device_link($device);
}
$auth = true;
}

View File

@ -0,0 +1,30 @@
<?php
/*
* Copyright (C) 2015 Mark Schouten <mark@tuxis.nl>
*
* 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; version 2 dated June,
* 1991.
*
* 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.
*
* See http://www.gnu.org/licenses/gpl.txt for the full license
*/
require 'includes/graphs/common.inc.php';
$proxmox_rrd = $config['rrd_dir'].'/proxmox/'.$vars['cluster'].'/'.$vars['vmid'].'_netif_'.$vars['port'].'.rrd';
if (is_file($proxmox_rrd)) {
$rrd_filename = $proxmox_rrd;
}
$ds_in = 'INOCTETS';
$ds_out = 'OUTOCTETS';
require 'includes/graphs/generic_data.inc.php';

View File

@ -103,3 +103,7 @@ else {
}
$rrd_options .= ' --font-render-mode normal';
if (isset($_GET['absolute']) && $_GET['absolute'] == "1") {
$rrd_options .= ' --full-size-mode';
}

View File

@ -51,6 +51,8 @@ if(is_admin() === false) {
<textarea class="form-control" id="template" name="template" rows="15"></textarea><br /><br />
<strong><em>Give your template a name: </em></strong><br />
<input type="text" class="form-control input-sm" id="name" name="name"><br />
<em>Optionally, add custom titles: </em><br />
<input type="text" class="form-control input-sm" id="title" name="title" placeholder="Alert Title"><input type="text" class="form-control input-sm" id="title_rec" name="title_rec" placeholder="Recovery Title"><br />
<span id="error"></span><br />
<button type="button" class="btn btn-primary btn-sm" name="create-template" id="create-template">Create template</button>
</div>
@ -113,6 +115,8 @@ $('#alert-template').on('show.bs.modal', function (event) {
success: function(output) {
$('#template').val(output['template']);
$('#name').val(output['name']);
$('#title').val(output['title']);
$('#title_rec').val(output['title_rec']);
}
});
}
@ -123,10 +127,12 @@ $('#create-template').click('', function(e) {
var template = $("#template").val();
var template_id = $("#template_id").val();
var name = $("#name").val();
var title = $("#title").val();
var title_rec = $("#title_rec").val();
$.ajax({
type: "POST",
url: "ajax_form.php",
data: { type: "alert-templates", template: template , name: name, template_id: template_id},
data: { type: "alert-templates", template: template , name: name, template_id: template_id, title: title, title_rec: title_rec},
dataType: "html",
success: function(msg){
if(msg.indexOf("ERROR:") <= -1) {

View File

@ -107,7 +107,7 @@ echo '<div class="table-responsive">
echo '<td colspan="7">';
if ($_SESSION['userlevel'] >= '10') {
echo '<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#create-alert" data-device_id="'.$device['device_id'].'">Create new alert rule</button>';
echo '<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#create-alert" data-device_id="'.$device['device_id'].'"><i class="fa fa-plus"></i> Create new alert rule</button>';
}
echo '</td>

View File

@ -233,7 +233,7 @@ if (strpos($port['label'], 'oopback') === false && !$graph_type) {
}//end foreach
}//end if
if ($port_details && $config['enable_port_relationship'] === true) {
if ($port_details && $config['enable_port_relationship'] === true && port_permitted($int_link,$device['device_id'])) {
foreach ($int_links as $int_link) {
$link_if = dbFetchRow('SELECT * from ports AS I, devices AS D WHERE I.device_id = D.device_id and I.port_id = ?', array($int_link));
@ -263,7 +263,7 @@ if (strpos($port['label'], 'oopback') === false && !$graph_type) {
// unset($int_links, $int_links_v6, $int_links_v4, $int_links_phys, $br);
}//end if
if ($port_details && $config['enable_port_relationship'] === true) {
if ($port_details && $config['enable_port_relationship'] === true && port_permitted($port['port_id'], $device['device_id'])) {
foreach (dbFetchRows('SELECT * FROM `pseudowires` WHERE `port_id` = ?', array($port['port_id'])) as $pseudowire) {
// `port_id`,`peer_device_id`,`peer_ldp_id`,`cpwVcID`,`cpwOid`
$pw_peer_dev = dbFetchRow('SELECT * FROM `devices` WHERE `device_id` = ?', array($pseudowire['peer_device_id']));

View File

@ -89,6 +89,15 @@ if (isset($config['graylog']['server']) && isset($config['graylog']['port'])) {
?>
<li><a href="<?php echo(generate_url(array('page'=>'inventory'))); ?>"><i class="fa fa-cube fa-fw fa-lg"></i> Inventory</a></li>
<?php
if ( dbFetchCell("SELECT 1 from `packages` LIMIT 1") ) {
?>
<li>
<a href="<?php echo(generate_url(array('page'=>'search','search'=>'packages'))); ?>"><i class="fa fa-archive fa-fw fa-lg fa-nav-icons"></i> Packages</a>
</li>
<?php
} # if ($packages)
?>
<li role="presentation" class="divider"></li>
<li role="presentation" class="dropdown-header"> Search</li>
<li><a href="<?php echo(generate_url(array('page'=>'search','search'=>'ipv4'))); ?>"><i class="fa fa-search fa-fw fa-lg"></i> IPv4 Search</a></li>
@ -351,21 +360,32 @@ foreach (array_keys($menu_sensors) as $item) {
</li>
<?php
$app_count = dbFetchCell("SELECT COUNT(`app_id`) FROM `applications`");
$app_list = dbFetchRows("SELECT DISTINCT(`app_type`) AS `app_type` FROM `applications` ORDER BY `app_type`");
if ($_SESSION['userlevel'] >= '5' && ($app_count) > "0") {
if ($_SESSION['userlevel'] >= '5' && count($app_list) > "0") {
?>
<li class="dropdown">
<a href="apps/" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><i class="fa fa-tasks fa-fw fa-lg fa-nav-icons"></i> Apps</a>
<ul class="dropdown-menu">
<?php
$app_list = dbFetchRows("SELECT `app_type` FROM `applications` GROUP BY `app_type` ORDER BY `app_type`");
foreach ($app_list as $app) {
if (isset($app['app_type'])) {
$app_i_list = dbFetchRows("SELECT DISTINCT(`app_instance`) FROM `applications` WHERE `app_type` = ? ORDER BY `app_instance`", array($app['app_type']));
$image = $config['html_dir']."/images/icons/".$app['app_type'].".png";
$icon = (file_exists($image) ? $app['app_type'] : "apps");
echo('<li><a href="apps/app='.$app['app_type'].'/"><i class="fa fa-angle-double-right fa-fw fa-lg"></i> '.nicecase($app['app_type']).' </a></li>');
if (count($app_i_list) > 1) {
echo '<li class="dropdown-submenu">';
echo '<a href="apps/app='.$app['app_type'].'/"><i class="fa fa-server fa-fw fa-lg"></i> '.nicecase($app['app_type']).' </a>';
echo '<ul class="dropdown-menu scrollable-menu">';
foreach ($app_i_list as $instance) {
echo ' <li><a href="apps/app='.$app['app_type'].'/instance='.$instance['app_instance'].'/"><i class="fa fa-angle-double-right fa-fw fa-lg"></i> ' . nicecase($instance['app_instance']) . '</a></li>';
}
echo '</ul></li>';
}
else {
echo('<li><a href="apps/app='.$app['app_type'].'/"><i class="fa fa-angle-double-right fa-fw fa-lg"></i> '.nicecase($app['app_type']).' </a></li>');
}
}
}
?>
@ -427,14 +447,6 @@ if ($_SESSION['userlevel'] >= '5' && ($routing_count['bgp']+$routing_count['ospf
<?php
}
if ( dbFetchCell("SELECT 1 from `packages` LIMIT 1") ) {
?>
<li>
<a href="<?php echo(generate_url(array('page'=>'search','search'=>'packages'))); ?>"><i class="fa fa-archive fa-fw fa-lg fa-nav-icons"></i> Packages</a>
</li>
<?php
} # if ($packages)
?>
<li class="dropdown">
@ -497,7 +509,7 @@ if ($_SESSION['userlevel'] >= '10') {
<li class="dropdown-submenu">
<a href="#"><i class="fa fa-clock-o fa-fw fa-lg"></i> Pollers</a>
<ul class="dropdown-menu scrollable-menu">
<li><a href="poll-log/"><i class="fa fa-exclamation fa-fw fa-lg"></i> Poll-log</a></li>');
<li><a href="poll-log/"><i class="fa fa-list-alt fa-fw fa-lg"></i> Poll-log</a></li>');
if($config['distributed_poller'] === TRUE) {
echo ('

View File

@ -64,7 +64,7 @@ foreach (dbFetchRows($sql, $param) as $port) {
<input type="hidden" name="olddis_'.$port['port_id'].'" value="'.($port['disabled'] ? 1 : 0).'"">',
'ignore' => '<input type="checkbox" class="ignore-check" name="ignore_'.$port['port_id'].'"'.($port['ignore'] ? 'checked' : '').'>
<input type="hidden" name="oldign_'.$port['port_id'].'" value="'.($port['ignore'] ? 1 : 0).'"">',
'ifAlias' => $port['ifAlias']
'ifAlias' => '<div class="form-group"><input class="form-control input-sm" id="if-alias" name="if-alias" data-device_id="'.$port['device_id'].'" data-port_id="'.$port['port_id'].'" data-ifName="'.$port['ifName'].'" value="'.$port['ifAlias'].'"><span class="glyphicon form-control-feedback" aria-hidden="true"></span></div>'
);
}//end foreach

View File

@ -1,4 +1,10 @@
<?php
session_start();
if( empty($_POST) && !empty($_SESSION) && !isset($_REQUEST['stage'])) {
$_POST = $_SESSION;
} else {
$_SESSION = $_POST;
}
$stage = $_POST['stage'];
@ -11,13 +17,13 @@ if(file_exists('../config.php') && $stage != "6") {
// List of php modules we expect to see
$modules = array('gd','mysql','snmp','mcrypt');
$dbhost = $_POST['dbhost'] ?: 'localhost';
$dbuser = $_POST['dbuser'] ?: 'librenms';
$dbpass = $_POST['dbpass'] ?: '';
$dbname = $_POST['dbname'] ?: 'librenms';
$add_user = $_POST['add_user'] ?: '';
$add_pass = $_POST['add_pass'] ?: '';
$add_email = $_POST['add_email'] ?: '';
$dbhost = @$_POST['dbhost'] ?: 'localhost';
$dbuser = @$_POST['dbuser'] ?: 'librenms';
$dbpass = @$_POST['dbpass'] ?: '';
$dbname = @$_POST['dbname'] ?: 'librenms';
$add_user = @$_POST['add_user'] ?: '';
$add_pass = @$_POST['add_pass'] ?: '';
$add_email = @$_POST['add_email'] ?: '';
if($stage == "4" || $stage == "3") {
// Ok now let's set the db connection up
@ -28,6 +34,7 @@ if($stage == "4" || $stage == "3") {
}
require '../includes/defaults.inc.php';
$config['db']['extension']='mysqli';
// Work out the install directory
$cur_dir = explode('/',__DIR__);
$check = end($cur_dir);
@ -46,28 +53,29 @@ require '../includes/functions.php';
require 'includes/functions.inc.php';
// Check we can connect to MySQL DB, if not, back to stage 1 :)
if($stage == 2) {
$test_db = mysqli_connect($dbhost,$dbuser,$dbpass,$dbname);
if($stage == 2 || $stage == 3) {
$database_link = mysqli_connect('p:'.$dbhost,$dbuser,$dbpass,$dbname);
if(mysqli_connect_error()) {
$stage = 1;
$msg = "Couldn't connect to the database, please check your details<br /> " . mysqli_connect_error();
}
else {
$sql = "SELECT * FROM users LIMIT 1";
if(mysqli_query($test_db,$sql)) {
$stage = 3;
$msg = "It appears that the database is already setup so have moved onto stage $stage";
elseif ($stage != 3) {
if($_SESSION['build-ok'] == true) {
$stage = 3;
$msg = "It appears that the database is already setup so have moved onto stage $stage";
}
}
$_SESSION['stage'] = $stage;
}
elseif($stage == "4") {
// Now check we have a username, password and email before adding new user
if(empty($add_user) || empty($add_pass) || empty($add_email)) {
$stage = 4;
$stage = 3;
$msg = "You haven't entered enough information to add the user account, please check below and re-try";
}
}
elseif($stage == "6") {
session_destroy();
// If we get here then let's do some final checks.
if(!file_exists("../config.php")) {
// config.php file doesn't exist. go back to that stage
@ -309,7 +317,20 @@ elseif($stage == "2") {
$config['db_name']=$dbname;
$config['db']['extension']='mysqli';
$sql_file = '../build.sql';
require '../build-base.php';
$_SESSION['last'] = time();
ob_end_flush();
ob_start();
if ($_SESSION['offset'] < 100 && $_REQUEST['offset'] < 94) {
require '../build-base.php';
}
else {
require '../includes/sql-schema/update.php';
}
$_SESSION['out'] .= ob_get_clean();
ob_end_clean();
ob_start();
echo $GLOBALS['refresh'];
echo "<pre>".trim($_SESSION['out'])."</pre>";
?>
</div>
<div class="col-md-3">

View File

@ -1,4 +1,5 @@
<?php
$pagetitle[] = 'About';
$git_log = `git log -10`;
?>
<div class="modal fade" id="git_log" tabindex="-1" role="dialog" aria-labelledby="git_log_label" aria-hidden="true">

View File

@ -221,7 +221,8 @@ if ($config['distributed_poller'] === true) {
}//end if
?>
<button type="submit" class="btn btn-default input-sm" name="Submit">Add Host</button>
<hr>
<center><button type="submit" class="btn btn-default" name="Submit">Add Device</button></center>
</div>
</form>
</div>

View File

@ -10,6 +10,7 @@ else if ($_SESSION['userlevel'] == 11) {
}
else {
echo '<h3>Add User</h3>';
echo '<hr>';
$pagetitle[] = 'Add user';
@ -37,7 +38,6 @@ else {
echo '<div class="red">Please enter a username!</div>';
}//end if
}//end if
echo "<form method='post' action='adduser/' class='form-horizontal' role='form'> <input type='hidden' value='add' name='action'>";
echo "
<div class='form-group'>
@ -89,22 +89,25 @@ else {
<option value='10'>Administrator</option>
<option value='11'>Demo account</option>
</select>
<div class='checkbox'>
<label>
<input type='checkbox' checked='checked' name='can_modify_passwd'> Allow the user to change his password.
</label>
</div>
<hr>
<center><button type='submit' class='btn btn-default'>Add User</button></center>
</div>
<div class='col-sm-6'>
</div>
</div>";
echo "<div class='form-group'>
<div class='col-sm-6'>
<div class='checkbox'>
<label>
<input type='checkbox' checked='checked' name='can_modify_passwd'> Allow the user to change his password.
</label>
</div>
</div>
<div class='col-sm-6'>
</div>
</div>";
echo "<button type='submit' class='btn btn-default'>Add</button>";
echo '</form>';
}
else {

View File

@ -79,7 +79,7 @@ foreach (dbFetchRows("SELECT user_id,username FROM `users` WHERE `level` >= '10'
</div>
<div class="modal-footer">
<div class="form-group">
<div class="col-sm-4">
<div class="pull-right">
<input type="hidden" name="type" id="type" value="token-item-create">
<button type="submit" class="btn btn-success" name="token-create" id="token-create">Create API Token</button>
</div>
@ -105,18 +105,13 @@ if ($_SESSION['api_token'] === true) {
}
echo '
<div class="row">
<div class="col-sm-2">
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#create-token">Create API access token</button>
</div>
</div>
<h3>API Access</h3>
<hr>
<div class="row">
<div class="col-sm-12">
&nbsp;
</div>
</div>
<div class="row">
<div class="col-sm-6">
<table class="table table-bordered table-condensed">
<tr>
<th>User</th>
@ -134,22 +129,22 @@ foreach (dbFetchRows('SELECT `AT`.*,`U`.`username` FROM `api_tokens` AS AT JOIN
else {
$api_disabled = '';
}
echo '
<tr id="'.$api['id'].'">
<td>'.$api['username'].'</td>
<td>'.$api['token_hash'].'</td>
<td>'.$api['description'].'</td>
<td><input type="checkbox" name="token-status" data-token_id="'.$api['id'].'" data-off-text="No" data-on-text="Yes" data-on-color="danger" '.$api_disabled.' data-size="mini"></td>
<td><button type="button" class="btn btn-primary btn-xs" id="'.$api['id'].'" data-token_id="'.$api['id'].'" data-toggle="modal" data-target="#confirm-delete">Delete</button></td>
<td><button type="button" class="btn btn-danger btn-xs" id="'.$api['id'].'" data-token_id="'.$api['id'].'" data-toggle="modal" data-target="#confirm-delete">Delete</button></td>
</tr>
';
}
echo '
</table>
</div>
</div>
<center>
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#create-token">Create API access token</button>
</center>
';
?>
<script>

View File

@ -0,0 +1,68 @@
<?php
require_once('includes/application/proxmox.inc.php');
$graphs['proxmox'] = array(
'netif'
);
$pmxcl = dbFetchRows("SELECT DISTINCT(`app_instance`) FROM `applications` WHERE `app_type` = ?", array('proxmox'));
print_optionbar_start();
echo "<span style='font-weight: bold;'>Proxmox Clusters</span> &#187; ";
unset($sep);
foreach ($pmxcl as $pmxc) {
if (isset($sep)) {
echo $sep;
};
if (var_eq('instance', $pmxc['app_instance']) || (!isset($vars['instance']) && !isset($sep))) {
echo "<span class='pagemenu-selected'>";
}
echo generate_link(nicecase($pmxc['app_instance']), array('page' => 'apps', 'app' => 'proxmox', 'instance' => $pmxc['app_instance']));
if (var_eq('instance', $pmxc['app_instance'])) {
echo '</span>';
}
$sep = ' | ';
}
print_optionbar_end();
$pagetitle[] = 'Proxmox';
$pagetitle[] = $instance;
if (!isset($vars['instance'])) {
$instance = $pmxcl[0]['app_instance'];
}
else {
$instance = var_get('instance');
}
if (isset($vars['vmid'])) {
include("pages/apps/proxmox/vm.inc.php");
$pagetitle[] = $vars['vmid'];
}
else {
echo '
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="row">';
foreach (proxmox_cluster_vms($instance) as $pmxvm) {
echo '
<div class="col-sm-4 col-md-3 col-lg-2">'.generate_link($pmxvm['vmid']." (".$pmxvm['description'].")", array('page' => 'apps', 'app' => 'proxmox', 'instance' => $instance, 'vmid' => $pmxvm['vmid'])).'</div>';
}
echo '
</div>
</div>
</div>
</div>
';
}

View File

@ -0,0 +1,32 @@
<?php
$vm = proxmox_vm_info(var_get('vmid'), var_get('instance'));
$graphs = array(
'proxmox_traffic' => 'Traffic',
);
foreach ($vm['ports'] as $port) {
foreach ($graphs as $key => $text) {
$graph_type = 'proxmox_traffic';
$graph_array['height'] = '100';
$graph_array['width'] = '215';
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $vm['app_id'];
$graph_array['device_id'] = $vm['device_id'];
$graph_array['type'] = 'application_'.$key;
$graph_array['port'] = $port['port'];
$graph_array['vmid'] = $vm['vmid'];
$graph_array['cluster'] = $vm['cluster'];
$graph_array['hostname'] = $vm['description'];
echo '<h3>'.$text.' '.$port['port'].'@'.$vm['description'].'</h3>';
echo "<tr bgcolor='$row_colour'><td colspan=5>";
include 'includes/print-graphrow.inc.php';
echo '</td></tr>';
}
}

View File

@ -1,5 +1,6 @@
<?php
echo "<h3>Authlog</h3>";
echo "<hr>";
if ($_SESSION['userlevel'] >= '10') {
echo '<table cellspacing=0 cellpadding=1 width=100%>';

View File

@ -1,4 +1,6 @@
<h3> Availability Map </h3>
<hr>
<?php
$pagetitle[] = 'Availability Map';
include_once 'includes/common/availability-map.inc.php';
echo implode('',$common_output);

View File

@ -1,5 +1,3 @@
<h1>Delete Host</h1>
<?php
if ($_SESSION['userlevel'] < 10) {
@ -27,16 +25,18 @@ else {
print_error("Are you sure you want to delete device " . $device['hostname'] . "?");
?>
<br />
<form name="form1" method="post" action="" class="form-horizontal" role="form">
<div class="form-group">
<div class="col-sm-4">
<input type="hidden" name="id" value="<?php echo $_REQUEST['id'] ?>" />
<input type="hidden" name="confirm" value="1" />
<!--<input type="hidden" name="remove_rrd" value="<?php echo $_POST['remove_rrd']; ?>">-->
<button type="submit" class="btn btn-default">Confirm host deletion</button>
<center>
<font color="red"></font><i class="fa fa-exclamation-triangle fa-3x"></i></font>
<br>
<form name="form1" method="post" action="" class="form-horizontal" role="form">
<div class="form-group">
<input type="hidden" name="id" value="<?php echo $_REQUEST['id'] ?>" />
<input type="hidden" name="confirm" value="1" />
<!--<input type="hidden" name="remove_rrd" value="<?php echo $_POST['remove_rrd']; ?>">-->
<button type="submit" class="btn btn-danger">Confirm host deletion</button>
</div>
</div>
</form>
</form>
</center>
<?php
}
echo('
@ -46,37 +46,39 @@ else {
else {
?>
<form name="form1" method="post" action="" class="form-horizontal" role="form">
<div class="form-group">
<div class="col-sm-offset-2 col-sm-7">
<?php print_error("Warning, this will remove the device from being monitered!</p>
<p>It will also remove historical data about this device such as <mark>Syslog</mark>, <mark>Eventlog</mark> and <mark>Alert log</mark> data.</p>");?>
</div>
</div>
<div class="form-group">
<label for="id" class="col-sm-2 control-label">Device:</label>
<div class="col-sm-7">
<select name="id" class="form-control" id="id">
<form name="form1" method="post" action="" class="form-horizontal" role="form">
<div class="form-group">
<div class="col-sm-offset-2 col-sm-7">
<div><h2>Delete Device</h2></div>
<div class="alert alert-danger" role="alert">
<center>
<p>Warning, this will remove the device from being monitered!</p>
<p>It will also remove historical data about this device such as <mark>Syslog</mark>, <mark>Eventlog</mark> and <mark>Alert log</mark> data.</p>
</center>
</div>
<div class="well">
<div class="form-group">
<label for="id" class="col-sm-2 control-label">Device:</label>
<div class="col-sm-10">
<select name="id" class="form-control" id="id">
<?php
foreach (dbFetchRows("SELECT * FROM `devices` ORDER BY `hostname`") as $data) {
echo("<option value='".$data['device_id']."'>".$data['hostname']."</option>");
}
<?php
foreach (dbFetchRows("SELECT * FROM `devices` ORDER BY `hostname`") as $data) {
echo("<option value='".$data['device_id']."'>".$data['hostname']."</option>");
}
?>
</select>
</div>
</div>
?>
</select>
</div>
</div>
<hr>
<input id="confirm" type="hidden" name="confirm" value="0" />
<center><button id="confirm_delete" type="submit" class="btn btn-default">Delete Device</button></center>
</div>
<div class="form-group">
<!-- <tr>
<td>Remove RRDs (Data files): </td>
<td><input type="checkbox" name="remove_rrd" value="yes"></td>
</tr>-->
<div class="col-sm-offset-2 col-sm-8">
<input id="confirm" type="hidden" name="confirm" value="0" />
<button id="confirm_delete" type="submit" class="btn btn-default">Delete Device</button>
</div>
</form>
<?php
}

View File

@ -3,23 +3,32 @@ require_once 'includes/modal/new_device_group.inc.php';
require_once 'includes/modal/delete_device_group.inc.php';
$no_refresh = true;
echo '<div class="row"><div class="col-sm-12"><span id="message"></span></div></div>';
echo '<div class="table-responsive">';
echo '<table class="table table-condensed table-hover"><thead><tr>';
echo '<th>Name</th><th>Description</th><th>Pattern</th><th>Actions</th>';
echo '</tr></thead><tbody>';
foreach (GetDeviceGroups() as $group) {
echo '<tr id="row_'.$group['id'].'">';
echo '<td>'.$group['name'].'</td>';
echo '<td>'.$group['desc'].'</td>';
echo '<td>'.$group['pattern'].'</td>';
echo '<td>';
echo "<button type='button' class='btn btn-primary btn-sm' aria-label='Edit' data-toggle='modal' data-target='#create-group' data-group_id='".$group['id']."' name='edit-device-group'><span class='glyphicon glyphicon-pencil' aria-hidden='true'></span></button> ";
echo "<button type='button' class='btn btn-danger btn-sm' aria-label='Delete' data-toggle='modal' data-target='#confirm-delete' data-group_id='".$group['id']."' name='delete-device-group'><span class='glyphicon glyphicon-trash' aria-hidden='true'></span></button>";
echo '</td>';
echo '</tr>';
$group_count_check = array_filter(GetDeviceGroups());
if(!empty($group_count_check)) {
echo '<div class="row"><div class="col-sm-12"><span id="message"></span></div></div>';
echo '<div class="table-responsive">';
echo '<table class="table table-condensed table-hover"><thead><tr>';
echo '<th>Name</th><th>Description</th><th>Pattern</th><th>Actions</th>';
echo '</tr></thead><tbody>';
foreach (GetDeviceGroups() as $group) {
echo '<tr id="row_'.$group['id'].'">';
echo '<td>'.$group['name'].'</td>';
echo '<td>'.$group['desc'].'</td>';
echo '<td>'.$group['pattern'].'</td>';
echo '<td>';
echo "<button type='button' class='btn btn-primary btn-sm' aria-label='Edit' data-toggle='modal' data-target='#create-group' data-group_id='".$group['id']."' name='edit-device-group'><span class='glyphicon glyphicon-pencil' aria-hidden='true'></span></button> ";
echo "<button type='button' class='btn btn-danger btn-sm' aria-label='Delete' data-toggle='modal' data-target='#confirm-delete' data-group_id='".$group['id']."' name='delete-device-group'><span class='glyphicon glyphicon-trash' aria-hidden='true'></span></button>";
echo '</td>';
echo '</tr>';
}
echo '</tbody></table></div>';
}
else { //if $group_count_check is empty, aka no group found, then display a message to the user.
echo "<center>Looks like no groups have been created, let's create one now. Click on <b>Create New Group</b> to create one.</center><br>";
echo "<center><button type='button' class='btn btn-primary btn-sm' aria-label='Add' data-toggle='modal' data-target='#create-group' data-group_id='' name='create-device-group'>Create new Group</button></center>";
}
echo '</tbody></table></div>';
echo "<button type='button' class='btn btn-primary btn-sm' aria-label='Add' data-toggle='modal' data-target='#create-group' data-group_id='' name='create-device-group'>Create new Group</button> ";
if(!empty($group_count_check)) { //display create new node group when $group_count_check has a value so that the user can define more groups in the future.
echo "<hr>";
echo "<center><button type='button' class='btn btn-primary btn-sm' aria-label='Add' data-toggle='modal' data-target='#create-group' data-group_id='' name='create-device-group'>Create new Group</button></center>";
}

View File

@ -357,6 +357,12 @@ if (device_permitted($vars['device']) || $check_device == $vars['device']) {
</a>
</li>';
echo '<li class="'.$select['notes'].'">
<a href="'.generate_device_url($device, array('tab' => 'notes')).'">
<img src="images/16/page_white_text.png" align="absmiddle" border="0" /> Notes
</a>
</li>';
echo '<li style="float: right;"><a href="https://'.$device['hostname'].'"><img src="images/16/http.png" alt="https" title="Launch browser to https://'.$device['hostname'].'" border="0" width="16" height="16" target="_blank"></a></li>
<li style="float: right;"><a href="ssh://'.$device['hostname'].'"><img src="images/16/ssh.png" alt="ssh" title="SSH to '.$device['hostname'].'" border="0" width="16" height="16"></a></li>

View File

@ -9,5 +9,5 @@
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
echo "<br>";
require_once 'includes/print-graph-alerts.inc.php';

View File

@ -0,0 +1,58 @@
<?php
/*
* Copyright (C) 2015 Mark Schouten <mark@tuxis.nl>
*
* 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; version 2 dated June,
* 1991.
*
* 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.
*
* See http://www.gnu.org/licenses/gpl.txt for the full license
*/
include('includes/application/proxmox.inc.php');
if (!isset($config['enable_proxmox']) || !$config['enable_proxmox']) {
print_error('Proxmox agent was discovered on this host. Please enable Proxmox in your config.');
}
else {
$graphs = array(
'proxmox_traffic' => 'Traffic',
);
foreach (proxmox_node_vms(var_get('device')) as $nvm) {
$vm = proxmox_vm_info($nvm['vmid'], $nvm['cluster']);
foreach ($vm['ports'] as $port) {
foreach ($graphs as $key => $text) {
$graph_type = 'proxmox_traffic';
$graph_array['height'] = '100';
$graph_array['width'] = '215';
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $vm['app_id'];
$graph_array['device_id'] = $vm['device_id'];
$graph_array['type'] = 'application_'.$key;
$graph_array['port'] = $port['port'];
$graph_array['vmid'] = $vm['vmid'];
$graph_array['cluster'] = $vm['cluster'];
$graph_array['hostname'] = $vm['description'];
echo '<h3>'.$text.' '.$port['port'].'@'.$vm['description'].'</h3>';
echo "<tr bgcolor='$row_colour'><td colspan=5>";
include 'includes/print-graphrow.inc.php';
echo '</td></tr>';
}
}
}
}

View File

@ -92,10 +92,19 @@ if ($disable_notify) {
/>
</div>
</div>
<button class="btn btn-default btn-sm" type="submit" name="Submit">Save</button>
<div class="row">
<div class="col-md-1 col-md-offset-3">
<button type="submit" name="Submit" class="btn btn-default"><i class="fa fa-check"></i> Save</button>
</div>
</div>
</form>
<?php
require_once 'includes/modal/new_alert_rule.inc.php';
?>
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#create-alert" data-device_id="<?php echo $device['device_id']; ?>">Create new alert rule</button>
<br>
<div class="row">
<div class="col-md-1 col-md-offset-3">
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#create-alert" data-device_id="<?php echo $device['device_id']; ?>"><i class="fa fa-plus"></i> Create new alert rule</button>
</div>
</div>

View File

@ -62,7 +62,7 @@ echo "<div class='row'>
<div class='col-md-4'>
<form id='appedit' name='appedit' method='post' action='' role='form' class='form-horizontal'>
<input type=hidden name=device value='".$device['device_id']."'>
<table class='table table-condensed table-striped table-responsive'>
<table class='table table-hover table-condensed table-responsive'>
<tr align=center>
<th>Enable</th>
<th>Application</th>
@ -90,14 +90,13 @@ foreach ($applications as $app) {
$row++;
}
echo '<tr>
<td>
<button type="submit" class="btn btn-default" value="Save">Save</button>
</td>
<td>
</td>
</tr>';
echo '</table>';
echo '<div class="row">
<div class="col-md-1">
<button type="submit" name="Submit" class="btn btn-default"><i class="fa fa-check"></i> Save</button>
</div>
</div>
';
echo '</form>';
echo '</div>';
echo '</div>';

View File

@ -1,5 +1,4 @@
<?php
if ($_POST['editing']) {
if ($_SESSION['userlevel'] > "7") {
$updated = 0;
@ -65,83 +64,84 @@ elseif ($update_message) {
?>
<div class="row">
<div class="col-sm-1">
<div class="col-md-1 col-md-offset-2">
<form id="delete_host" name="delete_host" method="post" action="delhost/" role="form">
<input type="hidden" name="id" value="<?php echo($device['device_id']); ?>">
<button type="submit" class="btn btn-danger" name="Submit">Delete device</button>
<button type="submit" class="btn btn-danger" name="Submit"><i class="fa fa-trash"></i> Delete device</button>
</form>
</div>
<div class="col-sm-1">
<div class="col-md-1 col-md-offset-2">
<?php
if($config['enable_clear_discovery'] == 1) {
?>
<button type="submit" id="rediscover" data-device_id="<?php echo($device['device_id']); ?>" class="btn btn-primary" name="rediscover"><i class="fa fa-retweet"></i> Rediscover device</button>
<?php
}
?>
</div>
<?php
if($config['enable_clear_discovery'] == 1) {
?>
<div class="col-sm-1">
<button type="submit" id="rediscover" data-device_id="<?php echo($device['device_id']); ?>" class="btn btn-primary" name="rediscover">Rediscover device</button>
</div>
<?php
}
?>
</div>
<br />
<br>
<form id="edit" name="edit" method="post" action="" role="form" class="form-horizontal">
<input type=hidden name="editing" value="yes">
<div class="form-group">
<label for="descr" class="col-sm-2 control-label">Description:</label>
<div class="col-sm-6">
<input id="descr" name="descr" value="<?php echo($device['purpose']); ?>" class="form-control">
<div class="form-group">
<label for="descr" class="col-sm-2 control-label">Description:</label>
<div class="col-sm-6">
<input id="descr" name="descr" value="<?php echo($device['purpose']); ?>" class="form-control">
</div>
</div>
</div>
<div class="form-group">
<label for="type" class="col-sm-2 control-label">Type:</label>
<div class="col-sm-6">
<select id="type" name="type" class="form-control">
<?php
$unknown = 1;
<div class="form-group">
<label for="type" class="col-sm-2 control-label">Type:</label>
<div class="col-sm-6">
<select id="type" name="type" class="form-control">
<?php
$unknown = 1;
foreach ($config['device_types'] as $type) {
echo(' <option value="'.$type['type'].'"');
if ($device['type'] == $type['type']) {
echo(' selected="1"');
$unknown = 0;
}
echo(' >' . ucfirst($type['type']) . '</option>');
}
if ($unknown) {
echo(' <option value="other">Other</option>');
}
?>
</select>
</div>
</div>
<div class="form-group">
foreach ($config['device_types'] as $type) {
echo(' <option value="'.$type['type'].'"');
if ($device['type'] == $type['type']) {
echo(' selected="1"');
$unknown = 0;
}
echo(' >' . ucfirst($type['type']) . '</option>');
}
if ($unknown) {
echo(' <option value="other">Other</option>');
}
?>
</select>
</div>
</div>
<div class="form-group">
<label for="sysLocation" class="col-sm-2 control-label">Override sysLocation:</label>
<div class="col-sm-6">
<div class="checkbox">
<input onclick="edit.sysLocation.disabled=!edit.override_sysLocation.checked" type="checkbox" name="override_sysLocation"<?php if ($override_sysLocation) echo(' checked="1"'); ?> />
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-2">
<div class="checkbox">
<input onclick="edit.sysLocation.disabled=!edit.override_sysLocation.checked" type="checkbox" name="override_sysLocation"<?php if ($override_sysLocation) echo(' checked="1"'); ?> />
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-2"></div>
<div class="col-sm-6">
<input id="sysLocation" name="sysLocation" class="form-control" <?php if (!$override_sysLocation) echo(' disabled="1"'); ?> value="<?php echo($override_sysLocation_string); ?>" />
</div>
</div>
<div class="form-group">
</div>
<div class="form-group">
<label for="disabled" class="col-sm-2 control-label">Disable:</label>
<div class="col-sm-6">
<input name="disabled" type="checkbox" id="disabled" value="1" <?php if ($device["disabled"]) echo("checked=checked"); ?> />
</div>
</div>
<div class="form-group">
</div>
<div class="form-group">
<label for="ignore" class="col-sm-2 control-label">Ignore</label>
<div class="col-sm-6">
<input name="ignore" type="checkbox" id="ignore" value="1" <?php if ($device['ignore']) echo("checked=checked"); ?> />
<input name="ignore" type="checkbox" id="ignore" value="1" <?php if ($device['ignore']) echo("checked=checked"); ?> />
</div>
</div>
<button type="submit" name="Submit" class="btn btn-default">Save</button>
</div>
<div class="row">
<div class="col-md-1 col-md-offset-2">
<button type="submit" name="Submit" class="btn btn-default"><i class="fa fa-check"></i> Save</button>
</div>
</div>
</form>
<br />
<script>
@ -166,13 +166,8 @@ if ($unknown) {
});
</script>
<?php
print_optionbar_start();
list($sizeondisk, $numrrds) = foldersize($config['rrd_dir']."/".$device['hostname']);
echo("Size on Disk: <b>" . formatStorage($sizeondisk) . "</b> in <b>" . $numrrds . " RRD files</b>.");
print_optionbar_end();
?>

View File

@ -66,6 +66,13 @@ else if ($update_message) {
<input id="ipmi_password" name="ipmi_password" type="password" class="form-control" value="<?php echo get_dev_attrib($device, 'ipmi_password'); ?>" />
</div>
</div>
<button class="btn btn-default btn-sm" type="submit" name="Submit">Save</button>
<div class="row">
<div class="col-md-1 col-md-offset-2">
<button type="submit" name="Submit" class="btn btn-default"><i class="fa fa-check"></i> Save</button>
</div>
</div>
<br><br>
<div class="alert alert-info" role="alert">
<p>To disable IPMI polling, please clear the setting fields and click <b>Save</b>.</p>
</div>
</form>
<p>To disable IPMI polling, please clear the setting fields and click <b>Save</b>.</p>

View File

@ -1,10 +1,12 @@
</form>
<span id="message"><small><div class="alert alert-danger">n.b For the first time, please click any button twice.</div></small></span>
<form id='ignoreport' name='ignoreport' method='post' action='' role='form' class='form-inline'>
<input type='hidden' name='ignoreport' value='yes'>
<input type='hidden' name='type' value='update-ports'>
<input type='hidden' name='device' value='<?php echo $device['device_id'];?>'>
<table id='edit-ports' class='table table-condensed table-responsive table-striped'>
<div class='table-responsibe'>
<table id='edit-ports' class='table table-striped'>
<thead>
<tr>
<th data-column-id='ifIndex'>Index</th>
@ -17,9 +19,50 @@
</tr>
</thead>
</table>
</div>
</form>
<script>
$(document).on('blur', "[name='if-alias']", function (){
var $this = $(this);
var descr = $this.val();
var device_id = $this.data('device_id');
var port_id = $this.data('port_id');
var ifName = $this.data('ifname');
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: {type: "update-ifalias", descr: descr, ifName: ifName, port_id: port_id, device_id: device_id},
dataType: "json",
success: function (data) {
if (data.status == 'ok') {
$this.closest('.form-group').addClass('has-success');
$this.next().addClass('glyphicon-ok');
setTimeout(function(){
$this.closest('.form-group').removeClass('has-success');
$this.next().removeClass('glyphicon-ok');
}, 2000);
} else if (data.status == 'na') {
} else {
$(this).closest('.form-group').addClass('has-error');
$this.next().addClass('glyphicon-remove');
setTimeout(function(){
$this.closest('.form-group').removeClass('has-error');
$this.next().removeClass('glyphicon-remove');
}, 2000);
}
},
error: function () {
$(this).closest('.form-group').addClass('has-error');
$this.next().addClass('glyphicon-remove');
setTimeout(function(){
$this.closest('.form-group').removeClass('has-error');
$this.next().removeClass('glyphicon-remove');
}, 2000);
}
});
});
$(document).ready(function() {
$('form#ignoreport').submit(function (event) {
$('#disable-toggle').click(function (event) {
@ -96,6 +139,7 @@
});
event.preventDefault();
});
});
var grid = $("#edit-ports").bootgrid({

View File

@ -70,8 +70,6 @@ if ($_POST['editing']) {
$device = dbFetchRow('SELECT * FROM `devices` WHERE `device_id` = ?', array($device['device_id']));
$descr = $device['purpose'];
echo '<div class="row">
<div class="col-sm-6">';
if ($updated && $update_message) {
print_message($update_message);
}
@ -79,9 +77,6 @@ else if ($update_message) {
print_error($update_message);
}
echo ' </div>
</div>';
echo "
<form id='edit' name='edit' method='post' action='' role='form' class='form-horizontal'>
<input type=hidden name='editing' value='yes'>
@ -128,7 +123,7 @@ echo " </select>
<div class='form-group'>
<label for='community' class='col-sm-2 control-label'>SNMP Community</label>
<div class='col-sm-4'>
<input id='community' class='form-control' name='community' value='".$device['community']."' />
<input id='community' class='form-control' name='community' value='".$device['community']."' required/>
</div>
</div>
</div>
@ -211,7 +206,11 @@ if ($config['distributed_poller'] === true) {
echo '
<button type="submit" name="Submit" class="btn btn-default">Save</button>
<div class="row">
<div class="col-md-1 col-md-offset-2">
<button type="submit" name="Submit" class="btn btn-default"><i class="fa fa-check"></i> Save</button>
</div>
</div>
</form>
';

View File

@ -1,27 +1,27 @@
<hr />
<form method="post" action="">
<div class="row">
<div class="col-md-4">
<input type="text" name="string" placeholder="Search" class="form-control" id="string" value="<?php echo $_POST['string']; ?>" required/>
</div>
<div class="col-md-4">
<select name="type" class="form-control" id="type">
<option value="">All Types</option>
<option value="system">System</option>
<?php
foreach (dbFetchRows('SELECT `type` FROM `eventlog` WHERE device_id = ? GROUP BY `type` ORDER BY `type`', array($device['device_id'])) as $data) {
echo "<option value='".$data['type']."'";
if ($data['type'] == $_POST['type']) {
echo 'selected';
}
<form method="post" action="">
<label><strong>Search</strong>
<input type="text" name="string" id="string" value="<?php echo $_POST['string']; ?>" />
</label>
<label>
<strong>Type</strong>
<select name="type" id="type">
<option value="">All Types</option>
<option value="system">System</option>
<?php
foreach (dbFetchRows('SELECT `type` FROM `eventlog` WHERE device_id = ? GROUP BY `type` ORDER BY `type`', array($device['device_id'])) as $data) {
echo "<option value='".$data['type']."'";
if ($data['type'] == $_POST['type']) {
echo 'selected';
echo '>'.$data['type'].'</option>';
}
echo '>'.$data['type'].'</option>';
}
?>
</select>
</label>
<input class="submit" type="submit" value="Search">
?>
</select>
</div>
<div class="col-md-4"><input class="btn btn-default" type="submit" value="Search"></div>
</div>
</form>
<?php

View File

@ -0,0 +1,56 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2015 Søren Friis Rosiak <sorenrosiak@gmail.com>
* 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.
*/
$data = dbFetchRow("SELECT `notes` FROM `devices` WHERE device_id = ?", array(
$device['device_id']
));
?>
<form class="form-horizontal" action="" method="post">
<h3>Device Notes</h3>
<hr>
<div class="form-group">
<div class="col-sm-10">
<textarea class="form-control" rows="6" name="notes" id="device-notes"><?php
echo htmlentities($data['notes']); ?></textarea>
</div>
</div>
<div class="form-group">
<div class="col-sm-10">
<?php
echo '
<button type="submit" name="btn-update-notes" id="btn-update-notes" class="btn btn-primary" data-device_id="' . $device['device_id'] . '">Submit</button>
';
?>
</div>
</div>
</form>
<script>
$("[name='btn-update-notes']").on('click', function(event) {
event.preventDefault();
var $this = $(this);
var device_id = $(this).data("device_id");
var notes = $("#device-notes").val();
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: { type: "update-notes", notes: notes, device_id: device_id},
dataType: "html",
success: function(data){
toastr.success('Saved');
},
error:function(){
toastr.error('Error');
}
});
});
</script>

View File

@ -35,17 +35,19 @@ if (empty($vars['dtpickerto'])) {
?>
<hr />
<form method="post" role="form" id="map" class="form-inline">
<div class="form-group">
<label for="dtpickerfrom">From</label>
<input type="text" class="form-control" id="dtpickerfrom" name="dtpickerfrom" maxlength="16" value="<?php echo $vars['dtpickerfrom']; ?>" data-date-format="YYYY-MM-DD HH:mm">
</div>
<div class="form-group">
<label for="dtpickerto">To</label>
<input type="text" class="form-control" id="dtpickerto" name="dtpickerto" maxlength=16 value="<?php echo $vars['dtpickerto']; ?>" data-date-format="YYYY-MM-DD HH:mm">
</div>
<input type="submit" class="btn btn-default" id="submit" value="Update">
</form>
<div class="center-block">
<form method="post" role="form" id="map" class="form-inline">
<div class="form-group">
<label for="dtpickerfrom">From</label>
<input type="text" class="form-control" id="dtpickerfrom" name="dtpickerfrom" maxlength="16" value="<?php echo $vars['dtpickerfrom']; ?>" data-date-format="YYYY-MM-DD HH:mm">
</div>
<div class="form-group">
<label for="dtpickerto">To</label>
<input type="text" class="form-control" id="dtpickerto" name="dtpickerto" maxlength=16 value="<?php echo $vars['dtpickerto']; ?>" data-date-format="YYYY-MM-DD HH:mm">
</div>
<input type="submit" class="btn btn-default" id="submit" value="Update">
</form>
</div>
<hr />
<script type="text/javascript">
$(function () {

View File

@ -94,26 +94,76 @@ if ($_SESSION['userlevel'] >= '7') {
}
else if ($config['oxidized']['enabled'] === true && isset($config['oxidized']['url'])) {
$node_info = json_decode(file_get_contents($config['oxidized']['url'].'/node/show/'.$device['hostname'].'?format=json'), true);
$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']);
if ($config['oxidized']['features']['versioning'] === true && isset($_POST['config'])) {
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');
}
}
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']);
}
}
if ($config['oxidized']['features']['versioning'] === true) {
$config_versions = json_decode(file_get_contents($config['oxidized']['url'].'/node/version?node_full='.$device['hostname'].'&format=json'), true);
}
if (is_array($node_info)) {
if (is_array($node_info) || is_array($config_versions)) {
echo '<br />
<div class="row">
<div class="col-sm-4">
<div class="panel panel-primary">
<div class="panel-heading">Sync status: <strong>'.$node_info['last']['status'].'</strong></div>
<ul class="list-group">
<li class="list-group-item"><strong>Node:</strong> '.$node_info['name'].'</strong></li>
<li class="list-group-item"><strong>IP:</strong> '.$node_info['ip'].'</strong></li>
<li class="list-group-item"><strong>Model:</strong> '.$node_info['model'].'</strong></li>
<li class="list-group-item"><strong>Last Sync:</strong> '.$node_info['last']['end'].'</strong></li>
</ul>
</div>
</div>
</div>';
';
if (is_array($node_info)) {
echo '
<div class="col-sm-4">
<div class="panel panel-primary">
<div class="panel-heading">Sync status: <strong>'.$node_info['last']['status'].'</strong></div>
<ul class="list-group">
<li class="list-group-item"><strong>Node:</strong> '.$node_info['name'].'</strong></li>
<li class="list-group-item"><strong>IP:</strong> '.$node_info['ip'].'</strong></li>
<li class="list-group-item"><strong>Model:</strong> '.$node_info['model'].'</strong></li>
<li class="list-group-item"><strong>Last Sync:</strong> '.$node_info['last']['end'].'</strong></li>
</ul>
</div>
</div>
';
}
if (is_array($config_versions)) {
echo '
<div class="col-sm-8">
<form class="form-horizontal" action="" method="post">
<div class="form-group">
<label for="config" class="col-sm-2 control-label">Config version</label>
<div class="col-sm-6">
<select id="config" name="config" class="form-control">
<option value="">Select version</option>
';
$config_total = count($config_versions);
foreach ($config_versions as $version) {
echo '<option value="'.$version['oid'].'|'.$version['date'].'|'.$config_total.'">'.$config_total.' :: '.$version['date'].' - '.$version['message'].'</option>';
$config_total--;
}
echo '
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-6">
<button type="submit" class="btn btn-primary btn-sm">Show version</button>
</div>
</div>
</form>
</div>
';
}
echo '</div>';
}
else {
echo '<br />';

View File

@ -17,37 +17,176 @@
*/
$no_refresh = true;
foreach (dbFetchRows('SELECT * FROM `users_widgets` LEFT JOIN `widgets` ON `widgets`.`widget_id`=`users_widgets`.`widget_id` WHERE `user_id`=?',array($_SESSION['user_id'])) as $items) {
if (dbFetchCell('SELECT dashboard_id FROM dashboards WHERE user_id=?',array($_SESSION['user_id'])) == 0) {
$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));
}
}
if (!empty($vars['dashboard'])) {
$orig = $vars['dashboard'];
$vars['dashboard'] = dbFetchRow('select * from dashboards where user_id = ? && dashboard_id = ? order by dashboard_id limit 1',array($_SESSION['user_id'],$vars['dashboard']));
if (empty($vars['dashboard'])) {
$vars['dashboard'] = dbFetchRow('select dashboards.*,users.username from dashboards inner join users on dashboards.user_id = users.user_id where dashboards.dashboard_id = ? && dashboards.access > 0',array($orig));
}
}
if (empty($vars['dashboard'])) {
$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 <code>#'.$orig.'</code> does not exist! Loaded <code>'.$vars['dashboard']['dashboard_name'].'</code> instead.','title' => 'Requested Dashboard Not Found!');
}
}
$data = array();
foreach (dbFetchRows('SELECT user_widget_id,users_widgets.widget_id,title,widget,col,row,size_x,size_y,refresh FROM `users_widgets` LEFT JOIN `widgets` ON `widgets`.`widget_id`=`users_widgets`.`widget_id` WHERE `dashboard_id`=?',array($vars['dashboard']['dashboard_id'])) as $items) {
$data[] = $items;
}
if (!is_array($data)) {
if (empty($data)) {
$data[] = array('user_widget_id'=>'0','widget_id'=>1,'title'=>'Add a widget','widget'=>'placeholder','col'=>1,'row'=>1,'size_x'=>2,'size_y'=>2,'refresh'=>60);
}
$data = serialize(json_encode($data));
$data = serialize(json_encode($data));
$dash_config = unserialize(stripslashes($data));
$dashboards = dbFetchRows("SELECT * FROM `dashboards` WHERE `user_id` = ? && `dashboard_id` != ?",array($_SESSION['user_id'],$vars['dashboard']['dashboard_id']));
?>
<div class="btn-group" role="group">
<a class="btn btn-default disabled" role="button">Widgets</a>
<a class="btn btn-success" role="button" data-toggle="collapse" href="#add_widget" aria-expanded="false" aria-controls="add_widget"><i class="fa fa-plus fa-fw"></i></a>
<a class="btn btn-danger" role="button" id="clear_widgets" name="clear_widgets"><i class="fa fa-trash fa-fw"></i></a>
</div>
<div class="collapse" id="add_widget">
<div class="well">
<div class="row">
<div class="col-md-6">
<div class="btn-group btn-lg">
<button class="btn btn-default disabled" style="min-width:160px;"><span class="pull-left">Dashboards</span></button>
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="min-width:160px;"><span class="pull-left"><?php echo ($vars['dashboard']['user_id'] != $_SESSION['user_id'] ? $vars['dashboard']['username'].':' : ''); ?><?php echo $vars['dashboard']['dashboard_name']; ?></span>
<span class="pull-right">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</span>
</button>
<ul class="dropdown-menu">
<?php
foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widgets) {
echo '<a class="btn btn-success" role="button" id="place_widget" name="place_widget" data-widget_id="'.$widgets['widget_id'] .'">'. $widgets['widget_title'] .'</a> ';
$nodash = 0;
if (sizeof($dashboards) > 0 || $vars['dashboard']['user_id'] != $_SESSION['user_id']) {
foreach ($dashboards as $dash) {
if ($dash['dashboard_id'] != $vars['dashboard']['dashboard_id']) {
echo ' <li><a href="'.rtrim($config['base_url'],'/').'/overview/dashboard='.$dash['dashboard_id'].'">'.$dash['dashboard_name'].'</a></li>';
$nodash = 1;
}
}
}
if ($nodash == 0) {
echo ' <li><a>No other Dashboards</a></li>';
}
$shared_dashboards = dbFetchRows("SELECT dashboards.*,users.username FROM `dashboards` INNER JOIN `users` ON users.user_id = dashboards.user_id WHERE dashboards.access > 0 && dashboards.user_id != ? && dashboards.dashboard_id != ?",array($_SESSION['user_id'],$vars['dashboard']['dashboard_id']));
if (!empty($shared_dashboards)) {
echo ' <li role="separator" class="divider"></li>';
echo ' <li class="dropdown-header">Shared Dashboards</li>';
foreach ($shared_dashboards as $dash) {
if ($dash['dashboard_id'] != $vars['dashboard']['dashboard_id']) {
echo ' <li><a href="'.rtrim($config['base_url'],'/').'/overview/dashboard='.$dash['dashboard_id'].'">&nbsp;&nbsp;&nbsp;'.$dash['username'].':'.$dash['dashboard_name'].($dash['access'] == 1 ? ' (Read)' : '').'</a></li>';
}
}
}
?>
</ul>
</div>
<button class="btn btn-default" href="#edit_dash" onclick="dashboard_collapse($(this).attr('href'))"><i class="fa fa-pencil-square-o fa-fw"></i></button>
<button class="btn btn-danger" href="#del_dash" onclick="dashboard_collapse($(this).attr('href'))"><i class="fa fa-trash fa-fw"></i></button>
<button class="btn btn-success" href="#add_dash" onclick="dashboard_collapse($(this).attr('href'))"><i class="fa fa-plus fa-fw"></i></button>
</div>
</div>
</div>
<div class="dash-collapse" id="add_dash">
<div class="row" style="margin-top:5px;">
<div class="col-md-6">
<form class="form-inline" onsubmit="dashboard_add(this); return false;">
<div class="col-sm-3 col-sx-6">
<div class="input-group">
<span class="input-group-btn">
<a class="btn btn-default disabled" type="button" style="min-width:160px;"><span class="pull-left">New Dashboard</span></a>
</span>
<input class="form-control" type="text" placeholder="Name" name="dashboard_name" style="min-width:160px;">
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">Add</button>
</span>
</div>
</div>
</form>
</div>
</div>
<hr>
</div>
<div class="dash-collapse" id="edit_dash">
<!-- Start Dashboard-Settings -->
<div class="row" style="margin-top:5px;">
<div class="col-md-12">
<div class="col-md-12">
<form class="form-inline" onsubmit="dashboard_edit(this); return false;">
<div class="form-group">
<div class="input-group">
<span class="input-group-btn">
<a class="btn btn-default disabled" type="button" style="min-width:160px;"><span class="pull-left">Dashboard Name</span></a>
</span>
<input class="form-control" type="text" placeholder="Dashbord Name" name="dashboard_name" value="<?php echo $vars['dashboard']['dashboard_name']; ?>" style="width:160px;">
<select class="form-control" name="access" style="width:160px;">
<?php
foreach (array('Private','Shared (Read)','Shared') as $k=>$v) {
echo ' <option value="'.$k.'"'.($vars['dashboard']['access'] == $k ? 'selected' : '').'>'.$v.'</option>';
}
?>
</select>
<span class="input-group-btn pull-left">
<button class="btn btn-primary" type="submit">Update</button>
</span>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- End Dashboard-Settings -->
<!-- Start Widget-Select -->
<div class="row" style="margin-top:5px;">
<div class="col-md-12">
<div class="col-md-12">
<div class="btn-group" role="group">
<a class="btn btn-default disabled" role="button" style="min-width:160px;"><span class="pull-left">Add Widgets</span></a>
<div class="btn-group">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="min-width:160px;"><span class="pull-left">Select Widget</span>
<span class="pull-right">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</span>
</button>
<ul class="dropdown-menu">
<?php
foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widgets) {
echo ' <li><a href="javascript:return false;" name="place_widget" data-widget_id="'.$widgets['widget_id'] .'">'. $widgets['widget_title'] .'</a></li>';
}
?>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- End Widget-Select -->
<hr>
</div>
<div class="dash-collapse" id="del_dash">
<div class="row" style="margin-top:5px;">
<div class="col-md-6">
<div class="col-md-6">
<button class="btn btn-danger" type="button" id="clear_widgets" name="clear_widgets" style="min-width:160px;"><span class="pull-left">Remove</span><strong class="pull-right">Widgets</strong></button>
</div>
</div>
</div>
<div class="row" style="margin-top:5px;">
<div class="col-md-6">
<div class="col-md-6">
<button class="btn btn-danger" type="button" onclick="dashboard_delete(this); return false;" data-dashboard="<?php echo $vars['dashboard']['dashboard_id']; ?>" style="min-width:160px;"><span class="pull-left">Delete</span><strong class="pull-right">Dashboard</strong></button>
</div>
</div>
</div>
<hr>
</div>
<script src='https://www.google.com/jsapi'></script>
<script src="js/jquery.gridster.min.js"></script>
@ -75,7 +214,7 @@ foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widg
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: {type: "update-dashboard-config", data: s},
data: {type: "update-dashboard-config", data: s, dashboard_id: <?php echo $vars['dashboard']['dashboard_id']; ?>},
dataType: "json",
success: function (data) {
if (data.status == 'ok') {
@ -91,25 +230,27 @@ foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widg
}
$(function(){
dashboard_collapse();
gridster = $(".gridster ul").gridster({
widget_base_dimensions: [100, 100],
widget_margins: [5, 5],
avoid_overlapped_widgets: true,
draggable: {
handle: 'header',
handle: 'header, span',
stop: function(e, ui, $widget) {
updatePos(gridster);
},
},
resize: {
enabled: true,
stop: function(e, ui, $widget) {
stop: function(e, ui, widget) {
updatePos(gridster);
widget_reload(widget.attr('id'),widget.data('type'));
}
},
serialize_params: function($w, wgd) {
serialize_params: function(w, wgd) {
return {
id: $($w).attr('id'),
id: $(w).attr('id'),
col: wgd.col,
row: wgd.row,
size_x: wgd.size_x,
@ -120,14 +261,7 @@ foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widg
gridster.remove_all_widgets();
$.each(serialization, function() {
gridster.add_widget(
'<li id="'+this.user_widget_id+'">'+
'\<script\>var timeout'+this.user_widget_id+' = grab_data('+this.user_widget_id+','+this.refresh+',\''+this.widget+'\');\<\/script\>'+
'<header class="widget_header">'+this.title+'<button style="color: #ffffff" type="button" class="close close-widget" data-widget-id="'+this.user_widget_id+'" aria-label="Close"><span aria-hidden="true">&times;</span></button></header>'+
'<div class="widget_body" id="widget_body_'+this.user_widget_id+'">'+this.widget+'</div>'+
'</li>',
parseInt(this.size_x), parseInt(this.size_y), parseInt(this.col), parseInt(this.row)
);
widget_dom(this);
});
$(document).on('click','#clear_widgets', function() {
@ -135,7 +269,7 @@ foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widg
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: {type: "update-dashboard-config", sub_type: 'remove-all'},
data: {type: "update-dashboard-config", sub_type: 'remove-all', dashboard_id: <?php echo $vars['dashboard']['dashboard_id']; ?>},
dataType: "json",
success: function (data) {
if (data.status == 'ok') {
@ -156,23 +290,11 @@ foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widg
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: {type: "update-dashboard-config", sub_type: 'add', widget_id: widget_id},
data: {type: "update-dashboard-config", sub_type: 'add', widget_id: widget_id, dashboard_id: <?php echo $vars['dashboard']['dashboard_id']; ?>},
dataType: "json",
success: function (data) {
if (data.status == 'ok') {
var widget_id = data.extra.widget_id;
var title = data.extra.title;
var widget = data.extra.widget;
var size_x = data.extra.size_x;
var size_y = data.extra.size_y;
gridster.add_widget(
'<li id="'+widget_id+'">'+
'\<script\>var timeout'+widget_id+' = grab_data('+widget_id+',60,\''+widget+'\');\<\/script\>'+
'<header class="widget_header">'+title+'<button type="button" class="close close-widget" data-widget-id="'+widget_id+'" aria-label="Close"><span aria-hidden="true">&times;</span></button></header>'+
'<div class="widget_body" id="widget_body_'+widget_id+'">'+widget+'</div>'+
'</li>',
parseInt(size_x), parseInt(size_y)
);
widget_dom(data.extra);
updatePos(gridster);
}
else {
@ -190,7 +312,7 @@ foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widg
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: {type: "update-dashboard-config", sub_type: 'remove', widget_id: widget_id},
data: {type: "update-dashboard-config", sub_type: 'remove', widget_id: widget_id, dashboard_id: <?php echo $vars['dashboard']['dashboard_id']; ?>},
dataType: "json",
success: function (data) {
if (data.status == 'ok') {
@ -207,33 +329,176 @@ foreach (dbFetchRows("SELECT * FROM `widgets` ORDER BY `widget_title`") as $widg
});
});
$(document).on("click",".edit-widget",function() {
obj = $(this).parent().parent();
if( obj.data('settings') == 1 ) {
obj.data('settings','0');
} else {
obj.data('settings','1');
}
widget_reload(obj.attr('id'),obj.data('type'));
});
});
function grab_data(id,refresh,data_type) {
new_refresh = refresh * 1000;
$.ajax({
type: 'POST',
url: 'ajax_dash.php',
data: {type: data_type},
dataType: "json",
success: function (data) {
if (data.status == 'ok') {
$("#widget_body_"+id).html(data.html);
}
else {
$("#widget_body_"+id).html('<div class="alert alert-info">' + data.message + '</div>');
}
},
error: function () {
$("#widget_body_"+id).html('<div class="alert alert-info">Problem with backend</div>');
}
});
function dashboard_collapse(target) {
if (target !== undefined) {
$('.dash-collapse:not('+target+')').each(function() {
$(this).fadeOut(0);
});
$(target).fadeToggle(300);
} else {
$('.dash-collapse').fadeOut(0);
}
}
setTimeout(function() {
grab_data(id,refresh,data_type);
},
new_refresh);
}
$('#new-widget').popover();
function dashboard_delete(data) {
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: {type: 'delete-dashboard', dashboard_id: $(data).data('dashboard')},
dataType: "json",
success: function (data) {
if( data.status == "ok" ) {
$("#message").html('<div class="alert alert-info">' + data.message + '</div>');
window.location.href="<?php echo rtrim($config['base_url'],'/'); ?>/overview";
}
else {
$("#message").html('<div class="alert alert-info">' + data.message + '</div>');
}
}
});
}
function dashboard_edit(data) {
datas = $(data).serializeArray();
data = [];
for( var field in datas ) {
data[datas[field].name] = datas[field].value;
}
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: {type: 'edit-dashboard', dashboard_name: data['dashboard_name'], dashboard_id: <?php echo $vars['dashboard']['dashboard_id']; ?>, access: data['access']},
dataType: "json",
success: function (data) {
if( data.status == "ok" ) {
$("#message").html('<div class="alert alert-info">' + data.message + '</div>');
window.location.href="<?php echo rtrim($config['base_url'],'/'); ?>/overview/dashboard=<?php echo $vars['dashboard']['dashboard_id']; ?>";
}
else {
$("#message").html('<div class="alert alert-info">' + data.message + '</div>');
}
}
});
}
function dashboard_add(data) {
datas = $(data).serializeArray();
data = [];
for( var field in datas ) {
data[datas[field].name] = datas[field].value;
}
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: {type: 'add-dashboard', dashboard_name: data['dashboard_name']},
dataType: "json",
success: function (data) {
if( data.status == "ok" ) {
$("#message").html('<div class="alert alert-info">' + data.message + '</div>');
window.location.href="<?php echo rtrim($config['base_url'],'/'); ?>/overview/dashboard="+data.dashboard_id;
}
else {
$("#message").html('<div class="alert alert-info">' + data.message + '</div>');
}
}
});
}
function widget_dom(data) {
dom = '<li id="'+data.user_widget_id+'" data-type="'+data.widget+'" data-settings="0">'+
'<header class="widget_header"><span id="widget_title_'+data.user_widget_id+'">'+data.title+'</span>'+
'<button style="color: #ffffff;" type="button" class="fa fa-times close close-widget" data-widget-id="'+data.user_widget_id+'" aria-label="Close">&nbsp;</button>'+
'<button style="color: #ffffff;" type="button" class="fa fa-pencil-square-o close edit-widget" data-widget-id="'+data.user_widget_id+'" aria-label="Settings">&nbsp;</button>'+
'</header>'+
'<div class="widget_body" id="widget_body_'+data.user_widget_id+'" style="height: 100%; width:100%;">'+data.widget+'</div>'+
'\<script\>var timeout'+data.user_widget_id+' = grab_data('+data.user_widget_id+','+data.refresh+',\''+data.widget+'\');\<\/script\>'+
'</li>';
if (data.hasOwnProperty('col') && data.hasOwnProperty('row')) {
gridster.add_widget(dom, parseInt(data.size_x), parseInt(data.size_y), parseInt(data.col), parseInt(data.row));
} else {
gridster.add_widget(dom, parseInt(data.size_x), parseInt(data.size_y));
}
}
function widget_settings(data) {
var widget_settings = {};
var widget_id = 0;
datas = $(data).serializeArray();
for( var field in datas ) {
widget_settings[datas[field].name] = datas[field].value;
}
$('.gridster').find('div[id^=widget_body_]').each(function() {
if(this.contains(data)) {
widget_id = $(this).parent().attr('id');
widget_type = $(this).parent().data('type');
$(this).parent().data('settings','0');
}
});
if( widget_id > 0 && widget_settings != {} ) {
$.ajax({
type: 'POST',
url: 'ajax_form.php',
data: {type: 'widget-settings', id: widget_id, settings: widget_settings},
dataType: "json",
success: function (data) {
if( data.status == "ok" ) {
widget_reload(widget_id,widget_type);
}
else {
$("#message").html('<div class="alert alert-info">' + data.message + '</div>');
}
}
});
}
}
function widget_reload(id,data_type) {
if( $("#widget_body_"+id).parent().data('settings') == 1 ) {
settings = 1;
} else {
settings = 0;
}
$.ajax({
type: 'POST',
url: 'ajax_dash.php',
data: {type: data_type, id: id, dimensions: {x:$("#widget_body_"+id).innerWidth()-50, y:$("#widget_body_"+id).innerHeight()-50}, settings:settings},
dataType: "json",
success: function (data) {
if (data.status == 'ok') {
$("#widget_title_"+id).html(data.title);
$("#widget_body_"+id).html(data.html);
}
else {
$("#widget_body_"+id).html('<div class="alert alert-info">' + data.message + '</div>');
}
},
error: function () {
$("#widget_body_"+id).html('<div class="alert alert-info">Problem with backend</div>');
}
});
}
function grab_data(id,refresh,data_type) {
if( $("#widget_body_"+id).parent().data('settings') == 0 ) {
widget_reload(id,data_type);
}
new_refresh = refresh * 1000;
setTimeout(function() {
grab_data(id,refresh,data_type);
},
new_refresh);
}
$('#new-widget').popover();
</script>

View File

@ -4,57 +4,64 @@ if( $config['twofactor'] && isset($twofactorform) ) {
}
else {
?>
<form class="form-horizontal" role="form" action="" method="post" name="logonform">
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<h3>Please log in:</h3>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<input type="text" name="username" id="username" class="form-control" placeholder="Username" required autofocus />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<input type="password" name="password" id="password" class="form-control" placeholder="Password" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<div class="checkbox">
<input type="checkbox" name="remember" id="remember" /> Remember me.
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<center>
<img src="images/librenms_logo_light.png">
</center></h3>
</div>
<div class="panel-body">
<div class="container-fluid">
<form class="form-horizontal" role="form" action="" method="post" name="logonform">
<div class="form-group">
<input type="text" name="username" id="username" class="form-control" placeholder="Username" required autofocus />
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control" placeholder="Password" />
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" name="remember" id="remember" /> Remember me.
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default btn-block" name="submit" type="submit">Login</button>
</div>
<?php
if (isset($auth_message)) {
$msg_box[] = array('type'=>'error','message'=>$auth_message,'title'=>'Login error');
}
?>
<?php
if (isset($config['login_message'])) {
echo('
<div class="form-group">
<div class="alert alert-info text-center">'.$config['login_message'].'</div>
</div>');
}
?>
</form>
<script type="text/javascript">
<!--
document.logonform.username.focus();
// -->
</script>
<?php
}
?>
</div>
</div>
</div>
</div>
<div class="col-md-4"></div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<button type="submit" class="btn btn-default btn-block" name="submit" type="submit">Login</button>
</div>
</div>
<?php
if (isset($auth_message)) {
$msg_box[] = array('type'=>'error','message'=>$auth_message,'title'=>'Login error');
}
?>
<?php
if (isset($config['login_message'])) {
echo('
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<div class="alert alert-info text-center">'.$config['login_message'].'</div>
</div>
</div>');
}
?>
</form>
<script type="text/javascript">
<!--
document.logonform.username.focus();
// -->
</script>
<?php
}
?>
</div>
</div>

View File

@ -1,5 +1,6 @@
<?php
$no_refresh = true;
$pagetitle[] = 'Poll Log';
?>
<table id="poll-log" class="table table-condensed table-hover table-striped">
<thead>

View File

@ -4,7 +4,8 @@ $no_refresh = true;
$pagetitle[] = 'Preferences';
echo '<h3>User Preferences</h3>';
echo '<h2>User Preferences</h2>';
echo '<hr>';
if ($_SESSION['userlevel'] == 11) {
demo_account();
@ -30,10 +31,12 @@ else {
include 'includes/update-preferences-password.inc.php';
echo "<div class='well'>";
if (passwordscanchange($_SESSION['username'])) {
echo '<h3>Change Password</h3>';
echo '<hr>';
echo "<div class='well'>";
echo $changepass_message;
echo "<form method='post' action='preferences/' class='form-horizontal' role='form'>
<input type=hidden name='action' value='changepass'>
@ -57,11 +60,13 @@ else {
<label for='new_pass2' class='col-sm-2 control-label'>New Password</label>
<div class='col-sm-4'>
<input type=password name=new_pass2 autocomplete='off' class='form-control input-sm'>
<hr>
<center><button type='submit' class='btn btn-default'>Submit</button></center>
</div>
<div class='col-sm-6'>
</div>
</div>
<button type='submit' class='btn btn-default'>Submit</button>
</form>";
echo '</div>';
}//end if
@ -183,9 +188,10 @@ else {
}//end if
}//end if
echo "<div style='background-color: #e5e5e5; border: solid #e5e5e5 10px; margin-bottom:10px;'>";
echo "<div style='font-size: 18px; font-weight: bold; margin-bottom: 5px;'>Device Permissions</div>";
echo "<h3>Device Permissions</h3>";
echo "<hr>";
echo "<div style='background-color: #e5e5e5; border: solid #e5e5e5 10px; margin-bottom:10px;'>";
if ($_SESSION['userlevel'] == '10') {
echo "<strong class='blue'>Global Administrative Access</strong>";
}

View File

@ -23,10 +23,12 @@
* @package LibreNMS
* @subpackage Page
*/
$pagetitle[] = 'Global Settings';
?>
<div class="container-fluid">
<h2>Global Settings</h2>
<hr>
<div class="row">
<div class="col-md-12">
<span id="message"></span>

View File

@ -799,6 +799,25 @@ echo '<div id="boxcar_appkey_template" class="hide">
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#pushbullet_transport_expand">Pushbullet</a> <button name="test-alert" id="test-alert" type="button" data-transport="pushbullet" class="btn btn-primary btn-xs pull-right">Test transport</button>
</h4>
</div>
<div id="pushbullet_transport_expand" class="panel-collapse collapse">
<div class="panel-body">
<div class="form-group has-feedback">
<label for="pushbullet" class="col-sm-4 control-label">Pushbullet Access Token </label>
<div data-toggle="tooltip" title="'.$config_groups['alert.transports.pushbullet']['config_descr'].'" class="toolTip glyphicon glyphicon-question-sign"></div>
<div class="col-sm-4">
<input id="pushbullet" class="form-control" type="text" name="global-config-input" value="'.$config_groups['alert.transports.pushbullet']['config_value'].'" data-config_id="'.$config_groups['alert.transports.pushbullet']['config_id'].'">
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
';
@ -815,12 +834,33 @@ echo '<div id="boxcar_appkey_template" class="hide">
$(".toolTip").tooltip();
$("button#test-alert").click(function() {
var transport = $(this).data("transport");
var $this = $(this);
var transport = $this.data("transport");
$.ajax({
type: 'POST',
url: '/ajax_form.php',
data: { type: "test-transport", transport: transport },
dataType: "json"
dataType: "json",
success: function(data){
if (data.status == 'ok') {
$this.removeClass('btn-primary').addClass('btn-success');
setTimeout(function(){
$this.removeClass('btn-success').addClass('btn-primary');
}, 2000);
}
else {
$this.removeClass('btn-primary').addClass('btn-danger');
setTimeout(function(){
$this.removeClass('btn-danger').addClass('btn-primary');
}, 2000);
}
},
error: function(){
$this.removeClass('btn-primary').addClass('btn-danger');
setTimeout(function(){
$this.removeClass('btn-danger').addClass('btn-primary');
}, 2000);
}
});
});

View File

@ -0,0 +1,47 @@
/* Copyright (C) 2015 Daniel Preussker <f0o@librenms.org>
* 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 <http://www.gnu.org/licenses/>. */
/**
* Pushbullet API Transport
* @author f0o <f0o@librenms.org>
* @copyright 2015 f0o, LibreNMS
* @license GPL
* @package LibreNMS
* @subpackage Alerts
*/
// Note: At this point it might be useful to iterate through $obj['contacts'] and send each of them a note ?
$data = array("type" => "note", "title" => $obj['title'], "body" => $obj['msg']);
$data = json_encode($data);
$curl = curl_init('https://api.pushbullet.com/v2/pushes');
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: '.strlen($data),
'Authorization: Bearer '.$opts,
));
$ret = curl_exec($curl);
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if( $code > 201 ) {
if( $debug ) {
var_dump($ret);
}
return false;
}
return true;

View File

@ -435,8 +435,14 @@ function get_dev_entity_state($device) {
return $state;
}
function get_dev_attrib($device, $attrib_type) {
if ($row = dbFetchRow("SELECT attrib_value FROM devices_attribs WHERE `device_id` = ? AND `attrib_type` = ?", array($device['device_id'], $attrib_type))) {
function get_dev_attrib($device, $attrib_type, $attrib_value='') {
$sql = '';
$params = array($device['device_id'], $attrib_type);
if (!empty($attrib_value)) {
$sql = " AND `attrib_value`=?";
array_push($params, $attrib_value);
}
if ($row = dbFetchRow("SELECT attrib_value FROM devices_attribs WHERE `device_id` = ? AND `attrib_type` = ? $sql", $params)) {
return $row['attrib_value'];
}
else {
@ -687,9 +693,7 @@ function get_graph_subtypes($type) {
// find the MIB subtypes
foreach ($config['graph_types'] as $type => $unused1) {
print_r($type);
foreach ($config['graph_types'][$type] as $subtype => $unused2) {
print_r($subtype);
if (is_mib_graph($type, $subtype)) {
$types[] = $subtype;
}

View File

@ -56,7 +56,7 @@ $config['fping'] = '/usr/bin/fping';
$config['fping_options']['retries'] = 3;
$config['fping_options']['timeout'] = 500;
$config['fping_options']['count'] = 3;
$config['fping_options']['millisec'] = 20;
$config['fping_options']['millisec'] = 200;
$config['snmpwalk'] = '/usr/bin/snmpwalk';
$config['snmpget'] = '/usr/bin/snmpget';
$config['snmpbulkwalk'] = '/usr/bin/snmpbulkwalk';
@ -192,14 +192,7 @@ $config['snmp']['v3'][0]['cryptopass'] = '';
// Privacy (Encryption) Passphrase
$config['snmp']['v3'][0]['cryptoalgo'] = 'AES';
// AES | DES
// RRD Format Settings
// These should not normally be changed
// Though one could conceivably increase or decrease the size of each RRA if one had performance problems
// Or if one had a very fast I/O subsystem with no performance worries.
$config['rrd_rra'] = ' RRA:AVERAGE:0.5:1:2016 RRA:AVERAGE:0.5:6:1440 RRA:AVERAGE:0.5:24:1440 RRA:AVERAGE:0.5:288:1440 ';
$config['rrd_rra'] .= ' RRA:MAX:0.5:1:720 RRA:MIN:0.5:6:1440 RRA:MIN:0.5:24:775 RRA:MIN:0.5:288:797 ';
$config['rrd_rra'] .= ' RRA:MAX:0.5:1:720 RRA:MAX:0.5:6:1440 RRA:MAX:0.5:24:775 RRA:MAX:0.5:288:797 ';
$config['rrd_rra'] .= ' RRA:LAST:0.5:1:1440 ';
// Autodiscovery Settings
$config['autodiscovery']['xdp'] = true;
@ -340,6 +333,9 @@ $config['network_map_vis_options'] = '{
randomSeed:2
},
"edges": {
arrows: {
to: {enabled: true, scaleFactor:0.5},
},
"smooth": {
enabled: false
},
@ -709,9 +705,10 @@ $config['eventlog_purge'] = 30;
$config['authlog_purge'] = 30;
// Number in days of how long to keep authlog entries for.
$config['perf_times_purge'] = 30;
// Number in days of how long to keep performace pooling stats entries for.
$config['device_perf_purge'] = 30;
// Number in days of how long to keep performace polling stats entries for.
$config['device_perf_purge'] = 7;
// Number in days of how long to keep device performance data for.
// Date format for PHP date()s
$config['dateformat']['long'] = 'r';
// RFC2822 style
@ -784,3 +781,6 @@ $config['gui']['network-map']['style'] = 'new';//old is also va
// Navbar variables
$config['navbar']['manage_groups']['hide'] = 0;
// Show errored ports in the summary table on the dashboard
$config['summary_errors'] = 0;

View File

@ -634,6 +634,12 @@ $config['os'][$os]['icon'] = 'avaya';
$config['os'][$os]['over'][0]['graph'] = 'device_bits';
$config['os'][$os]['over'][0]['text'] = 'Device Traffic';
$os = 'avaya-ipo';
$config['os'][$os]['text'] = 'IP Office Firmware';
$config['os'][$os]['type'] = 'network';
$config['os'][$os]['icon'] = 'avaya';
$os = 'arista_eos';
$config['os'][$os]['text'] = 'Arista EOS';
$config['os'][$os]['type'] = 'network';
@ -1276,6 +1282,26 @@ $config['os'][$os]['icon'] = 'perle';
$config['os'][$os]['over'][0]['graph'] = 'device_bits';
$config['os'][$os]['over'][0]['text'] = 'Traffic';
// MACOSX
$os = 'macosx';
$config['os'][$os]['text'] = 'Apple OS X';
$config['os'][$os]['type'] = 'server';
$config['os'][$os]['icon'] = 'generic';
$config['os'][$os]['over'][0]['graph'] = 'device_bits';
$config['os'][$os]['over'][0]['text'] = 'Traffic';
// Appliances
$os = 'fortios';
$config['os'][$os]['text'] = 'FortiOS';
$config['os'][$os]['type'] = 'appliance';
$config['os'][$os]['icon'] = 'fortios';
$config['os'][$os]['over'][0]['graph'] = 'device_bits';
$config['os'][$os]['over'][0]['text'] = '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';
// Graph Types
require_once $config['install_dir'].'/includes/load_db_graph_types.inc.php';
@ -1630,10 +1656,15 @@ if (isset($config['enable_printers']) && $config['enable_printers']) {
$config['device_types'][$i]['icon'] = 'printer.png';
}
$i++;
$config['device_types'][$i]['text'] = 'Appliance';
$config['device_types'][$i]['type'] = 'appliance';
$config['device_types'][$i]['icon'] = 'appliance.png';
//
// No changes below this line #
//
$config['version'] = '2014.master';
$config['version'] = '2015.master';
$config['project_name_version'] = $config['project_name'].' '.$config['version'];
if (isset($config['rrdgraph_def_text'])) {

View File

@ -0,0 +1,7 @@
<?php
if (!$os) {
if (strstr(snmp_get($device, 'ENTITY-MIB::entPhysicalDescr.1', '-Oqvn'), 'Avaya IP Office')) {
$os = "avaya-ipo";
}
}

View File

@ -0,0 +1,7 @@
<?php
if (!$os) {
if (strstr($sysObjectId, '.1.3.6.1.4.1.12356.103.3')) {
$os = 'fortios';
}
}

View File

@ -1,7 +1,7 @@
<?php
if (!$os) {
if (strstr($sysDescr, 'IES-')) {
if (strstr($sysDescr, 'IES-') && !strstr($sysDescr, 'Cisco Systems')) {
$os = 'ies';
}
}

View File

@ -0,0 +1,16 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2015 Søren Friis Rosiak <sorenrosiak@gmail.com>
* 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 (strpos($sysObjectId, '1.3.6.1.4.1.8072.3.2.16') !== false) {
$os = 'macosx';
}
}

View File

@ -4,4 +4,7 @@ if (!$os) {
if (stristr($sysDescr, 'ProSafe')) {
$os = 'netgear';
}
elseif (strpos($sysObjectId, '1.3.6.1.4.1.4526') !== FALSE) {
$os = 'netgear';
}
}

View File

@ -1,15 +1,7 @@
<?php
if (!$os) {
if (stristr($sysDescr, 'VRP (R) Software')) {
$os = 'vrp';
}
if (stristr($sysDescr, 'VRP Software Version')) {
$os = 'vrp';
}
if (stristr($sysDescr, 'Software Version VRP')) {
$os = 'vrp';
} if (stristr($sysDescr, 'Versatile Routing Platform Software Version')) {
if (stristr($sysDescr, 'VRP (R) Software') || stristr($sysDescr, 'VRP Software Version') || stristr($sysDescr, 'Software Version VRP') || stristr($sysDescr, 'Versatile Routing Platform Software')) {
$os = 'vrp';
}
}

View File

@ -4,4 +4,7 @@ if (!$os) {
if (strstr($sysDescr, 'ZyWALL')) {
$os = 'zywall';
}
if (strstr($sysObjectId, '.1.3.6.1.4.1.890.1.15')) {
$os = 'zywall';
}
}

View File

@ -3,7 +3,7 @@
// Force10 S-Series
// F10-S-SERIES-CHASSIS-MIB::chStackUnitTemp.1 = Gauge32: 47
// F10-S-SERIES-CHASSIS-MIB::chStackUnitModelID.1 = STRING: S25-01-GE-24V
if ($device['os'] == 'ftos' || $device['os_group'] == 'ftos') {
if ($device['os'] == 'ftos' || $device['os_group'] == 'ftos' || $device['os'] == 'dnos') {
echo 'FTOS C-Series ';
$oids = snmpwalk_cache_oid($device, 'chStackUnitTemp', array(), 'F10-S-SERIES-CHASSIS-MIB', $config['mib_dir'].':'.$config['mib_dir'].'/ftos');

View File

@ -1227,3 +1227,7 @@ function fping($host,$params) {
function function_check($function) {
return function_exists($function);
}
function get_last_commit() {
return `git log -n 1|head -n1`;
}//end get_last_commit

View File

@ -0,0 +1,93 @@
<?php
if (isset($config['enable_proxmox']) && $config['enable_proxmox'] && !empty($agent_data['app']['proxmox'])) {
$proxmox = $agent_data['app']['proxmox'];
}
/**
* Check if a port on a Proxmox VM exists
* @param string $p Port name
* @param string $c Clustername
* @param integer $i VM ID
* @return integer|boolean The port-ID if the port exists, false if it doesn't exist
*/
function proxmox_port_exists($i, $c, $p) {
if ($row = dbFetchRow("SELECT pmp.id FROM proxmox_ports pmp, proxmox pm WHERE pm.id = pmp.vm_id AND pmp.port = ? AND pm.cluster = ? AND pm.vmid = ?", array($p, $c, $i))) {
return $row['id'];
}
return false;
}
/**
* Check if a Proxmox VM exists
* @param integer $i VM ID
* @param string $c Clustername
* @param array $pmxcache Reference to the Proxmox VM Cache
* @return boolean true if the VM exists, false if it doesn't
*/
function proxmox_vm_exists($i, $c, &$pmxcache) {
if (isset($pmxcache[$c][$i]) && $pmxcache[$c][$i] > 0) {
return true;
}
if ($row = dbFetchRow("SELECT id FROM proxmox WHERE vmid = ? AND cluster = ?", array($i, $c))) {
$pmxcache[$c][$i] = (integer) $row['id'];
return true;
}
return false;
}
$pmxlines = explode("\n", $proxmox);
if (count($pmxlines) > 2) {
$pmxcluster = array_shift($pmxlines);
$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'));
$pmxcache = [];
foreach ($pmxlines as $vm) {
list($vmid, $vmport, $vmpin, $vmpout, $vmdesc) = explode('/', $vm, 5);
$rrd_filename = join('/', array(
$pmxcdir,
$vmid.'_netif_'.$vmport.'.rrd'));
if (!is_file($rrd_filename)) {
rrdtool_create(
$rrd_filename,
' --step 300 \
DS:INOCTETS:DERIVE:600:0:12500000000 \
DS:OUTOCTETS:DERIVE:600:0:12500000000 '.$config['rrd_rra']);
}
rrdtool_update($rrd_filename, 'N:'.$vmpin.':'.$vmpout);
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));
}
else {
$pmxcache[$pmxcluster][$vmid] = dbInsert(array('cluster' => $pmxcluster, 'vmid' => $vmid, 'description' => $vmdesc, 'device_id' => $device['device_id']), 'proxmox');
}
if ($portid = proxmox_port_exists($vmid, $pmxcluster, $vmport) !== false) {
dbUpdate(array('last_seen' => array('NOW()')), 'proxmox_ports', '`vm_id` = ? AND `port` = ?', array($pmxcache[$pmxcluster][$vmid], $vmport));
}
else {
dbInsert(array('vm_id' => $pmxcache[$pmxcluster][$vmid], 'port' => $vmport), 'proxmox_ports');
}
}
unset($pmxlines);
unset($pmxcluster);
unset($pmxcdir);
unset($proxmox);
unset($pmxcache);
}

View File

@ -278,7 +278,8 @@ function poll_device($device, $options) {
// echo("$device_end - $device_start; $device_time $device_run");
echo "Polled in $device_time seconds\n";
d_echo('Updating '.$device['hostname'].' - '.print_r($update_array)." \n");
d_echo('Updating '.$device['hostname']."\n");
d_echo($update_array);
$updated = dbUpdate($update_array, 'devices', '`device_id` = ?', array($device['device_id']));
if ($updated) {

View File

@ -0,0 +1,10 @@
<?php
echo 'Scanning Avaya IP Office...';
$physDevice = snmp_get($device, 'ENTITY-MIB::entPhysicalDescr.1', '-Oqvn');
if (strstr($physDevice, 'Avaya IP Office')) {
$hardware = $physDevice;
}
$version = $poll_device['sysDescr'];

View File

@ -0,0 +1,3 @@
<?php
$serial = snmp_get($device, 'fnSysSerial', '-OQv', 'FORTINET-FORTIANALYZER-MIB');

View File

@ -35,9 +35,6 @@ $peth_oids = array(
'pethMainPseConsumptionPower',
);
$port_stats = snmpwalk_cache_oid($device, 'pethPsePortEntry', $port_stats, 'POWER-ETHERNET-MIB');
$port_stats = snmpwalk_cache_oid($device, 'cpeExtPsePortEntry', $port_stats, 'CISCO-POWER-ETHERNET-EXT-MIB');
if ($port_stats[$port['ifIndex']]
&& $port['ifType'] == 'ethernetCsmacd'
&& isset($port_stats[$port['ifIndex']]['dot3StatsIndex'])) {

View File

@ -145,6 +145,11 @@ if ($device['adsl_count'] > '0') {
$port_stats = snmpwalk_cache_oid($device, '.1.3.6.1.2.1.10.94.1.1.7.1.7', $port_stats, 'ADSL-LINE-MIB');
}//end if
if ($config['enable_ports_poe']) {
$port_stats = snmpwalk_cache_oid($device, 'pethPsePortEntry', $port_stats, 'POWER-ETHERNET-MIB');
$port_stats = snmpwalk_cache_oid($device, 'cpeExtPsePortEntry', $port_stats, 'CISCO-POWER-ETHERNET-EXT-MIB');
}
// FIXME This probably needs re-enabled. We need to clear these things when they get unset, too.
// foreach ($etherlike_oids as $oid) { $port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "EtherLike-MIB"); }
// foreach ($cisco_oids as $oid) { $port_stats = snmpwalk_cache_oid($device, $oid, $port_stats, "OLD-CISCO-INTERFACES-MIB"); }
@ -289,7 +294,7 @@ foreach ($ports as $port) {
}
// Overwrite ifSpeed with ifHighSpeed if it's over 1G
if (is_numeric($this_port['ifHighSpeed']) && $this_port['ifSpeed'] > '1000000000') {
if (is_numeric($this_port['ifHighSpeed']) && ($this_port['ifSpeed'] > '1000000000' || $this_port['ifSpeed'] == 0)) {
echo 'HighSpeed ';
$this_port['ifSpeed'] = ($this_port['ifHighSpeed'] * 1000000);
}
@ -328,6 +333,13 @@ foreach ($ports as $port) {
// Update IF-MIB data
foreach ($data_oids as $oid) {
if ($oid == 'ifAlias') {
if (get_dev_attrib($device, 'ifName', $port['ifName'])) {
$this_port['ifAlias'] = $port['ifAlias'];
}
}
if ($port[$oid] != $this_port[$oid] && !isset($this_port[$oid])) {
$port['update'][$oid] = array('NULL');
log_event($oid.': '.$port[$oid].' -> NULL', $device, 'interface', $port['port_id']);

Some files were not shown because too many files have changed in this diff Show More