From bf913f5a3bab36088be64d3ab2cc188b39c3db29 Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Thu, 27 Aug 2015 13:18:53 +0200 Subject: [PATCH 01/15] Add initial support for Proxmox VM network traffic. [WIP] --- html/includes/graphs/application/auth.inc.php | 8 +- .../application/proxmox_traffic.inc.php | 15 ++++ html/includes/print-menubar.php | 20 +++++ html/pages/proxmox.inc.php | 83 +++++++++++++++++++ html/pages/proxmox/vm.inc.php | 48 +++++++++++ includes/polling/applications/proxmox.inc.php | 74 +++++++++++++++++ includes/polling/unix-agent.inc.php | 3 +- 7 files changed, 248 insertions(+), 3 deletions(-) create mode 100644 html/includes/graphs/application/proxmox_traffic.inc.php create mode 100644 html/pages/proxmox.inc.php create mode 100644 html/pages/proxmox/vm.inc.php create mode 100644 includes/polling/applications/proxmox.inc.php diff --git a/html/includes/graphs/application/auth.inc.php b/html/includes/graphs/application/auth.inc.php index 15c8f01ca..23eea4141 100644 --- a/html/includes/graphs/application/auth.inc.php +++ b/html/includes/graphs/application/auth.inc.php @@ -3,7 +3,11 @@ 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; } diff --git a/html/includes/graphs/application/proxmox_traffic.inc.php b/html/includes/graphs/application/proxmox_traffic.inc.php new file mode 100644 index 000000000..e37cd00d9 --- /dev/null +++ b/html/includes/graphs/application/proxmox_traffic.inc.php @@ -0,0 +1,15 @@ += '5' && ($app_count) > "0") { 0) { +?> + +Proxmox » "; + +unset($sep); + +foreach ($pmxcl as $pmxc) { + if (isset($sep)) { echo $sep; }; + + if (var_eq('cluster', $pmxc['app_instance'])) { + echo ""; + } + + echo generate_link(nicecase($pmxc['app_instance']), array('page' => 'proxmox', 'cluster' => $pmxc['app_instance'])); + + if (var_eq('cluster', $pmxc['app_instance'])) { + echo ''; + } + + $sep = ' | '; +} + +print_optionbar_end(); + +if (!var_isset('cluster')) { + echo 'Select a cluster:'; + echo ''; +} elseif (!var_isset('vmid')) { + echo ''; +} else { + include("pages/proxmox/vm.inc.php"); +} + +$pagetitle[] = 'Proxmox'; diff --git a/html/pages/proxmox/vm.inc.php b/html/pages/proxmox/vm.inc.php new file mode 100644 index 000000000..cb43e3c9f --- /dev/null +++ b/html/pages/proxmox/vm.inc.php @@ -0,0 +1,48 @@ +'; +var_dump($vm); +print ''; +$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 '

'.$text.' '.$port['port'].'@'.$vm['description'].'

'; + + echo ""; + + include 'includes/print-graphrow.inc.php'; + + echo ''; + } +} + + +#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; +# $auth = true; +#} + diff --git a/includes/polling/applications/proxmox.inc.php b/includes/polling/applications/proxmox.inc.php new file mode 100644 index 000000000..65214d229 --- /dev/null +++ b/includes/polling/applications/proxmox.inc.php @@ -0,0 +1,74 @@ + $device['device_id'], 'app_type' => 'proxmox', 'app_instance' => $pmxcluster), 'applications', '`device_id` = ? AND `app_type` = ?', array($device['device_id'], 'proxmox')); + +$pmxcache = []; + +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; +} + +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; +} + +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); diff --git a/includes/polling/unix-agent.inc.php b/includes/polling/unix-agent.inc.php index 3d1754498..5b78b682c 100644 --- a/includes/polling/unix-agent.inc.php +++ b/includes/polling/unix-agent.inc.php @@ -50,6 +50,7 @@ if ($device['os_group'] == 'unix') { "mysql", "nginx", "bind", + "proxmox", "tinydns"); if (in_array($section, $agentapps)) { @@ -99,7 +100,7 @@ if ($device['os_group'] == 'unix') { if (file_exists("includes/polling/applications/$key.inc.php")) { d_echo("Enabling $key for ".$device['hostname']." if not yet enabled\n"); - if (in_array($key, array('apache', 'mysql', 'nginx'))) { + if (in_array($key, array('apache', 'mysql', 'nginx', 'proxmox'))) { if (dbFetchCell('SELECT COUNT(*) FROM `applications` WHERE `device_id` = ? AND `app_type` = ?', array($device['device_id'], $key)) == '0') { echo "Found new application '$key'\n"; dbInsert(array('device_id' => $device['device_id'], 'app_type' => $key), 'applications'); From 0153ace2e7da4e103849035939824e969b4a6473 Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Thu, 27 Aug 2015 13:28:35 +0200 Subject: [PATCH 02/15] Add SQL for proxmox --- sql-schema/067.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sql-schema/067.sql diff --git a/sql-schema/067.sql b/sql-schema/067.sql new file mode 100644 index 000000000..a3584ebbe --- /dev/null +++ b/sql-schema/067.sql @@ -0,0 +1,2 @@ +CREATE TABLE `proxmox` ( `id` int(11) NOT NULL AUTO_INCREMENT, `device_id` int(11) NOT NULL DEFAULT '0', `vmid` int(11) NOT NULL, `cluster` varchar(255) NOT NULL, `description` varchar(255) DEFAULT NULL, `last_seen` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `cluster_vm` (`cluster`,`vmid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `proxmox_ports` ( `id` int(11) NOT NULL AUTO_INCREMENT, `vm_id` int(11) NOT NULL, `port` varchar(10) NOT NULL, `last_seen` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `vm_port` (`vm_id`,`port`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; From a211b3706db8796b031b8b175fabff35cc099b95 Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Thu, 27 Aug 2015 13:48:04 +0200 Subject: [PATCH 03/15] We don't seem to need a multiplier here --- html/includes/graphs/application/proxmox_traffic.inc.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/html/includes/graphs/application/proxmox_traffic.inc.php b/html/includes/graphs/application/proxmox_traffic.inc.php index e37cd00d9..9c81416f8 100644 --- a/html/includes/graphs/application/proxmox_traffic.inc.php +++ b/html/includes/graphs/application/proxmox_traffic.inc.php @@ -7,8 +7,6 @@ if (is_file($mysql_rrd)) { $rrd_filename = $mysql_rrd; } -$multiplier = 8; - $ds_in = 'INOCTETS'; $ds_out = 'OUTOCTETS'; From 1595f03568826a9f73ef82db6d1902b77a54b87c Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Thu, 27 Aug 2015 21:06:07 +0200 Subject: [PATCH 04/15] Cleanup and show an app-page with the corresponding device --- html/includes/application/proxmox.inc.php | 18 +++++++++++ html/includes/functions.inc.php | 23 ++++++++++++++ html/pages/device/apps/proxmox.inc.php | 38 +++++++++++++++++++++++ html/pages/proxmox.inc.php | 38 ++--------------------- html/pages/proxmox/vm.inc.php | 3 -- 5 files changed, 81 insertions(+), 39 deletions(-) create mode 100644 html/includes/application/proxmox.inc.php create mode 100644 html/pages/device/apps/proxmox.inc.php diff --git a/html/includes/application/proxmox.inc.php b/html/includes/application/proxmox.inc.php new file mode 100644 index 000000000..dcc28d954 --- /dev/null +++ b/html/includes/application/proxmox.inc.php @@ -0,0 +1,18 @@ + '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 '

'.$text.' '.$port['port'].'@'.$vm['description'].'

'; + + echo ""; + + include 'includes/print-graphrow.inc.php'; + + echo ''; + } + } +} diff --git a/html/pages/proxmox.inc.php b/html/pages/proxmox.inc.php index fc04dac9f..9593992b0 100644 --- a/html/pages/proxmox.inc.php +++ b/html/pages/proxmox.inc.php @@ -1,40 +1,6 @@ '; foreach (proxmox_cluster_vms(var_get('cluster')) as $pmxvm) { - echo '
  • '.generate_link($pmxvm['vmid']." (".$pmxvm['description'].")", array('page' => 'proxmox', 'cluster' => $pmxc['app_instance'], 'vmid' => $pmxvm['vmid'])).'
  • '; + echo '
  • '.generate_link($pmxvm['vmid']." (".$pmxvm['description'].")", array('page' => 'proxmox', 'cluster' => var_get('cluster'), 'vmid' => $pmxvm['vmid'])).'
  • '; } echo ''; } else { diff --git a/html/pages/proxmox/vm.inc.php b/html/pages/proxmox/vm.inc.php index cb43e3c9f..2f9f14776 100644 --- a/html/pages/proxmox/vm.inc.php +++ b/html/pages/proxmox/vm.inc.php @@ -5,9 +5,6 @@ global $vars; $vm = proxmox_vm_info(var_get('vmid'), var_get('cluster')); -print '
    ';
    -var_dump($vm);
    -print '
    '; $graphs = array( 'proxmox_traffic' => 'Traffic', ); From fce9b44c32e49bdf6cdb68b8968bbea31a596257 Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Fri, 28 Aug 2015 11:01:36 +0200 Subject: [PATCH 05/15] Add licenses --- html/includes/application/proxmox.inc.php | 16 ++++++++++++++++ .../graphs/application/proxmox_traffic.inc.php | 17 +++++++++++++++++ html/pages/device/apps/proxmox.inc.php | 16 ++++++++++++++++ html/pages/proxmox.inc.php | 16 ++++++++++++++++ html/pages/proxmox/vm.inc.php | 15 +++++++++++++++ 5 files changed, 80 insertions(+) diff --git a/html/includes/application/proxmox.inc.php b/html/includes/application/proxmox.inc.php index dcc28d954..05448e1e3 100644 --- a/html/includes/application/proxmox.inc.php +++ b/html/includes/application/proxmox.inc.php @@ -1,5 +1,21 @@ + * + * 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 + */ + function proxmox_cluster_vms($c) { return dbFetchRows("SELECT * FROM proxmox WHERE cluster = ? ORDER BY vmid", array($c)); } diff --git a/html/includes/graphs/application/proxmox_traffic.inc.php b/html/includes/graphs/application/proxmox_traffic.inc.php index 9c81416f8..c83b6dc5c 100644 --- a/html/includes/graphs/application/proxmox_traffic.inc.php +++ b/html/includes/graphs/application/proxmox_traffic.inc.php @@ -1,4 +1,21 @@ + * + * 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'; $mysql_rrd = $config['rrd_dir'].'/proxmox/'.$vars['cluster'].'/'.$vars['vmid'].'_netif_'.$vars['port'].'.rrd'; diff --git a/html/pages/device/apps/proxmox.inc.php b/html/pages/device/apps/proxmox.inc.php index 06a5d0bc8..bc661cfb3 100644 --- a/html/pages/device/apps/proxmox.inc.php +++ b/html/pages/device/apps/proxmox.inc.php @@ -1,5 +1,21 @@ + * + * 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'); global $config; diff --git a/html/pages/proxmox.inc.php b/html/pages/proxmox.inc.php index 9593992b0..e7ced1f88 100644 --- a/html/pages/proxmox.inc.php +++ b/html/pages/proxmox.inc.php @@ -1,5 +1,21 @@ + * + * 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'); $graphs['proxmox'] = array( 'netif' diff --git a/html/pages/proxmox/vm.inc.php b/html/pages/proxmox/vm.inc.php index 2f9f14776..1300bf951 100644 --- a/html/pages/proxmox/vm.inc.php +++ b/html/pages/proxmox/vm.inc.php @@ -1,5 +1,20 @@ + * + * 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 + */ global $vars; From 822a93b509d4e1849e9de68163e3c168bb65c030 Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Fri, 28 Aug 2015 11:35:34 +0200 Subject: [PATCH 06/15] Do not run the Proxmox-stuff unless it is explicitly enabled in the config --- html/pages/device/apps/proxmox.inc.php | 55 ++++++------ includes/polling/applications/proxmox.inc.php | 87 ++++++++++--------- 2 files changed, 75 insertions(+), 67 deletions(-) diff --git a/html/pages/device/apps/proxmox.inc.php b/html/pages/device/apps/proxmox.inc.php index bc661cfb3..5adf31ff1 100644 --- a/html/pages/device/apps/proxmox.inc.php +++ b/html/pages/device/apps/proxmox.inc.php @@ -20,35 +20,40 @@ include('includes/application/proxmox.inc.php'); global $config; -$graphs = array( - 'proxmox_traffic' => 'Traffic', -); +if (!isset($config['enable_proxmox']) || !$config['enable_proxmox']) { + print_error('Proxmox agent was discovered on this host. Please enable Proxmox in your config.'); +} else { -foreach (proxmox_node_vms(var_get('device')) as $nvm) { - $vm = proxmox_vm_info($nvm['vmid'], $nvm['cluster']); + $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 '

    '.$text.' '.$port['port'].'@'.$vm['description'].'

    '; - - echo ""; + foreach (proxmox_node_vms(var_get('device')) as $nvm) { + $vm = proxmox_vm_info($nvm['vmid'], $nvm['cluster']); - include 'includes/print-graphrow.inc.php'; + foreach ($vm['ports'] as $port) { + foreach ($graphs as $key => $text) { + $graph_type = 'proxmox_traffic'; - echo ''; + $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 '

    '.$text.' '.$port['port'].'@'.$vm['description'].'

    '; + + echo ""; + + include 'includes/print-graphrow.inc.php'; + + echo ''; + } } } } diff --git a/includes/polling/applications/proxmox.inc.php b/includes/polling/applications/proxmox.inc.php index 65214d229..bb6dd95e7 100644 --- a/includes/polling/applications/proxmox.inc.php +++ b/includes/polling/applications/proxmox.inc.php @@ -1,21 +1,9 @@ $device['device_id'], 'app_type' => 'proxmox', 'app_instance' => $pmxcluster), 'applications', '`device_id` = ? AND `app_type` = ?', array($device['device_id'], 'proxmox')); - -$pmxcache = []; - 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']; @@ -37,38 +25,53 @@ function proxmox_vm_exists($i, $c, &$pmxcache) { return false; } -foreach ($pmxlines as $vm) { - list($vmid, $vmport, $vmpin, $vmpout, $vmdesc) = explode('/', $vm, 5); +$pmxlines = explode("\n", $proxmox); - $rrd_filename = join('/', array( - $pmxcdir, - $vmid.'_netif_'.$vmport.'.rrd')); +if (count($pmxlines) > 2) { + $pmxcluster = array_shift($pmxlines); - 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']); + $pmxcdir = join('/', array($config['rrd_dir'],'proxmox',$pmxcluster)); + if (!is_dir($pmxcdir)) { + mkdir($pmxcdir, 0775, true); } - 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'); + 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); } - -unset($pmxlines); -unset($pmxcluster); -unset($pmxcdir); -unset($proxmox); -unset($pmxcache); From d704488413b7084eb5b7d40fe4e967f854c27a51 Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Fri, 28 Aug 2015 13:31:44 +0200 Subject: [PATCH 07/15] Add documentation --- doc/Extensions/Proxmox.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 doc/Extensions/Proxmox.md diff --git a/doc/Extensions/Proxmox.md b/doc/Extensions/Proxmox.md new file mode 100644 index 000000000..0691e1d27 --- /dev/null +++ b/doc/Extensions/Proxmox.md @@ -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. From f3211733cd76213d6f0ab203df0983ac7d9a823e Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Fri, 28 Aug 2015 14:21:07 +0200 Subject: [PATCH 08/15] Add missing SQL statement --- sql-schema/067.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/sql-schema/067.sql b/sql-schema/067.sql index a3584ebbe..5ad0781bd 100644 --- a/sql-schema/067.sql +++ b/sql-schema/067.sql @@ -1,2 +1,3 @@ CREATE TABLE `proxmox` ( `id` int(11) NOT NULL AUTO_INCREMENT, `device_id` int(11) NOT NULL DEFAULT '0', `vmid` int(11) NOT NULL, `cluster` varchar(255) NOT NULL, `description` varchar(255) DEFAULT NULL, `last_seen` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `cluster_vm` (`cluster`,`vmid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `proxmox_ports` ( `id` int(11) NOT NULL AUTO_INCREMENT, `vm_id` int(11) NOT NULL, `port` varchar(10) NOT NULL, `last_seen` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `vm_port` (`vm_id`,`port`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; +ALTER TABLE `applications` ADD COLUMN `app_instance` varchar(255) NOT NULL; From 45dd02d301fa989a6be89f8a2faa3dff1a7118ff Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Fri, 28 Aug 2015 14:34:25 +0200 Subject: [PATCH 09/15] %s/mysql/proxmox/g --- html/includes/graphs/application/proxmox_traffic.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/html/includes/graphs/application/proxmox_traffic.inc.php b/html/includes/graphs/application/proxmox_traffic.inc.php index c83b6dc5c..26d6e6682 100644 --- a/html/includes/graphs/application/proxmox_traffic.inc.php +++ b/html/includes/graphs/application/proxmox_traffic.inc.php @@ -18,10 +18,10 @@ require 'includes/graphs/common.inc.php'; -$mysql_rrd = $config['rrd_dir'].'/proxmox/'.$vars['cluster'].'/'.$vars['vmid'].'_netif_'.$vars['port'].'.rrd'; +$proxmox_rrd = $config['rrd_dir'].'/proxmox/'.$vars['cluster'].'/'.$vars['vmid'].'_netif_'.$vars['port'].'.rrd'; -if (is_file($mysql_rrd)) { - $rrd_filename = $mysql_rrd; +if (is_file($proxmox_rrd)) { + $rrd_filename = $proxmox_rrd; } $ds_in = 'INOCTETS'; From 34abb859df61756059ae64c2e8aeb0fdd263a259 Mon Sep 17 00:00:00 2001 From: Mark Schouten Date: Fri, 28 Aug 2015 17:01:51 +0200 Subject: [PATCH 10/15] Remove proxmox as a page and add is as an app. Also, this introduces actual working app_instance stuff into LibreNMS --- html/includes/print-menubar.php | 39 +++++++----------- html/pages/apps/proxmox.inc.php | 52 ++++++++++++++++++++++++ html/pages/apps/proxmox/vm.inc.php | 35 ++++++++++++++++ html/pages/proxmox.inc.php | 65 ------------------------------ html/pages/proxmox/vm.inc.php | 60 --------------------------- 5 files changed, 102 insertions(+), 149 deletions(-) create mode 100644 html/pages/apps/proxmox.inc.php create mode 100644 html/pages/apps/proxmox/vm.inc.php delete mode 100644 html/pages/proxmox.inc.php delete mode 100644 html/pages/proxmox/vm.inc.php diff --git a/html/includes/print-menubar.php b/html/includes/print-menubar.php index f24eb41c0..1cf1747e0 100644 --- a/html/includes/print-menubar.php +++ b/html/includes/print-menubar.php @@ -360,21 +360,32 @@ foreach (array_keys($menu_sensors) as $item) { = '5' && ($app_count) > "0") { +if ($_SESSION['userlevel'] >= '5' && count($app_list) > "0") { ?>