mirror of
https://github.com/Cacti/cacti.git
synced 2026-10-27 15:17:05 +09:00
* issue#7024: do not delete still-running poller_time rows on cycle start The overrun path deleted every poller_time row for the poller, including the in-flight ones it had just counted, so overrunning processes lost their tracking. Restrict the delete to completed rows. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7028: restore identifier and connection safety in the db layer _db_replace interpolated caller-supplied column keys as backtick identifiers without escaping, and db_commit_transaction checked @@in_transaction on the default connection rather than the one passed in. Both were correct on 1.2.x and regressed on develop. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7341: size the CSV export maxrows to the requested span The export hardcoded --maxrows=10000, truncating wide date ranges regardless of the data source profile step. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7421: offset automation_get_next_host through the 32-bit integer The hand-rolled octet walk subtracted the wrong magnitude per octet and emitted out-of-range octets for ranges wider than a /16. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7030: skip the poller_output ENGINE=MEMORY conversion when already applied The output-table refresh ran ALTER TABLE poller_output ENGINE=MEMORY every cycle even though the swapped-in copy already inherits the engine, adding a metadata-locking DDL to the hot path. Probe the current engine and convert only when needed. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7342: prefer snmpEngineTime only when it covers system uptime update_system_mibs preferred snmpEngineTime (x100) over sysUpTime whenever it was present, so an SNMP engine that restarts independently of the system (for example OpenBSD snmpd) made the stored uptime drop, which reads as a reboot and forces a perpetual reindex with mass 'U' results. Capture both values and use snmpEngineTime only when it is at least the system uptime, which still covers the 32-bit sysUpTime wrap. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7403: scale lmsensors readings in the get path like the query path The get path returned the raw milli-unit SNMP counter while the query path divided voltage and temperature by 1000 (and corrected negative voltages), so a get gave values 1000x too large. Apply the same scaling before returning. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7029: propagate the reconnected handle back to the caller db_check_reconnect() closed the dead connection, opened a new one, and returned true without giving the new handle back, so the db_execute_prepared retry ran its query against the connection that was just closed. Take $db_conn by reference and assign the fresh handle; the one caller that passed a literal false now passes a variable. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: refresh sink inventory baseline Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: refresh architectural hotspots baseline Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7474: return valid after correcting the theme to selected_theme is_valid_theme() corrected an invalid theme to selected_theme but left $valid false, so callers saw the theme as invalid even though it had been fixed. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7462: allow SELECT aliases as sortable automation columns site_name and host_template_name are aliases (s.name AS site_name), valid in ORDER BY but not real columns, so api_automation_column_exists() rejected them and the site-name sort silently failed. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7456: bind the OS value in the automation OS filter The OS filter built 'os = ?' but bound the network value, so filtering by OS matched on the wrong input. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7491: filter host_template_id against its own column html_make_device_where() compared h.location to the host_template_id value instead of h.host_template_id. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7479: apply the hostname and description filters in get_hosts The REST get_hosts() honored host_id/poller/site/template/location but ignored the hostname and description filters its callers pass; add them as bound LIKE. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * issue#7475: authorize a direct client-IP poller match before the hostname guard A poller configured by IP with no hostname-based pollers was rejected because the empty-hostname guard ran before the direct-match check, even though the client address exactly matched a poller's configured address. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Guard two divisors that PHP 8 makes fatal Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * docs: consolidate functional fix changelog * test: cover consolidated functional fixes * docs: identify consolidated functional fixes --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
718 lines
21 KiB
PHP
718 lines
21 KiB
PHP
<?php
|
|
/*
|
|
+-------------------------------------------------------------------------+
|
|
| Copyright (C) 2004-2026 The Cacti Group |
|
|
| |
|
|
| 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 2 |
|
|
| 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. |
|
|
+-------------------------------------------------------------------------+
|
|
| Cacti: The Complete RRDtool-based Graphing Solution |
|
|
+-------------------------------------------------------------------------+
|
|
| This code is designed, written, and maintained by the Cacti Group. See |
|
|
| about.php and/or the AUTHORS file for specific developer information. |
|
|
+-------------------------------------------------------------------------+
|
|
| http://www.cacti.net/ |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
require('./include/auth.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/api_aggregate.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/api_automation.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/api_data_source.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/api_device.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/api_graph.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/api_tree.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/html_form_template.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/data_query.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/html_graph.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/html_tree.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/ping.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/poller.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/reports.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/rrd.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/snmp.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/template.php');
|
|
require_once(CACTI_PATH_LIBRARY . '/utility.php');
|
|
|
|
$actions = [
|
|
1 => __('Add Device'),
|
|
2 => __('Delete Device')
|
|
];
|
|
|
|
$os_arr = array_rekey(db_fetch_assoc('SELECT DISTINCT os
|
|
FROM automation_devices
|
|
WHERE os IS NOT NULL AND os!=""'), 'os', 'os');
|
|
|
|
$status_arr = [
|
|
__('Down'),
|
|
__('Up')
|
|
];
|
|
|
|
$networks = array_rekey(db_fetch_assoc('SELECT an.id, an.name
|
|
FROM automation_networks AS an
|
|
INNER JOIN automation_devices AS ad
|
|
ON an.id=ad.network_id
|
|
ORDER BY name'), 'id', 'name');
|
|
|
|
set_default_action();
|
|
|
|
switch(grv('action')) {
|
|
case 'purge':
|
|
purge_discovery_results();
|
|
|
|
break;
|
|
case 'actions':
|
|
form_actions();
|
|
|
|
break;
|
|
case 'export':
|
|
export_discovery_results();
|
|
|
|
break;
|
|
default:
|
|
display_discovery_page();
|
|
|
|
break;
|
|
}
|
|
|
|
function form_actions() : void {
|
|
global $actions, $availability_options;
|
|
|
|
// ================= input validation =================
|
|
gfrv('drp_action', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^([a-zA-Z0-9_]+)$/']]);
|
|
// ====================================================
|
|
|
|
// if we are to save this form, instead of display it
|
|
if (isrv('selected_items')) {
|
|
$selected_items = sanitize_unserialize_selected_items(gnrv('selected_items'));
|
|
|
|
if ($selected_items != false) {
|
|
if (gnrv('drp_action') == '1') { // add to cacti
|
|
$i = 0;
|
|
|
|
foreach ($selected_items as $id) {
|
|
$d = db_fetch_row_prepared('SELECT * FROM automation_devices WHERE id = ?', [$id]);
|
|
$d['poller_id'] = gfrv('poller_id');
|
|
$d['host_template'] = gfrv('host_template');
|
|
$d['availability_method'] = gfrv('availability_method');
|
|
$d['notes'] = __('Added manually through device automation interface.');
|
|
$d['snmp_sysName'] = $d['sysName'];
|
|
|
|
// pull ping options from network_id
|
|
$n = db_fetch_row_prepared('SELECT * FROM automation_networks WHERE id = ?', [$d['network_id']]);
|
|
|
|
if (cacti_sizeof($n)) {
|
|
$d['ping_method'] = $n['ping_method'];
|
|
$d['ping_port'] = $n['ping_port'];
|
|
$d['ping_timeout'] = $n['ping_timeout'];
|
|
$d['ping_retries'] = $n['ping_retries'];
|
|
}
|
|
|
|
$host_id = automation_add_device($d, true);
|
|
$description = (trim($d['hostname']) != '' ? $d['hostname'] : $d['ip']);
|
|
|
|
if ($host_id) {
|
|
raise_message('automation_msg_' . $i, __esc('Device %s Added to Cacti', $description), MESSAGE_LEVEL_INFO);
|
|
} else {
|
|
raise_message('automation_msg_' . $i, __esc('Device %s Not Added to Cacti', $description), MESSAGE_LEVEL_ERROR);
|
|
}
|
|
|
|
$i++;
|
|
}
|
|
} elseif (gnrv('drp_action') == 2) { // remove device
|
|
foreach ($selected_items as $id) {
|
|
db_execute_prepared('DELETE FROM automation_devices WHERE id = ?', [$id]);
|
|
}
|
|
|
|
raise_message('automation_remove', __('Devices Removed from Cacti Automation database'), MESSAGE_LEVEL_INFO);
|
|
}
|
|
}
|
|
|
|
header('Location: automation_devices.php');
|
|
|
|
exit;
|
|
} else {
|
|
$ilist = '';
|
|
$iarray = [];
|
|
|
|
// default variables
|
|
$pollers = [];
|
|
$host_templates = [];
|
|
$poller_id = 0;
|
|
|
|
$availability_method = 0;
|
|
$host_template = 0;
|
|
|
|
// loop through each of the graphs selected on the previous page and get more info about them
|
|
foreach ($_POST as $var => $val) {
|
|
if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) {
|
|
// ================= input validation =================
|
|
input_validate_input_number($matches[1], 'chk[1]');
|
|
// ====================================================
|
|
|
|
$ilist .= '<li>' . htmle(db_fetch_cell_prepared('SELECT CONCAT(IF(hostname!="", hostname, "unknown"), " (", ip, ")") FROM automation_devices WHERE id = ?', [$matches[1]])) . '</li>';
|
|
|
|
$iarray[] = $matches[1];
|
|
}
|
|
}
|
|
|
|
if (cacti_sizeof($iarray) && grv('drp_action') == '1') { // add
|
|
$pollers = array_rekey(
|
|
db_fetch_assoc_prepared('SELECT id, name
|
|
FROM poller
|
|
ORDER BY name'),
|
|
'id', 'name'
|
|
);
|
|
|
|
$host_templates = array_rekey(
|
|
db_fetch_assoc_prepared('SELECT id, name
|
|
FROM host_template
|
|
ORDER BY name'),
|
|
'id', 'name'
|
|
);
|
|
|
|
$poller_id = db_fetch_cell_prepared('SELECT id FROM poller WHERE disabled = "" LIMIT 1');
|
|
|
|
if (empty($poller_id)) {
|
|
$poller_id = $pollers[0]['id'];
|
|
}
|
|
|
|
$devices = db_fetch_assoc('SELECT id, sysName, sysDescr
|
|
FROM automation_devices
|
|
WHERE id IN (' . implode(',', $iarray) . ')');
|
|
|
|
foreach ($devices as $device) {
|
|
$os = automation_find_os($device['sysDescr'], '', $device['sysName']);
|
|
|
|
if (isset($os['host_template']) && $os['host_template'] > 0) {
|
|
if ($host_template == 0) {
|
|
$host_template = $os['host_template'];
|
|
$availability_method = $os['availability_method'];
|
|
} elseif ($host_template != $os['host_template']) {
|
|
$host_template = 0;
|
|
$availability_method = 0;
|
|
|
|
break;
|
|
}
|
|
} else {
|
|
$host_template = 0;
|
|
$availability_method = 0;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$form_data = [
|
|
'general' => [
|
|
'page' => 'automation_devices.php',
|
|
'actions' => $actions,
|
|
'optvar' => 'drp_action',
|
|
'item_array' => $iarray,
|
|
'item_list' => $ilist
|
|
],
|
|
'options' => [
|
|
1 => [
|
|
'smessage' => __('Click \'Continue\' to Add the following Discovered Device to Cacti.'),
|
|
'pmessage' => __('Click \'Continue\' to Add the following Discovered Devices to Cacti.'),
|
|
'scont' => __('Add Discovered Device'),
|
|
'pcont' => __('Add Discovered Devices'),
|
|
'extra' => [
|
|
'poller_id' => [
|
|
'method' => 'drop_array',
|
|
'title' => __('Poller'),
|
|
'array' => $pollers,
|
|
'default' => $poller_id,
|
|
'name' => 'name',
|
|
'id' => 'id',
|
|
],
|
|
'host_template' => [
|
|
'method' => 'drop_array',
|
|
'title' => __('Device Template'),
|
|
'array' => $host_templates,
|
|
'default' => $host_template,
|
|
'name' => 'name',
|
|
'id' => 'id',
|
|
],
|
|
'availability_method' => [
|
|
'method' => 'drop_array',
|
|
'title' => __('Availability Method'),
|
|
'array' => $availability_options,
|
|
'default' => $availability_method,
|
|
'name' => 'name',
|
|
'id' => 'id',
|
|
],
|
|
]
|
|
],
|
|
2 => [
|
|
'smessage' => __('Click \'Continue\' to Remove the following Discovered Device.'),
|
|
'pmessage' => __('Click \'Continue\' to Remove the following Discovered Devices.'),
|
|
'scont' => __('Remove Discovered Device'),
|
|
'pcont' => __('Remove Discovered Devices'),
|
|
]
|
|
]
|
|
];
|
|
|
|
form_continue_confirmation($form_data);
|
|
}
|
|
}
|
|
|
|
function display_discovery_page() : void {
|
|
global $item_rows, $os_arr, $status_arr, $networks, $actions;
|
|
|
|
top_header();
|
|
|
|
draw_automation_devices_filter(true);
|
|
|
|
$total_rows = 0;
|
|
|
|
if (grv('rows') == '-1') {
|
|
$rows = read_config_option('num_rows_table');
|
|
} else {
|
|
$rows = grv('rows');
|
|
}
|
|
|
|
$results = get_discovery_results($total_rows, $rows);
|
|
|
|
// generate page list
|
|
$nav = html_nav_bar('automation_devices.php', MAX_DISPLAY_PAGES, grv('page'), $rows, $total_rows, 12, __('Devices'), 'page', 'main');
|
|
|
|
form_start('automation_devices.php', 'chk');
|
|
|
|
print $nav;
|
|
|
|
html_start_box('', '100%', false, 3, 'center', '');
|
|
|
|
$display_text = [
|
|
'host_id' => [
|
|
'display' => __('Imported Device'),
|
|
'align' => 'left',
|
|
'sort' => 'ASC'
|
|
],
|
|
'hostname' => [
|
|
'display' => __('Device Name'),
|
|
'align' => 'left',
|
|
'sort' => 'ASC'
|
|
],
|
|
'ip' => [
|
|
'display' => __('IP'),
|
|
'align' => 'left',
|
|
'sort' => 'ASC'
|
|
],
|
|
'network_id' => [
|
|
'display' => __('Network'),
|
|
'align' => 'left',
|
|
'sort' => 'ASC'
|
|
],
|
|
'sysName' => [
|
|
'display' => __('SNMP Name'),
|
|
'align' => 'left',
|
|
'sort' => 'ASC'
|
|
],
|
|
'sysLocation' => [
|
|
'display' => __('Location'),
|
|
'align' => 'left',
|
|
'sort' => 'ASC'
|
|
],
|
|
'sysContact' => [
|
|
'display' => __('Contact'),
|
|
'align' => 'left',
|
|
'sort' => 'ASC'
|
|
],
|
|
'sysDescr' => [
|
|
'display' => __('Description'),
|
|
'align' => 'left',
|
|
'sort' => 'ASC'
|
|
],
|
|
'os' => [
|
|
'display' => __('OS'),
|
|
'align' => 'left',
|
|
'sort' => 'ASC'
|
|
],
|
|
'time' => [
|
|
'display' => __('Uptime'),
|
|
'align' => 'right',
|
|
'sort' => 'DESC'
|
|
],
|
|
'snmp' => [
|
|
'display' => __('SNMP'),
|
|
'align' => 'right',
|
|
'sort' => 'DESC'
|
|
],
|
|
'up' => [
|
|
'display' => __('Status'),
|
|
'align' => 'right',
|
|
'sort' => 'ASC'
|
|
],
|
|
'mytime' => [
|
|
'display' => __('Last Check'),
|
|
'align' => 'right',
|
|
'sort' => 'DESC'
|
|
]
|
|
];
|
|
|
|
html_header_sort_checkbox($display_text, grv('sort_column'), grv('sort_direction'), false);
|
|
|
|
$snmp_version = read_config_option('snmp_version');
|
|
$snmp_port = read_config_option('snmp_port');
|
|
$snmp_timeout = read_config_option('snmp_timeout');
|
|
$snmp_username = read_config_option('snmp_username');
|
|
$snmp_password = read_config_option('snmp_password');
|
|
$max_oids = read_config_option('max_get_size');
|
|
$ping_method = read_config_option('ping_method');
|
|
$availability_method = read_config_option('availability_method');
|
|
|
|
$status = ["<span class='deviceDown'>" . __('Down') . '</span>', "<span class='deviceUp'>" . __('Up') . '</span>'];
|
|
|
|
if (cacti_sizeof($results)) {
|
|
foreach ($results as $host) {
|
|
$description = get_device_description($host['host_id']);
|
|
$network = get_network_description($host['network_id']);
|
|
|
|
form_alternate_row('line' . base64_encode($host['ip']), true);
|
|
|
|
if ($host['hostname'] == '') {
|
|
$host['hostname'] = __('Not Detected');
|
|
}
|
|
|
|
form_selectable_cell(filter_value($description, ''), $host['id']);
|
|
form_selectable_cell(filter_value($host['hostname'], grv('filter')), $host['id']);
|
|
form_selectable_cell(filter_value($host['ip'], grv('filter')), $host['id']);
|
|
form_selectable_cell(filter_value($network, ''), $host['id']);
|
|
form_selectable_cell(filter_value(snmp_data($host['sysName']), grv('filter')), $host['id'], '', 'text-align:left');
|
|
form_selectable_cell(filter_value(snmp_data($host['sysLocation']), grv('filter')), $host['id'], '', 'text-align:left');
|
|
form_selectable_cell(filter_value(snmp_data($host['sysContact']), grv('filter')), $host['id'], '', 'text-align:left');
|
|
form_selectable_cell(filter_value(snmp_data($host['sysDescr']), grv('filter')), $host['id'], '', 'text-align:left;white-space:normal;');
|
|
form_selectable_cell(filter_value(snmp_data($host['os']), grv('filter')), $host['id'], '', 'text-align:left');
|
|
form_selectable_cell(snmp_data(get_uptime($host)), $host['id'], '', 'text-align:right');
|
|
form_selectable_cell($status[$host['snmp']], $host['id'], '', 'text-align:right');
|
|
form_selectable_cell($status[$host['up']], $host['id'], '', 'text-align:right');
|
|
form_selectable_cell(substr($host['mytime'],0,16), $host['id'], '', 'text-align:right');
|
|
form_checkbox_cell($host['ip'], $host['id']);
|
|
|
|
form_end_row();
|
|
}
|
|
} else {
|
|
print '<tr class="tableRow odd"><td colspan="' . (cacti_sizeof($display_text) + 1) . '"><em>' . __('No Devices Found') . '</em></td></tr>';
|
|
}
|
|
|
|
html_end_box(false);
|
|
|
|
if (cacti_sizeof($results)) {
|
|
print $nav;
|
|
}
|
|
|
|
// draw the dropdown containing a list of available actions for this form
|
|
draw_actions_dropdown($actions);
|
|
|
|
form_end();
|
|
|
|
bottom_footer();
|
|
}
|
|
|
|
function get_device_description(int $id) : string {
|
|
if ($id > 0) {
|
|
$description = db_fetch_cell_prepared('SELECT description FROM host WHERE id = ?', [$id]);
|
|
|
|
if (empty($description)) {
|
|
return __('Removed from Cacti');
|
|
} else {
|
|
return $description;
|
|
}
|
|
} else {
|
|
return __('Not In Cacti');
|
|
}
|
|
}
|
|
|
|
function get_network_description(int $id) : string {
|
|
if ($id > 0) {
|
|
$description = db_fetch_cell_prepared('SELECT name FROM automation_networks WHERE id = ?', [$id]);
|
|
|
|
if (empty($description)) {
|
|
return __('Removed from Cacti');
|
|
} else {
|
|
return $description;
|
|
}
|
|
} else {
|
|
return __('Invalid Network');
|
|
}
|
|
}
|
|
|
|
function get_discovery_results(int &$total_rows = 0, int $rows = 0, bool $export = false) : array {
|
|
global $os_arr, $status_arr, $networks, $actions;
|
|
|
|
$sql_where = '';
|
|
$status = grv('status');
|
|
$network = grv('network');
|
|
$snmp = grv('snmp');
|
|
$os = grv('os');
|
|
$filter = grv('filter');
|
|
|
|
$sql_where = '';
|
|
$sql_params = [];
|
|
|
|
if ($status != '-1') {
|
|
$sql_where .= 'WHERE up = ?';
|
|
$sql_params[] = $status;
|
|
}
|
|
|
|
if ($network > 0) {
|
|
$sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . 'network_id = ?';
|
|
$sql_params[] = $network;
|
|
}
|
|
|
|
if ($snmp != '-1') {
|
|
$sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . 'snmp = ?';
|
|
$sql_params[] = $snmp;
|
|
}
|
|
|
|
if ($os != '-1' && in_array($os, $os_arr, true)) {
|
|
$sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . 'os = ?';
|
|
$sql_params[] = $os;
|
|
}
|
|
|
|
if ($filter != '') {
|
|
$sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') .
|
|
'(hostname LIKE ? OR ip LIKE ? OR sysName LIKE ? OR sysDescr LIKE ? OR sysLocation LIKE ? OR sysContact LIKE ?)';
|
|
|
|
$sql_params[] = "%$filter%";
|
|
$sql_params[] = "%$filter%";
|
|
$sql_params[] = "%$filter%";
|
|
$sql_params[] = "%$filter%";
|
|
$sql_params[] = "%$filter%";
|
|
$sql_params[] = "%$filter%";
|
|
}
|
|
|
|
if ($export) {
|
|
return db_fetch_assoc_prepared("SELECT *
|
|
FROM automation_devices
|
|
$sql_where
|
|
ORDER BY INET_ATON(ip)",
|
|
$sql_params);
|
|
} else {
|
|
$total_rows = db_fetch_cell_prepared("SELECT
|
|
COUNT(*)
|
|
FROM automation_devices
|
|
$sql_where",
|
|
$sql_params);
|
|
|
|
$page = grv('page');
|
|
$sql_order = get_order_string();
|
|
$sql_limit = ' LIMIT ' . ($rows * ($page - 1)) . ',' . $rows;
|
|
|
|
$sql_query = "SELECT *,sysUpTime snmp_sysUpTimeInstance, FROM_UNIXTIME(time) AS mytime
|
|
FROM automation_devices
|
|
$sql_where
|
|
$sql_order
|
|
$sql_limit";
|
|
|
|
return db_fetch_assoc_prepared($sql_query, $sql_params);
|
|
}
|
|
}
|
|
|
|
function create_automation_devices_filter() : array {
|
|
global $item_rows, $os_arr, $status_arr, $networks;
|
|
|
|
$any = [-1 => __('Any')];
|
|
$networks_arr = $any + $networks;
|
|
$status_arr = $any + $status_arr;
|
|
$os_arr = $any + $os_arr;
|
|
|
|
return [
|
|
'rows' => [
|
|
[
|
|
'filter' => [
|
|
'method' => 'textbox',
|
|
'friendly_name' => __('Search'),
|
|
'filter' => FILTER_DEFAULT,
|
|
'placeholder' => __('Enter a search term'),
|
|
'size' => '30',
|
|
'default' => '',
|
|
'pageset' => true,
|
|
'max_length' => '120',
|
|
'value' => ''
|
|
],
|
|
'network' => [
|
|
'method' => 'drop_array',
|
|
'friendly_name' => __('Network'),
|
|
'filter' => FILTER_VALIDATE_INT,
|
|
'default' => '-1',
|
|
'pageset' => true,
|
|
'array' => $networks_arr,
|
|
'value' => '-1'
|
|
]
|
|
],
|
|
[
|
|
'status' => [
|
|
'method' => 'drop_array',
|
|
'friendly_name' => __('Status'),
|
|
'filter' => FILTER_VALIDATE_INT,
|
|
'default' => '-1',
|
|
'pageset' => true,
|
|
'array' => $status_arr,
|
|
'value' => '-1'
|
|
],
|
|
'os' => [
|
|
'method' => 'drop_array',
|
|
'friendly_name' => __('OS'),
|
|
'filter' => FILTER_DEFAULT,
|
|
'default' => '-1',
|
|
'pageset' => true,
|
|
'array' => $os_arr,
|
|
'value' => '-1'
|
|
],
|
|
'snmp' => [
|
|
'method' => 'drop_array',
|
|
'friendly_name' => __('SNMP'),
|
|
'filter' => FILTER_VALIDATE_INT,
|
|
'default' => '-1',
|
|
'pageset' => true,
|
|
'array' => $status_arr,
|
|
'value' => '-1'
|
|
],
|
|
'rows' => [
|
|
'method' => 'drop_array',
|
|
'friendly_name' => __('Devices'),
|
|
'filter' => FILTER_VALIDATE_INT,
|
|
'default' => '-1',
|
|
'pageset' => true,
|
|
'array' => $item_rows,
|
|
'value' => '-1'
|
|
]
|
|
]
|
|
],
|
|
'buttons' => [
|
|
'go' => [
|
|
'method' => 'submit',
|
|
'display' => __('Go'),
|
|
'title' => __('Apply filter to table'),
|
|
],
|
|
'clear' => [
|
|
'method' => 'button',
|
|
'display' => __('Clear'),
|
|
'title' => __('Reset filter to default values'),
|
|
],
|
|
'export' => [
|
|
'method' => 'button',
|
|
'display' => __('Export'),
|
|
'action' => 'default',
|
|
'title' => __('Export the Discovered Devices to CSV'),
|
|
'callback' => 'document.location = \'automation_devices.php?action=export\''
|
|
],
|
|
'purge' => [
|
|
'method' => 'button',
|
|
'display' => __('Purge'),
|
|
'action' => 'default',
|
|
'title' => __('Purge the Discovered Devices from the Database'),
|
|
]
|
|
],
|
|
'sort' => [
|
|
'sort_column' => 'hostname',
|
|
'sort_direction' => 'ASC'
|
|
]
|
|
];
|
|
}
|
|
|
|
function draw_automation_devices_filter(bool $render = false) : void {
|
|
global $item_rows, $filters, $os_arr, $status_arr, $networks, $actions;
|
|
|
|
$filters = create_automation_devices_filter();
|
|
|
|
// create the page filter
|
|
$pageFilter = new CactiTableFilter(__('Discovered Devices'), 'automation_devices.php', 'form_devices', 'sess_autom_device');
|
|
|
|
$pageFilter->rows_label = __('Devices');
|
|
$pageFilter->set_filter_array($filters);
|
|
|
|
if ($render) {
|
|
$pageFilter->render();
|
|
} else {
|
|
$pageFilter->sanitize();
|
|
}
|
|
}
|
|
|
|
function export_discovery_results() : void {
|
|
draw_automation_devices_filter(false);
|
|
|
|
$total_rows = 0;
|
|
|
|
$results = get_discovery_results($total_rows, 0, true);
|
|
|
|
header('Content-type: application/csv');
|
|
header('Content-Disposition: attachment; filename=discovery_results.csv');
|
|
print implode(',', [
|
|
cacti_csv_cell('Host'),
|
|
cacti_csv_cell('IP'),
|
|
cacti_csv_cell('System Name'),
|
|
cacti_csv_cell('System Location'),
|
|
cacti_csv_cell('System Contact'),
|
|
cacti_csv_cell('System Description'),
|
|
cacti_csv_cell('OS'),
|
|
cacti_csv_cell('Uptime'),
|
|
cacti_csv_cell('SNMP'),
|
|
cacti_csv_cell('Status')
|
|
]) . "\n";
|
|
|
|
if (cacti_sizeof($results)) {
|
|
foreach ($results as $host) {
|
|
if (isset($host['sysUpTime']) && $host['sysUpTime'] != 0) {
|
|
$days = intval($host['sysUpTime'] / 8640000);
|
|
$hours = intval(($host['sysUpTime'] - ($days * 8640000)) / 360000);
|
|
$uptime = $days . ' days ' . $hours . ' hours';
|
|
} else {
|
|
$uptime = '';
|
|
}
|
|
|
|
print implode(',', [
|
|
cacti_csv_cell($host['hostname'] == '' ? __('Not Detected') : $host['hostname']),
|
|
cacti_csv_cell($host['ip']),
|
|
cacti_csv_cell(export_data($host['sysName'])),
|
|
cacti_csv_cell(export_data($host['sysLocation'])),
|
|
cacti_csv_cell(export_data($host['sysContact'])),
|
|
cacti_csv_cell(export_data($host['sysDescr'])),
|
|
cacti_csv_cell(export_data($host['os'])),
|
|
cacti_csv_cell(export_data($uptime)),
|
|
cacti_csv_cell($host['snmp'] == 1 ? __('Up') : __('Down')),
|
|
cacti_csv_cell($host['up'] == 1 ? __('Up') : __('Down'))
|
|
]) . "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
function purge_discovery_results() : void {
|
|
gfrv('network');
|
|
|
|
if (grv('network') > 0) {
|
|
db_execute_prepared('DELETE FROM automation_devices WHERE network_id = ?', [grv('network')]);
|
|
} else {
|
|
db_execute('TRUNCATE TABLE automation_devices');
|
|
}
|
|
|
|
header('Location: automation_devices.php');
|
|
|
|
exit;
|
|
}
|
|
|
|
function snmp_data(string $item) : string {
|
|
if ($item == '') {
|
|
return __('N/A');
|
|
} else {
|
|
return htmle(str_replace(':',' ', $item));
|
|
}
|
|
}
|
|
|
|
function export_data(string $item) : string {
|
|
if ($item == '') {
|
|
return 'N/A';
|
|
} else {
|
|
return $item;
|
|
}
|
|
}
|