mirror of
https://github.com/Cacti/cacti.git
synced 2026-10-23 19:47:06 +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>
503 lines
17 KiB
PHP
503 lines
17 KiB
PHP
<?php
|
|
function get_hosts(array $params = []) : mixed {
|
|
$sql = 'SELECT id as host_id, description as host_description, hostname, host_template_id,
|
|
poller_id, site_id, disabled, status, status_fail_date AS last_fail_date,
|
|
status_rec_date AS last_recovery_date, status_last_error AS last_error,
|
|
availability, polling_time, total_polls, failed_polls, snmp_sysDescr AS snmp_description,
|
|
snmp_sysUpTimeInstance AS snmp_uptime, snmp_sysLocation AS snmp_location, last_updated
|
|
FROM host';
|
|
|
|
$conditions = [];
|
|
$values = [];
|
|
|
|
if (isset($params['host_id']) && $params['host_id'] !== '') {
|
|
if (!is_array($params['host_id'])) {
|
|
$params['host_id'] = explode(',', $params['host_id']);
|
|
}
|
|
|
|
$params['host_id'] = array_map('trim', $params['host_id']);
|
|
$params['host_id'] = array_filter($params['host_id'], fn ($v) => $v !== '');
|
|
|
|
if (!empty($params['host_id'])) {
|
|
$placeholders = implode(',', array_fill(0, count($params['host_id']), '?'));
|
|
$conditions[] = "id IN ($placeholders)";
|
|
$values = array_merge($values, $params['host_id']);
|
|
}
|
|
}
|
|
|
|
if (isset($params['poller_id']) && $params['poller_id'] !== '') {
|
|
if (!is_array($params['poller_id'])) {
|
|
$params['poller_id'] = explode(',', $params['poller_id']);
|
|
}
|
|
|
|
$params['poller_id'] = array_map('trim', $params['poller_id']);
|
|
$params['poller_id'] = array_filter($params['poller_id'], fn ($v) => $v !== '');
|
|
|
|
if (!empty($params['poller_id'])) {
|
|
$placeholders = implode(',', array_fill(0, count($params['poller_id']), '?'));
|
|
$conditions[] = "poller_id IN ($placeholders)";
|
|
$values = array_merge($values, $params['poller_id']);
|
|
}
|
|
}
|
|
|
|
if (isset($params['site_id']) && $params['site_id'] !== '') {
|
|
if (!is_array($params['site_id'])) {
|
|
$params['site_id'] = explode(',', $params['site_id']);
|
|
}
|
|
$params['site_id'] = array_map('trim', $params['site_id']);
|
|
$params['site_id'] = array_filter($params['site_id'], fn ($v) => $v !== '');
|
|
|
|
if (!empty($params['site_id'])) {
|
|
$placeholders = implode(',', array_fill(0, count($params['site_id']), '?'));
|
|
$conditions[] = "site_id IN ($placeholders)";
|
|
$values = array_merge($values, $params['site_id']);
|
|
}
|
|
}
|
|
|
|
if (isset($params['template_id']) && $params['template_id'] !== '') {
|
|
if (!is_array($params['template_id'])) {
|
|
$params['template_id'] = explode(',', $params['template_id']);
|
|
}
|
|
|
|
$params['template_id'] = array_map('trim', $params['template_id']);
|
|
$params['template_id'] = array_filter($params['template_id'], fn ($v) => $v !== '');
|
|
|
|
if (!empty($params['template_id'])) {
|
|
$placeholders = implode(',', array_fill(0, count($params['template_id']), '?'));
|
|
$conditions[] = "host_template_id IN ($placeholders)";
|
|
$values = array_merge($values, $params['template_id']);
|
|
}
|
|
}
|
|
|
|
if (isset($params['status'])) {
|
|
$conditions[] = 'status = ?';
|
|
$values[] = $params['status'];
|
|
}
|
|
|
|
if (isset($params['snmp_location'])) {
|
|
$conditions[] = 'snmp_sysLocation LIKE ?';
|
|
$values[] = '%' . $params['snmp_location'] . '%';
|
|
}
|
|
|
|
if (isset($params['hostname']) && $params['hostname'] !== '') {
|
|
$conditions[] = 'hostname LIKE ?';
|
|
$values[] = '%' . $params['hostname'] . '%';
|
|
}
|
|
|
|
if (isset($params['description']) && $params['description'] !== '') {
|
|
$conditions[] = 'description LIKE ?';
|
|
$values[] = '%' . $params['description'] . '%';
|
|
}
|
|
|
|
// Apply WHERE clause if needed
|
|
if (!empty($conditions)) {
|
|
$sql .= ' WHERE ' . implode(' AND ', $conditions);
|
|
}
|
|
|
|
return $values ? db_fetch_assoc_prepared($sql, $values) : db_fetch_assoc($sql);
|
|
}
|
|
|
|
/**
|
|
* Retrieves a list of graphs associated with a specific host.
|
|
*
|
|
* This function queries the database to fetch graph details for a given host ID.
|
|
* It returns an array of graphs, each containing the host ID, graph ID, and RRD name.
|
|
*
|
|
* @param int $host_id The ID of the host for which to retrieve the graph list. Defaults to 0.
|
|
*
|
|
* @return array An associative array with the key "graphs" containing a list of graphs.
|
|
* Each graph is represented as an associative array with the following keys:
|
|
* - "host_id" (int): The ID of the host.
|
|
* - "graph_id" (int): The ID of the graph.
|
|
* - "rrd_name" (string): The name of the RRD file.
|
|
*/
|
|
function get_graph_list(int $host_id = 0) : array {
|
|
if (filter_var($host_id, FILTER_VALIDATE_INT) === false || $host_id < 0) {
|
|
return ['graphs' => ['Host must be a valid INT']];
|
|
}
|
|
|
|
$sql = "SELECT DISTINCT h.id as host_id, dl.id as graph_id, dtd.name_cache as rrd_name, pi.rrd_name as rrd_path
|
|
FROM poller_item AS pi
|
|
INNER JOIN data_local AS dl
|
|
ON dl.id = pi.local_data_id
|
|
INNER JOIN data_template_data AS dtd
|
|
ON dtd.local_data_id = pi.local_data_id
|
|
INNER JOIN host AS h
|
|
ON pi.host_id = h.id
|
|
WHERE rrd_name != ''
|
|
AND h.id = ?";
|
|
|
|
$rows = db_fetch_assoc_prepared($sql, [$host_id]);
|
|
$graphs = [];
|
|
|
|
if (is_array($rows)) {
|
|
foreach ($rows as $row) {
|
|
$graphs[] = [
|
|
'host_id' => $row['host_id'],
|
|
'graph_id' => $row['graph_id'],
|
|
'rrd_name' => $row['rrd_name']
|
|
];
|
|
}
|
|
}
|
|
|
|
return ['graphs' => $graphs];
|
|
}
|
|
|
|
function get_poller_status(int $poller_id = 0) : mixed {
|
|
if (filter_var($poller_id, FILTER_VALIDATE_INT) === false || $poller_id < 0) {
|
|
return ['error' => 'Poller ID must be a valid INT'];
|
|
}
|
|
|
|
$sql = 'SELECT id, name, disabled, status, hostname, total_time, max_time,
|
|
min_time, avg_time, total_polls, processes, threads, last_update, last_status
|
|
FROM poller';
|
|
|
|
$values = [];
|
|
|
|
if ($poller_id > 0) {
|
|
$sql .= ' WHERE id = ?';
|
|
$values[] = $poller_id;
|
|
}
|
|
|
|
return $values ? db_fetch_assoc_prepared($sql, $values) : db_fetch_assoc($sql);
|
|
}
|
|
|
|
function get_host_templates(int $template_id = 0) : mixed {
|
|
if (filter_var($template_id, FILTER_VALIDATE_INT) === false || $template_id < 0) {
|
|
return ['templates' => ['Template ID must be a valid INT']];
|
|
}
|
|
|
|
$sql = 'SELECT id,name,class FROM host_template';
|
|
$values = [];
|
|
|
|
if ($template_id > 0) {
|
|
$sql .= ' WHERE id = ?';
|
|
$values[] = $template_id;
|
|
}
|
|
|
|
return $values ? db_fetch_assoc_prepared($sql, $values) : db_fetch_assoc($sql);
|
|
}
|
|
|
|
function get_cacti_status() : array {
|
|
// Get Cacti version
|
|
$cacti_version = db_fetch_cell('SELECT cacti AS version FROM version LIMIT 1');
|
|
$poller_type = read_config_option('poller_type');
|
|
$poller_enabled = read_config_option('poller_enabled');
|
|
$total_hosts = db_fetch_cell('SELECT COUNT(*) as count FROM host');
|
|
|
|
$total_data_sources = db_fetch_cell('SELECT COUNT(*) as count FROM data_local');
|
|
$poller_output_size = db_fetch_cell('SELECT COUNT(*) as count FROM poller_output');
|
|
$boost_table_size = db_fetch_cell('SELECT COUNT(*) as count FROM poller_output_boost');
|
|
|
|
if ($poller_enabled === 'on') {
|
|
$poller_enabled = 'Global Polling is enabled';
|
|
} else {
|
|
$poller_enabled = 'Global polling is disabled';
|
|
}
|
|
|
|
$poller_type = ($poller_type === '2') ? 'Spine' : (($poller_type === '1') ? 'cmd.php' : $poller_type);
|
|
|
|
// Get installed plugins
|
|
$plugins = db_fetch_assoc('SELECT name, status, version FROM plugin_config');
|
|
|
|
$installed_plugins = [];
|
|
|
|
if (is_array($plugins)) {
|
|
foreach ($plugins as $plugin) {
|
|
$status = ($plugin['status'] == 1) ? 'enabled' : 'disabled';
|
|
|
|
$installed_plugins[] = [
|
|
'name' => $plugin['name'],
|
|
'status' => $status,
|
|
'version' => $plugin['version']
|
|
];
|
|
}
|
|
}
|
|
|
|
$cacti_status = [
|
|
[
|
|
'cacti_version' => $cacti_version,
|
|
'poller_type' => $poller_type,
|
|
'poller_enabled' => $poller_enabled,
|
|
'total_hosts' => $total_hosts,
|
|
'poller_output_size' => $poller_output_size,
|
|
'boost_table_size' => $boost_table_size,
|
|
'total_data_sources' => $total_data_sources,
|
|
'installed_plugins' => $installed_plugins
|
|
]
|
|
];
|
|
|
|
return ['cacti_status' => $cacti_status];
|
|
}
|
|
|
|
function get_boost_status() : array {
|
|
$boost_rrd_update_enable = read_config_option('boost_rrd_update_enable');
|
|
|
|
if ($boost_rrd_update_enable !== 'on') {
|
|
return ['boost_rrd_update_enable' => 'Boost is disabled'];
|
|
}
|
|
|
|
$boost_last_end_time = read_config_option('boost_last_end_time');
|
|
$boost_last_start_time = read_config_option('boost_last_start_time');
|
|
$boost_next_run_time = read_config_option('boost_next_run_time');
|
|
$stats_detail_boost = read_config_option('stats_detail_boost');
|
|
$total_boost_records = db_fetch_cell('SELECT COUNT(*) as count FROM poller_output_boost');
|
|
|
|
$boost_status = [
|
|
'boost_rrd_update_enable' => $boost_rrd_update_enable,
|
|
'boost_last_end_time' => $boost_last_end_time,
|
|
'boost_last_start_time' => $boost_last_start_time,
|
|
'boost_next_run_time' => $boost_next_run_time,
|
|
'stats_detail_boost' => $stats_detail_boost,
|
|
'total_boost_records' => $total_boost_records
|
|
];
|
|
|
|
return ['boost_status' => $boost_status];
|
|
}
|
|
|
|
function get_dsstats_status() : array {
|
|
$check_dsstats_enabled = read_config_option('dsstats_enable');
|
|
|
|
if ($check_dsstats_enabled !== 'on') {
|
|
return ['dsstats_status' => 'Data Source Statistics is disabled'];
|
|
}
|
|
|
|
$dsstats_status = [
|
|
'dsstats_poller_memory_limit' => read_config_option('dsstats_poller_mem_limit'),
|
|
'dsstats_timeout' => read_config_option('dsstats_timeout'),
|
|
'dsstats_parallel_processes' => read_config_option('dsstats_parallel'),
|
|
'dsstats_mode' => (read_config_option('dsstats_mode') == 0 ? 'Peak/Average Only' : 'All Metrics'),
|
|
'dsstats_hourly_duration' => read_config_option('dsstats_hourly_duration'),
|
|
'dsstats_daily_interval' => read_config_option('dsstats_daily_interval'),
|
|
'dsstats_weekly_retention' => read_config_option('dsstats_weekly_retention'),
|
|
'dsstats_monthly_retention' => read_config_option('dsstats_monthly_retention'),
|
|
'dsstats_yearly_retention' => read_config_option('dsstats_yearly_retention'),
|
|
'dsstats_last_run_time' => read_config_option('dsstats_last_major_run_time'),
|
|
'dsstats_peak' => read_config_option('dsstats_peak'),
|
|
];
|
|
|
|
return ['dsstats_status' => $dsstats_status];
|
|
}
|
|
|
|
function get_cacti_db_status() : array {
|
|
$status_rows = db_fetch_assoc('SHOW STATUS');
|
|
$status_assoc = [];
|
|
|
|
foreach ($status_rows as $row) {
|
|
if (isset($row['Variable_name']) && isset($row['Value'])) {
|
|
$status_assoc[$row['Variable_name']] = $row['Value'];
|
|
}
|
|
}
|
|
|
|
$db_status = [
|
|
'max_used_connections' => $status_assoc['Max_used_connections'] ?? 0,
|
|
'threads_connected' => $status_assoc['Threads_connected'] ?? 0,
|
|
'threads_running' => $status_assoc['Threads_running'] ?? 0,
|
|
'Aborted_clients' => $status_assoc['Aborted_clients'] ?? 0,
|
|
'Aborted_connects' => $status_assoc['Aborted_connects'] ?? 0,
|
|
'Uptime' => $status_assoc['Uptime'] ?? 0,
|
|
'innodb_buffer_pool_size' => $status_assoc['Innodb_buffer_pool_size'] ?? 0,
|
|
'innodb_buffer_pool_pages_total' => $status_assoc['Innodb_buffer_pool_pages_total'] ?? 0,
|
|
'innodb_buffer_pool_pages_free' => $status_assoc['Innodb_buffer_pool_pages_free'] ?? 0,
|
|
'innodb_buffer_pool_pages_data' => $status_assoc['Innodb_buffer_pool_pages_data'] ?? 0,
|
|
'innodb_buffer_pool_pages_dirty' => $status_assoc['Innodb_buffer_pool_pages_dirty'] ?? 0
|
|
];
|
|
|
|
return ['db_status' => $db_status];
|
|
}
|
|
|
|
function get_thresholds(array $params = []) : array {
|
|
$check_thold_installed = db_fetch_assoc("SHOW TABLES LIKE 'thold_data'");
|
|
|
|
if (empty($check_thold_installed)) {
|
|
return ['thold_status' => 'Thresholds plugin is not installed'];
|
|
}
|
|
|
|
$sql = 'SELECT h.id as HOST_ID, description AS HOST_DESCRIPTION, h.hostname, data_source_name, thold_hi, thold_low, lastread, lastchanged, thold_fail_count, thold_enabled
|
|
FROM thold_data td
|
|
INNER JOIN host h
|
|
ON td.host_id = h.id';
|
|
|
|
$conditions = [];
|
|
$values = [];
|
|
|
|
if (isset($params['host_id']) && $params['host_id'] !== '') {
|
|
if (!is_array($params['host_id'])) {
|
|
$params['host_id'] = explode(',', $params['host_id']);
|
|
}
|
|
|
|
$params['host_id'] = array_map('trim', $params['host_id']);
|
|
$params['host_id'] = array_filter($params['host_id'], fn ($v) => $v !== '');
|
|
|
|
if (!empty($params['host_id'])) {
|
|
$placeholders = implode(',', array_fill(0, count($params['host_id']), '?'));
|
|
$conditions[] = "h.id IN ($placeholders)";
|
|
$values = array_merge($values, $params['host_id']);
|
|
}
|
|
}
|
|
|
|
if (isset($params['host_description'])) {
|
|
$conditions[] = 'h.description LIKE ?';
|
|
$values[] = '%' . $params['host_description'] . '%';
|
|
}
|
|
|
|
if (isset($params['hostname'])) {
|
|
$conditions[] = 'h.hostname LIKE ?';
|
|
$values[] = '%' . $params['hostname'] . '%';
|
|
}
|
|
|
|
if (isset($params['data_source_name'])) {
|
|
$conditions[] = 'td.data_source_name LIKE ?';
|
|
$values[] = '%' . $params['data_source_name'] . '%';
|
|
}
|
|
|
|
if (isset($params['template_id']) && $params['template_id'] !== '') {
|
|
if (!is_array($params['template_id'])) {
|
|
$params['template_id'] = explode(',', $params['template_id']);
|
|
}
|
|
|
|
$params['template_id'] = array_map('trim', $params['template_id']);
|
|
$params['template_id'] = array_filter($params['template_id'], fn ($v) => $v !== '');
|
|
|
|
if (!empty($params['template_id'])) {
|
|
$placeholders = implode(',', array_fill(0, count($params['template_id']), '?'));
|
|
$conditions[] = "host_template_id IN ($placeholders)";
|
|
$values = array_merge($values, $params['template_id']);
|
|
}
|
|
}
|
|
|
|
if (!empty($conditions)) {
|
|
$sql .= ' WHERE ' . implode(' AND ', $conditions);
|
|
}
|
|
|
|
$rows = $values ? db_fetch_assoc_prepared($sql, $values) : db_fetch_assoc($sql);
|
|
$thresholds = [];
|
|
|
|
if (is_array($rows)) {
|
|
foreach ($rows as $row) {
|
|
$thresholds[] = [
|
|
'host_id' => $row['HOST_ID'],
|
|
'host_description' => $row['HOST_DESCRIPTION'],
|
|
'hostname' => $row['hostname'],
|
|
'data_source_name' => $row['data_source_name'],
|
|
'thold_hi' => $row['thold_hi'],
|
|
'thold_low' => $row['thold_low'],
|
|
'lastread' => $row['lastread'],
|
|
'lastchanged' => $row['lastchanged'],
|
|
'thold_fail_count' => $row['thold_fail_count'],
|
|
'thold_enabled' => $row['thold_enabled']
|
|
];
|
|
}
|
|
}
|
|
|
|
return ['thresholds' => $thresholds];
|
|
}
|
|
|
|
function get_threshold_status() : array {
|
|
$check_thold_installed = db_fetch_assoc("SHOW TABLES LIKE 'thold_data'");
|
|
|
|
if (empty($check_thold_installed)) {
|
|
return ['thold_status' => 'Thresholds plugin is not installed'];
|
|
}
|
|
|
|
$check_daemon_enabled = read_config_option('thold_daemon_enable');
|
|
|
|
$daemon_status = [];
|
|
|
|
if (empty($check_daemon_enabled)) {
|
|
$daemon_status = ['thold_status' => 'Thold daemon is not enabled'];
|
|
} else {
|
|
$daemon_status = [
|
|
'thold_daemon_dead_notification' => read_config_option('thold_daemon_dead_notification'),
|
|
'thold_daemon_debug' => (read_config_option('thold_daemon_debug') === 'on') ? 'enabled' : 'disabled',
|
|
'thold_daemon_down_notify_time' => read_config_option('thold_daemon_down_notify_time'),
|
|
'thold_daemon_enable' => ($check_daemon_enabled === 'on') ? 'enabled' : 'disabled'
|
|
];
|
|
}
|
|
|
|
$poller_stats = read_config_option('stats_thold');
|
|
$total_thresholds = db_fetch_cell('SELECT COUNT(*) as cnt FROM thold_data') ?? 0;
|
|
$enabled_thresholds = db_fetch_cell('SELECT COUNT(*) as cnt FROM thold_data WHERE thold_enabled = 1') ?? 0;
|
|
$disabled_thresholds = db_fetch_cell('SELECT COUNT(*) as cnt FROM thold_data WHERE thold_enabled = 0') ?? 0;
|
|
|
|
return [
|
|
'thold_status' => [
|
|
'daemon' => $daemon_status,
|
|
'poller_stats' => $poller_stats,
|
|
'total_thresholds' => $total_thresholds,
|
|
'enabled_thresholds' => $enabled_thresholds,
|
|
'disabled_thresholds' => $disabled_thresholds
|
|
]
|
|
];
|
|
}
|
|
|
|
// automation functions
|
|
function get_automation_networks(array $params = []) : mixed {
|
|
$sql = 'SELECT id, poller_id, name, subnet_range, ignore_ips, dns_servers, enabled,
|
|
notification_email, up_hosts, snmp_hosts, ping_method, ping_timeout, ping_retries,
|
|
start_at, next_start, last_runtime, last_started, last_status
|
|
FROM automation_networks';
|
|
|
|
$conditions = [];
|
|
$values = [];
|
|
|
|
if (isset($params['network_id']) && $params['network_id'] !== '') {
|
|
if (!is_array($params['network_id'])) {
|
|
$params['network_id'] = explode(',', $params['network_id']);
|
|
}
|
|
|
|
$params['network_id'] = array_map('trim', $params['network_id']);
|
|
$params['network_id'] = array_filter($params['network_id'], fn ($v) => $v !== '');
|
|
|
|
if (!empty($params['network_id'])) {
|
|
$placeholders = implode(',', array_fill(0, count($params['network_id']), '?'));
|
|
$conditions[] = "id IN ($placeholders)";
|
|
$values = array_merge($values, $params['network_id']);
|
|
}
|
|
}
|
|
|
|
if (isset($params['network_name']) && $params['network_name'] !== '') {
|
|
$conditions[] = 'name LIKE ?';
|
|
$values[] = '%' . $params['network_name'] . '%';
|
|
}
|
|
|
|
if (isset($params['subnet_range']) && $params['subnet_range'] !== '') {
|
|
$conditions[] = 'subnet_range LIKE ?';
|
|
$values[] = '%' . $params['subnet_range'] . '%';
|
|
}
|
|
|
|
if (!empty($conditions)) {
|
|
$sql .= ' WHERE ' . implode(' AND ', $conditions);
|
|
}
|
|
|
|
// Use prepared variant when values exist (placeholders present)
|
|
if (!empty($values)) {
|
|
return db_fetch_assoc_prepared($sql, $values);
|
|
}
|
|
|
|
return db_fetch_assoc($sql);
|
|
}
|
|
|
|
function get_automation_status() : array {
|
|
$sql = 'SELECT DISTINCT ap.network_id, an.name, an.subnet_range, an.last_started
|
|
FROM automation_processes ap
|
|
INNER JOIN automation_networks an ON ap.network_id = an.id';
|
|
|
|
$rows = db_fetch_assoc($sql);
|
|
|
|
$automation_status = [];
|
|
|
|
if (is_array($rows)) {
|
|
foreach ($rows as $row) {
|
|
$automation_status[] = [
|
|
'network_id' => $row['network_id'],
|
|
'network_name' => $row['name'],
|
|
'subnet_range' => $row['subnet_range'],
|
|
'last_started' => $row['last_started']
|
|
];
|
|
}
|
|
}
|
|
|
|
return ['running_automations' => $automation_status];
|
|
}
|