mirror of
https://github.com/pandorafms/pandorafms.git
synced 2025-07-30 09:15:15 +02:00
Merge remote-tracking branch 'origin/develop' into ent-8130-ncm-fase-2
Conflicts: pandora_console/extras/mr/51.sql
This commit is contained in:
commit
f852df2f1c
@ -1,5 +1,5 @@
|
||||
package: pandorafms-agent-unix
|
||||
Version: 7.0NG.758.1-211207
|
||||
Version: 7.0NG.758.1-211214
|
||||
Architecture: all
|
||||
Priority: optional
|
||||
Section: admin
|
||||
|
@ -14,7 +14,7 @@
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
pandora_version="7.0NG.758.1-211207"
|
||||
pandora_version="7.0NG.758.1-211214"
|
||||
|
||||
echo "Test if you has the tools for to make the packages."
|
||||
whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null
|
||||
|
@ -1015,7 +1015,7 @@ my $Sem = undef;
|
||||
my $ThreadSem = undef;
|
||||
|
||||
use constant AGENT_VERSION => '7.0NG.758.1';
|
||||
use constant AGENT_BUILD => '211207';
|
||||
use constant AGENT_BUILD => '211214';
|
||||
|
||||
# Agent log default file size maximum and instances
|
||||
use constant DEFAULT_MAX_LOG_SIZE => 600000;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
%define name pandorafms_agent_unix
|
||||
%define version 7.0NG.758.1
|
||||
%define release 211207
|
||||
%define release 211214
|
||||
|
||||
Summary: Pandora FMS Linux agent, PERL version
|
||||
Name: %{name}
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
%define name pandorafms_agent_unix
|
||||
%define version 7.0NG.758.1
|
||||
%define release 211207
|
||||
%define release 211214
|
||||
|
||||
Summary: Pandora FMS Linux agent, PERL version
|
||||
Name: %{name}
|
||||
|
@ -10,7 +10,7 @@
|
||||
# **********************************************************************
|
||||
|
||||
PI_VERSION="7.0NG.758.1"
|
||||
PI_BUILD="211207"
|
||||
PI_BUILD="211214"
|
||||
OS_NAME=`uname -s`
|
||||
|
||||
FORCE=0
|
||||
|
@ -186,7 +186,7 @@ UpgradeApplicationID
|
||||
{}
|
||||
|
||||
Version
|
||||
{211207}
|
||||
{211214}
|
||||
|
||||
ViewReadme
|
||||
{Yes}
|
||||
|
@ -30,7 +30,7 @@ using namespace Pandora;
|
||||
using namespace Pandora_Strutils;
|
||||
|
||||
#define PATH_SIZE _MAX_PATH+1
|
||||
#define PANDORA_VERSION ("7.0NG.758.1 Build 211207")
|
||||
#define PANDORA_VERSION ("7.0NG.758.1 Build 211214")
|
||||
|
||||
string pandora_path;
|
||||
string pandora_dir;
|
||||
|
@ -11,7 +11,7 @@ BEGIN
|
||||
VALUE "LegalCopyright", "Artica ST"
|
||||
VALUE "OriginalFilename", "PandoraAgent.exe"
|
||||
VALUE "ProductName", "Pandora FMS Windows Agent"
|
||||
VALUE "ProductVersion", "(7.0NG.758.1(Build 211207))"
|
||||
VALUE "ProductVersion", "(7.0NG.758.1(Build 211214))"
|
||||
VALUE "FileVersion", "1.0.0.0"
|
||||
END
|
||||
END
|
||||
|
@ -1,5 +1,5 @@
|
||||
package: pandorafms-console
|
||||
Version: 7.0NG.758.1-211207
|
||||
Version: 7.0NG.758.1-211214
|
||||
Architecture: all
|
||||
Priority: optional
|
||||
Section: admin
|
||||
|
@ -14,7 +14,7 @@
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
pandora_version="7.0NG.758.1-211207"
|
||||
pandora_version="7.0NG.758.1-211214"
|
||||
|
||||
package_pear=0
|
||||
package_pandora=1
|
||||
|
@ -89,14 +89,13 @@ function agents_modules_load_js()
|
||||
|
||||
var controls = document.getElementById('vc-controls');
|
||||
autoHideElement(controls, 1000);
|
||||
|
||||
|
||||
$('select#refresh').change(function (event) {
|
||||
refr = Number.parseInt(event.target.value, 10);
|
||||
startCountDown(refr, false);
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
||||
var agentes_id = $("#id_agents2").val();
|
||||
var id_agentes = getQueryParam("full_agents_id");
|
||||
if (agentes_id === null && id_agentes !== null) {
|
||||
@ -104,15 +103,15 @@ function agents_modules_load_js()
|
||||
id_agentes.forEach(function(element) {
|
||||
$("#id_agents2 option[value="+ element +"]").attr("selected",true);
|
||||
});
|
||||
|
||||
|
||||
selection_agent_module();
|
||||
}
|
||||
|
||||
|
||||
$('#refresh').change(function () {
|
||||
$('#hidden-vc_refr').val($('#refresh option:selected').val());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$("#group_id").change (function () {
|
||||
jQuery.post ("ajax.php",
|
||||
{"page" : "operation/agentes/ver_agente",
|
||||
@ -128,7 +127,6 @@ function agents_modules_load_js()
|
||||
jQuery.each (data, function (id, value) {
|
||||
// Remove keys_prefix from the index
|
||||
id = id.substring(1);
|
||||
|
||||
option = $("<option></option>")
|
||||
.attr ("value", value["id_agente"])
|
||||
.html (value["alias"]);
|
||||
@ -139,7 +137,7 @@ function agents_modules_load_js()
|
||||
"json"
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
$("#checkbox-recursion").change (function () {
|
||||
jQuery.post ("ajax.php",
|
||||
{"page" : "operation/agentes/ver_agente",
|
||||
@ -155,7 +153,6 @@ function agents_modules_load_js()
|
||||
jQuery.each (data, function (id, value) {
|
||||
// Remove keys_prefix from the index
|
||||
id = id.substring(1);
|
||||
|
||||
option = $("<option></option>")
|
||||
.attr ("value", value["id_agente"])
|
||||
.html (value["alias"]);
|
||||
@ -166,7 +163,7 @@ function agents_modules_load_js()
|
||||
"json"
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
$("#modulegroup").change (function () {
|
||||
jQuery.post ("ajax.php",
|
||||
{"page" : "operation/agentes/ver_agente",
|
||||
@ -180,8 +177,8 @@ function agents_modules_load_js()
|
||||
if(data){
|
||||
jQuery.each (data, function (id, value) {
|
||||
option = $("<option></option>")
|
||||
.attr ("value", value["id_agente_modulo"])
|
||||
.html (value["nombre"]);
|
||||
.attr ("value", id)
|
||||
.html (value);
|
||||
$("#module").append (option);
|
||||
});
|
||||
}
|
||||
@ -207,8 +204,8 @@ function agents_modules_load_js()
|
||||
if(data){
|
||||
jQuery.each (data, function (id, value) {
|
||||
option = $("<option></option>")
|
||||
.attr ("value", value["id_agente_modulo"])
|
||||
.html (value["nombre"]);
|
||||
.attr ("value", id)
|
||||
.html (value);
|
||||
$("#module").append (option);
|
||||
});
|
||||
}
|
||||
@ -231,11 +228,11 @@ function agents_modules_load_js()
|
||||
if(data){
|
||||
jQuery.each (data, function (id, value) {
|
||||
option = $("<option></option>")
|
||||
.attr ("value", value["id_agente_modulo"])
|
||||
.html (value["nombre"]);
|
||||
.attr ("value", id)
|
||||
.html (value);
|
||||
$("#module").append (option);
|
||||
});
|
||||
|
||||
|
||||
var id_modules = getQueryParam("full_modules_selected");
|
||||
if(id_modules !== null) {
|
||||
id_modules = id_modules.split(";");
|
||||
@ -249,20 +246,19 @@ function agents_modules_load_js()
|
||||
);
|
||||
}
|
||||
|
||||
function getQueryParam (key) {
|
||||
key = key.replace(/[[]/, '[');
|
||||
key = key.replace(/[]]/, ']');
|
||||
var pattern = "[?&]" + key + "=([^&#]*)";
|
||||
function getQueryParam (key) {
|
||||
key = key.replace(/[[]/, '[');
|
||||
key = key.replace(/[]]/, ']');
|
||||
var pattern = "[?&]" + key + "=([^&#]*)";
|
||||
var regex = new RegExp(pattern);
|
||||
var url = unescape(window.location.href);
|
||||
var results = regex.exec(url);
|
||||
if (results === null) {
|
||||
return null;
|
||||
} else {
|
||||
return results[1];
|
||||
}
|
||||
if (results === null) {
|
||||
return null;
|
||||
} else {
|
||||
return results[1];
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ ALTER TABLE `tlocal_component` ADD COLUMN `percentage_critical` tinyint(1) UNSIG
|
||||
ALTER TABLE `tlocal_component` ADD COLUMN `percentage_warning` tinyint(1) UNSIGNED DEFAULT 0;
|
||||
ALTER TABLE `tpolicy_modules` ADD COLUMN `percentage_warning` tinyint(1) UNSIGNED DEFAULT 0;
|
||||
ALTER TABLE `tpolicy_modules` ADD COLUMN `percentage_critical` tinyint(1) UNSIGNED DEFAULT 0;
|
||||
|
||||
ALTER TABLE `tsync_queue` ADD COLUMN `result` TEXT;
|
||||
ALTER TABLE tagente_modulo MODIFY debug_content TEXT;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tncm_queue` (
|
||||
@ -39,23 +39,30 @@ CREATE TABLE IF NOT EXISTS `tncm_firmware` (
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `talert_calendar` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL default '',
|
||||
`id_group` INT(10) NOT NULL DEFAULT 0,
|
||||
`description` text,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (`name`)
|
||||
`id_group` INT(10) NOT NULL DEFAULT 0,
|
||||
`description` text,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tipam_network_location` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL default '',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (`name`)
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL default '',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tipam_sites` (
|
||||
`id` serial,
|
||||
`name` varchar(100) UNIQUE NOT NULL default '',
|
||||
`description` text,
|
||||
`parent` bigint unsigned null,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`parent`) REFERENCES `tipam_sites`(`id`) ON UPDATE CASCADE ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `tncm_agent` ADD COLUMN `cron_interval` varchar(100) default '' AFTER `execute`;
|
||||
ALTER TABLE `tncm_agent` ADD COLUMN `event_on_change` int unsigned default null AFTER `cron_interval`;
|
||||
ALTER TABLE `tipam_network` MODIFY `location` int(10) unsigned NULL;
|
||||
ALTER TABLE `tipam_network` ADD FOREIGN KEY (`location`) REFERENCES `tipam_network_location`(`id`) ON DELETE CASCADE;
|
||||
ALTER TABLE `tagent_repository` ADD COLUMN `deployment_timeout` INT UNSIGNED DEFAULT 600 AFTER `path`;
|
||||
@ -63,6 +70,15 @@ ALTER TABLE `talert_special_days` ADD COLUMN `id_calendar` int(10) unsigned NOT
|
||||
ALTER TABLE `talert_special_days` ADD COLUMN `day_code` tinyint(2) unsigned NOT NULL DEFAULT 0;
|
||||
ALTER TABLE `talert_special_days` DROP COLUMN `same_day`;
|
||||
ALTER TABLE `talert_special_days` ADD FOREIGN KEY (`id_calendar`) REFERENCES `talert_calendar`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE `tipam_network` ADD COLUMN `id_site` bigint unsigned;
|
||||
ALTER TABLE `tipam_network` ADD CONSTRAINT FOREIGN KEY (`id_site`) REFERENCES `tipam_sites`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE `tipam_supernet` ADD COLUMN `id_site` bigint unsigned;
|
||||
ALTER TABLE `tipam_supernet` ADD CONSTRAINT FOREIGN KEY (`id_site`) REFERENCES `tipam_sites`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE `tipam_network` ADD COLUMN `vrf` int(10) unsigned;
|
||||
ALTER TABLE `tipam_network` ADD CONSTRAINT FOREIGN KEY (`vrf`) REFERENCES `tagente`(`id_agente`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE `tncm_agent` ADD COLUMN `cron_interval` varchar(100) default '' AFTER `execute`;
|
||||
ALTER TABLE `tncm_agent` ADD COLUMN `event_on_change` int unsigned default null AFTER `cron_interval`;
|
||||
ALTER TABLE `tncm_vendor` ADD COLUMN `icon` VARCHAR(255) DEFAULT '';
|
||||
ALTER TABLE `tevento` MODIFY COLUMN `event_type` ENUM('going_unknown','unknown','alert_fired','alert_recovered','alert_ceased','alert_manual_validation','recon_host_detected','system','error','new_agent','going_up_warning','going_up_critical','going_down_warning','going_down_normal','going_down_critical','going_up_normal', 'configuration_change', 'ncm') DEFAULT 'unknown';
|
||||
|
||||
|
@ -3970,15 +3970,20 @@ CREATE TABLE IF NOT EXISTS `tipam_network` (
|
||||
`network` varchar(100) NOT NULL default '',
|
||||
`name_network` varchar(255) default '',
|
||||
`description` text NOT NULL,
|
||||
`location` tinytext NOT NULL,
|
||||
`location` int(10) unsigned NULL,
|
||||
`id_recon_task` int(10) unsigned NOT NULL,
|
||||
`scan_interval` tinyint(2) default 1,
|
||||
`monitoring` tinyint(2) default 0,
|
||||
`id_group` mediumint(8) unsigned NULL default 0,
|
||||
`lightweight_mode` tinyint(2) default 0,
|
||||
`users_operator` text,
|
||||
`id_site` bigint unsigned,
|
||||
`vrf` int(10) unsigned,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`id_recon_task`) REFERENCES trecon_task(`id_rt`) ON DELETE CASCADE
|
||||
FOREIGN KEY (`id_recon_task`) REFERENCES trecon_task(`id_rt`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`location`) REFERENCES `tipam_network_location`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`id_site`) REFERENCES `tipam_sites`(`id`) ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
FOREIGN KEY (`vrf`) REFERENCES `tagente`(`id_agente`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tipam_ip` (
|
||||
@ -4033,7 +4038,9 @@ CREATE TABLE IF NOT EXISTS `tipam_supernet` (
|
||||
`address` varchar(250) NOT NULL,
|
||||
`mask` varchar(250) NOT NULL,
|
||||
`subneting_mask` varchar(250) default '',
|
||||
PRIMARY KEY (`id`)
|
||||
`id_site` bigint unsigned,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`id_site`) REFERENCES `tipam_sites`(`id`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tipam_supernet_network` (
|
||||
@ -4052,10 +4059,16 @@ CREATE TABLE IF NOT EXISTS `tipam_network_location` (
|
||||
UNIQUE (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tipam_sites` (
|
||||
`id` serial,
|
||||
`name` varchar(100) UNIQUE NOT NULL default '',
|
||||
`description` text,
|
||||
`parent` bigint unsigned null,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`parent`) REFERENCES `tipam_sites`(`id`) ON UPDATE CASCADE ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT IGNORE INTO `tipam_network_location` (`name`) SELECT `location` FROM `tipam_network` WHERE `location` <> '';
|
||||
UPDATE `tipam_network` INNER JOIN `tipam_network_location` ON tipam_network_location.name=tipam_network.location SET tipam_network.location=tipam_network_location.id;
|
||||
ALTER TABLE `tipam_network` MODIFY `location` int(10) unsigned NULL;
|
||||
ALTER TABLE `tipam_network` ADD FOREIGN KEY (`location`) REFERENCES `tipam_network_location`(`id`) ON DELETE CASCADE;
|
||||
|
||||
SET @insert_type = 3;
|
||||
SET @insert_name = 'IPAM Recon';
|
||||
@ -4089,6 +4102,7 @@ CREATE TABLE IF NOT EXISTS `tsync_queue` (
|
||||
`operation` text,
|
||||
`table` text,
|
||||
`error` MEDIUMTEXT,
|
||||
`result` TEXT,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
@ -1607,6 +1607,15 @@ if ($update_module || $create_module) {
|
||||
);
|
||||
}
|
||||
|
||||
if ($prediction_module === MODULE_PREDICTION_PLANNING) {
|
||||
$custom_string_2 = get_parameter('estimation_type', 'estimation_calculation');
|
||||
if ($custom_string_2 === 'estimation_calculation') {
|
||||
$custom_string_1 = get_parameter('estimation_days', -1);
|
||||
} else {
|
||||
$custom_string_1 = get_parameter('estimation_interval', '300');
|
||||
}
|
||||
}
|
||||
|
||||
$active_snmp_v3 = get_parameter('active_snmp_v3');
|
||||
|
||||
/*
|
||||
@ -1792,7 +1801,7 @@ if ($update_module) {
|
||||
"Fail to try update module '".io_safe_output($name)."' for agent ".io_safe_output($agent['alias'])
|
||||
);
|
||||
} else {
|
||||
if ($prediction_module == 3) {
|
||||
if ($prediction_module == MODULE_PREDICTION_SYNTHETIC) {
|
||||
enterprise_hook(
|
||||
'modules_create_synthetic_operations',
|
||||
[
|
||||
@ -1937,7 +1946,7 @@ if ($create_module) {
|
||||
}
|
||||
}
|
||||
|
||||
if ($prediction_module == 3 && $serialize_ops == '') {
|
||||
if ($prediction_module == MODULE_PREDICTION_SYNTHETIC && $serialize_ops == '') {
|
||||
$id_agent_module = false;
|
||||
} else {
|
||||
$id_agent_module = modules_create_agent_module(
|
||||
@ -1978,7 +1987,7 @@ if ($create_module) {
|
||||
"Fail to try added module '".io_safe_output($name)."' for agent ".io_safe_output($agent['alias'])
|
||||
);
|
||||
} else {
|
||||
if ($prediction_module == 3) {
|
||||
if ($prediction_module == MODULE_PREDICTION_SYNTHETIC) {
|
||||
enterprise_hook(
|
||||
'modules_create_synthetic_operations',
|
||||
[
|
||||
|
@ -14,6 +14,7 @@
|
||||
enterprise_include_once('include/functions_policies.php');
|
||||
enterprise_include_once('godmode/agentes/module_manager_editor_prediction.php');
|
||||
require_once 'include/functions_agents.php';
|
||||
ui_require_jquery_file('validate');
|
||||
|
||||
$disabledBecauseInPolicy = false;
|
||||
$disabledTextBecauseInPolicy = '';
|
||||
@ -36,9 +37,9 @@ if ($row !== false && is_array($row)) {
|
||||
// Services are an Enterprise feature.
|
||||
$custom_integer_1 = $row['custom_integer_1'];
|
||||
|
||||
switch ($prediction_module) {
|
||||
switch ((int) $prediction_module) {
|
||||
case MODULE_PREDICTION_SERVICE:
|
||||
$is_service = true;
|
||||
$selected = 'service_selected';
|
||||
$custom_integer_2 = 0;
|
||||
break;
|
||||
|
||||
@ -61,20 +62,33 @@ if ($row !== false && is_array($row)) {
|
||||
|
||||
|
||||
if (isset($first_op[1]) && $first_op[1] == 'avg') {
|
||||
$is_synthetic_avg = true;
|
||||
$selected = 'synthetic_avg_selected';
|
||||
} else {
|
||||
$is_synthetic = true;
|
||||
$selected = 'synthetic_selected';
|
||||
}
|
||||
|
||||
$custom_integer_1 = 0;
|
||||
$custom_integer_2 = 0;
|
||||
break;
|
||||
|
||||
case MODULE_PREDICTION_TRENDING:
|
||||
$selected = 'trending_selected';
|
||||
$prediction_module = $custom_integer_1;
|
||||
break;
|
||||
|
||||
case MODULE_PREDICTION_PLANNING:
|
||||
$selected = 'capacity_planning';
|
||||
$prediction_module = $custom_integer_1;
|
||||
$estimation_interval = $custom_string_1;
|
||||
$estimation_type = $custom_string_2;
|
||||
break;
|
||||
|
||||
default:
|
||||
$prediction_module = $custom_integer_1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$selected = 'capacity_planning';
|
||||
$custom_integer_1 = 0;
|
||||
}
|
||||
|
||||
@ -97,7 +111,7 @@ $data[0] = __('Source module');
|
||||
$data[0] .= ui_print_help_icon('prediction_source_module', true);
|
||||
$data[1] = '';
|
||||
// Services and Synthetic are an Enterprise feature.
|
||||
$module_service_synthetic_selector = enterprise_hook('get_module_service_synthetic_selector', [$is_service, $is_synthetic, $is_synthetic_avg]);
|
||||
$module_service_synthetic_selector = enterprise_hook('get_module_service_synthetic_selector', [$selected]);
|
||||
if ($module_service_synthetic_selector !== ENTERPRISE_NOT_HOOK) {
|
||||
$data[1] = $module_service_synthetic_selector;
|
||||
|
||||
@ -112,16 +126,17 @@ $data[1] = '<div id="module_data" class="w50p float-left top-1em">';
|
||||
$data[1] .= html_print_label(__('Agent'), 'agent_name', true).'<br/>';
|
||||
|
||||
// Get module and agent of the target prediction module
|
||||
if (!empty($prediction_module)) {
|
||||
if (empty($prediction_module) === false) {
|
||||
$id_agente_clean = modules_get_agentmodule_agent($prediction_module);
|
||||
$prediction_module_agent = modules_get_agentmodule_agent_name($prediction_module);
|
||||
$agent_name_clean = $prediction_module_agent;
|
||||
$agent_alias = agents_get_alias($id_agente_clean);
|
||||
} else {
|
||||
$id_agente_clean = $id_agente;
|
||||
$agent_name_clean = $agent_name;
|
||||
$id_agente_clean = 0;
|
||||
$agent_name_clean = '';
|
||||
$agent_alias = '';
|
||||
}
|
||||
|
||||
$agent_alias = agents_get_alias($id_agente_clean);
|
||||
|
||||
$params = [];
|
||||
$params['return'] = true;
|
||||
@ -135,7 +150,8 @@ $params['use_hidden_input_idagent'] = true;
|
||||
$params['hidden_input_idagent_id'] = 'hidden-id_agente_module_prediction';
|
||||
$data[1] .= ui_print_agent_autocomplete_input($params);
|
||||
|
||||
$data[1] .= html_print_label(__('Module'), 'prediction_module', true);
|
||||
$data[1] .= '<br />';
|
||||
$data[1] .= html_print_label(__('Module'), 'prediction_module', true).'<br />';
|
||||
if ($id_agente) {
|
||||
$sql = 'SELECT id_agente_modulo, nombre
|
||||
FROM tagente_modulo
|
||||
@ -143,19 +159,23 @@ if ($id_agente) {
|
||||
AND history_data = 1
|
||||
AND id_agente = '.$id_agente_clean.'
|
||||
AND id_agente_modulo <> '.$id_agente_modulo;
|
||||
$data[1] .= html_print_select_from_sql(
|
||||
$sql,
|
||||
'prediction_module',
|
||||
$prediction_module,
|
||||
false,
|
||||
__('Select Module'),
|
||||
0,
|
||||
true
|
||||
|
||||
$data[1] .= html_print_input(
|
||||
[
|
||||
'type' => 'select_from_sql',
|
||||
'sql' => $sql,
|
||||
'name' => 'prediction_module',
|
||||
'selected' => $prediction_module,
|
||||
'nothing' => __('Select Module'),
|
||||
'nothing_value' => 0,
|
||||
'return' => true,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$data[1] .= '<select id="prediction_module" name="custom_integer_1" disabled="disabled"><option value="0">Select an Agent first</option></select>';
|
||||
}
|
||||
|
||||
$data[1] .= '<br />';
|
||||
$data[1] .= html_print_label(__('Period'), 'custom_integer_2', true).'<br/>';
|
||||
|
||||
$periods[0] = __('Weekly');
|
||||
@ -169,6 +189,56 @@ $data[1] .= '</div>';
|
||||
$table_simple->colspan['prediction_module'][1] = 3;
|
||||
push_table_simple($data, 'prediction_module');
|
||||
|
||||
$data = [];
|
||||
$data[0] = '';
|
||||
|
||||
$data[1] .= html_print_label(__('Calculation type'), 'estimation_type', true).'<br/>';
|
||||
$data[1] .= html_print_input(
|
||||
[
|
||||
'type' => 'select',
|
||||
'return' => 'true',
|
||||
'name' => 'estimation_type',
|
||||
'class' => 'w250px',
|
||||
'fields' => [
|
||||
'estimation_absolute' => __('Estimated absolute value'),
|
||||
'estimation_calculation' => __('Calculation of days to reach limit'),
|
||||
],
|
||||
'selected' => $estimation_type,
|
||||
],
|
||||
'div',
|
||||
false
|
||||
);
|
||||
|
||||
$data[1] .= '<div id="estimation_interval_row">';
|
||||
$data[1] .= html_print_label(__('Future estimation'), 'estimation_interval', true).'<br/>';
|
||||
$data[1] .= html_print_input(
|
||||
[
|
||||
'type' => 'interval',
|
||||
'return' => 'true',
|
||||
'name' => 'estimation_interval',
|
||||
'value' => $estimation_interval,
|
||||
],
|
||||
'div',
|
||||
false
|
||||
);
|
||||
$data[1] .= '</div>';
|
||||
|
||||
|
||||
$data[1] .= '<div id="estimation_days_row">';
|
||||
$data[1] .= html_print_label(__('Limit value'), 'estimation_days', true).'<br/>';
|
||||
$data[1] .= html_print_input(
|
||||
[
|
||||
'type' => 'number',
|
||||
'return' => 'true',
|
||||
'id' => 'estimation_days',
|
||||
'name' => 'estimation_days',
|
||||
'value' => $estimation_interval,
|
||||
]
|
||||
);
|
||||
$data[1] .= '</div>';
|
||||
|
||||
push_table_simple($data, 'capacity_planning');
|
||||
|
||||
// Services are an Enterprise feature.
|
||||
$selector_form = enterprise_hook('get_selector_form', [$custom_integer_1]);
|
||||
if ($selector_form !== ENTERPRISE_NOT_HOOK) {
|
||||
@ -187,10 +257,20 @@ if ($synthetic_module_form !== ENTERPRISE_NOT_HOOK) {
|
||||
$data[0] = '';
|
||||
$data[1] = $synthetic_module_form;
|
||||
|
||||
$table_simple->colspan['synthetic_module'][1] = 3;
|
||||
push_table_simple($data, 'synthetic_module');
|
||||
}
|
||||
|
||||
$trending_module_form = enterprise_hook('get_trending_module_form', [$custom_string_1]);
|
||||
if ($trending_module_form !== ENTERPRISE_NOT_HOOK) {
|
||||
$data = [];
|
||||
$data[0] = '';
|
||||
$data[1] .= $trending_module_form;
|
||||
|
||||
push_table_simple($data, 'trending_module');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Netflow modules are an Enterprise feature.
|
||||
$netflow_module_form = enterprise_hook('get_netflow_module_form', [$custom_integer_1]);
|
||||
if ($netflow_module_form !== ENTERPRISE_NOT_HOOK) {
|
||||
@ -214,9 +294,7 @@ unset($table_advanced->data[3]);
|
||||
enterprise_hook(
|
||||
'setup_services_synth',
|
||||
[
|
||||
$is_service,
|
||||
$is_synthetic,
|
||||
$is_synthetic_avg,
|
||||
$selected,
|
||||
$is_netflow,
|
||||
$ops,
|
||||
]
|
||||
|
@ -136,10 +136,10 @@ $percentil = false;
|
||||
$time_compare_overlapped = false;
|
||||
|
||||
// Added for events items.
|
||||
$show_summary_group = false;
|
||||
$show_summary_group = false;
|
||||
$filter_event_severity = false;
|
||||
$filter_event_type = false;
|
||||
$filter_event_status = false;
|
||||
$filter_event_type = false;
|
||||
$filter_event_status = false;
|
||||
$event_graph_by_agent = false;
|
||||
$event_graph_by_user_validator = false;
|
||||
$event_graph_by_criticity = false;
|
||||
@ -175,6 +175,8 @@ $agent_max_value = true;
|
||||
$agent_min_value = true;
|
||||
$uncompressed_module = true;
|
||||
|
||||
$only_data = false;
|
||||
|
||||
// Users.
|
||||
$id_users = [];
|
||||
$users_groups = [];
|
||||
@ -185,6 +187,16 @@ $nothing_value = 0;
|
||||
|
||||
$graph_render = (empty($config['type_mode_graph']) === true) ? 0 : $config['type_mode_graph'];
|
||||
|
||||
$valuesGroupBy = [0 => __('None')];
|
||||
$valuesGroupByDefaultAlertActions = [
|
||||
'agent' => __('Agent'),
|
||||
'module' => __('Module'),
|
||||
'group' => __('Group'),
|
||||
];
|
||||
if (is_metaconsole() === false) {
|
||||
$valuesGroupByDefaultAlertActions['template'] = __('Template');
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'new':
|
||||
$actionParameter = 'save';
|
||||
@ -733,21 +745,73 @@ switch ($action) {
|
||||
case 'agent_module':
|
||||
$description = $item['description'];
|
||||
$es = json_decode($item['external_source'], true);
|
||||
$id_agents = $es['id_agents'];
|
||||
|
||||
// Decode agents and modules.
|
||||
$id_agents = json_decode(
|
||||
io_safe_output(base64_decode($es['id_agents'])),
|
||||
true
|
||||
);
|
||||
$module = json_decode(
|
||||
io_safe_output(base64_decode($es['module'])),
|
||||
true
|
||||
);
|
||||
|
||||
$selection_a_m = get_parameter('selection');
|
||||
$recursion = $item['recursion'];
|
||||
|
||||
if ((count($es['module']) == 1) && ($es['module'][0] == 0)) {
|
||||
$module = '';
|
||||
} else {
|
||||
$module = $es['module'];
|
||||
}
|
||||
|
||||
$group = $item['id_group'];
|
||||
$modulegroup = $item['id_module_group'];
|
||||
$idAgentModule = $module;
|
||||
break;
|
||||
|
||||
case 'alert_report_actions':
|
||||
$description = $item['description'];
|
||||
$es = json_decode($item['external_source'], true);
|
||||
|
||||
// Decode agents and modules.
|
||||
$id_agents = json_decode(
|
||||
io_safe_output(base64_decode($es['id_agents'])),
|
||||
true
|
||||
);
|
||||
$module = json_decode(
|
||||
io_safe_output(base64_decode($es['module'])),
|
||||
true
|
||||
);
|
||||
|
||||
$selection_a_m = get_parameter('selection');
|
||||
$recursion = $item['recursion'];
|
||||
|
||||
$group = $item['id_group'];
|
||||
$modulegroup = $item['id_module_group'];
|
||||
$idAgentModule = $module;
|
||||
|
||||
$alert_templates_selected = $es['templates'];
|
||||
$alert_actions_selected = $es['actions'];
|
||||
|
||||
$show_summary = $es['show_summary'];
|
||||
|
||||
$group_by = $es['group_by'];
|
||||
|
||||
$only_data = $es['only_data'];
|
||||
|
||||
$period = $item['period'];
|
||||
|
||||
$lapse = $item['lapse'];
|
||||
|
||||
// Set values.
|
||||
$valuesGroupBy = [
|
||||
'agent' => __('Agent'),
|
||||
'module' => __('Module'),
|
||||
'group' => __('Group'),
|
||||
];
|
||||
|
||||
if (is_metaconsole() === false) {
|
||||
$valuesGroupBy['template'] = __('Template');
|
||||
}
|
||||
|
||||
$lapse_calc = 1;
|
||||
break;
|
||||
|
||||
case 'agents_inventory':
|
||||
$description = $item['description'];
|
||||
$es = json_decode($item['external_source'], true);
|
||||
@ -1652,30 +1716,12 @@ $class = 'databox filters';
|
||||
<td class="bolder"><?php echo __('Agents'); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$all_agent_log = agents_get_agents(false, ['id_agente', 'alias']);
|
||||
foreach ($all_agent_log as $key => $value) {
|
||||
$agents2[$value['id_agente']] = $value['alias'];
|
||||
}
|
||||
|
||||
if ((empty($agents2)) || $agents2 == -1) {
|
||||
$agents = [];
|
||||
}
|
||||
|
||||
$agents_select = [];
|
||||
if (is_array($id_agents) || is_object($id_agents)) {
|
||||
foreach ($id_agents as $id) {
|
||||
foreach ($agents2 as $key => $a) {
|
||||
if ($key == (int) $id) {
|
||||
$agents_select[$key] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$all_agents = agents_get_agents_selected($group);
|
||||
|
||||
html_print_select(
|
||||
$agents2,
|
||||
$all_agents,
|
||||
'id_agents2[]',
|
||||
$agents_select,
|
||||
$id_agents,
|
||||
$script = '',
|
||||
'',
|
||||
0,
|
||||
@ -1684,7 +1730,23 @@ $class = 'databox filters';
|
||||
true,
|
||||
'',
|
||||
false,
|
||||
'min-width: 180px'
|
||||
'min-width: 500px; max-height: 100px',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
html_print_input_hidden(
|
||||
'id_agents2-multiple-text',
|
||||
json_encode($agents_select)
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
@ -1721,48 +1783,146 @@ $class = 'databox filters';
|
||||
<td class="bolder"><?php echo __('Modules'); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
if (empty($id_agents) || $id_agents == null || $id_agents === 0) {
|
||||
$all_modules = '';
|
||||
if (empty($id_agents) === true) {
|
||||
$all_modules = [];
|
||||
$idAgentModule = [];
|
||||
} else {
|
||||
$all_modules = db_get_all_rows_sql(
|
||||
'SELECT DISTINCT nombre FROM
|
||||
tagente_modulo WHERE id_agente IN ('.implode(',', array_values($id_agents)).')'
|
||||
$all_modules = get_modules_agents(
|
||||
$modulegroup,
|
||||
$id_agents,
|
||||
!$selection_a_m,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if ((empty($all_modules)) || $all_modules == -1) {
|
||||
$all_modules = [];
|
||||
}
|
||||
|
||||
$modules_select = [];
|
||||
$all_modules_structured = [];
|
||||
if (is_array($idAgentModule) || is_object($idAgentModule)) {
|
||||
foreach ($idAgentModule as $id) {
|
||||
foreach ($all_modules as $key => $a) {
|
||||
if ($a['id_agente_modulo'] == (int) $id) {
|
||||
$modules_select[$a['id_agente_modulo']] = $a['id_agente_modulo'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($all_modules as $a) {
|
||||
$all_modules_structured[$a['id_agente_modulo']] = $a['nombre'];
|
||||
}
|
||||
|
||||
html_print_select(
|
||||
$all_modules_structured,
|
||||
$all_modules,
|
||||
'module[]',
|
||||
$modules_select,
|
||||
$idAgentModule,
|
||||
$script = '',
|
||||
__('None'),
|
||||
'',
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
'',
|
||||
false,
|
||||
'min-width: 180px'
|
||||
'min-width: 500px; max-width: 500px; max-height: 100px',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
html_print_input_hidden(
|
||||
'module-multiple-text',
|
||||
json_encode($agents_select)
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="row_alert_templates" class="datos">
|
||||
<td class="bolder"><?php echo __('Templates'); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$alert_templates = [];
|
||||
$own_info = get_user_info($config['id_user']);
|
||||
if ($own_info['is_admin']) {
|
||||
$alert_templates = alerts_get_alert_templates(
|
||||
false,
|
||||
[
|
||||
'id',
|
||||
'name',
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$usr_groups = users_get_groups($config['id_user'], 'LW', true);
|
||||
$filter_groups = '';
|
||||
$filter_groups = implode(',', array_keys($usr_groups));
|
||||
$alert_templates = alerts_get_alert_templates(
|
||||
['id_group IN ('.$filter_groups.')'],
|
||||
[
|
||||
'id',
|
||||
'name',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$alert_templates = array_reduce(
|
||||
$alert_templates,
|
||||
function ($carry, $item) {
|
||||
$carry[$item['id']] = $item['name'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
html_print_select(
|
||||
$alert_templates,
|
||||
'alert_templates[]',
|
||||
$alert_templates_selected,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
'',
|
||||
false,
|
||||
'min-width: 500px; max-height: 100px',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="row_alert_actions" class="datos">
|
||||
<td class="bolder"><?php echo __('Actions'); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$alert_actions = alerts_get_alert_actions(true);
|
||||
html_print_select(
|
||||
$alert_actions,
|
||||
'alert_actions[]',
|
||||
$alert_actions_selected,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
'',
|
||||
false,
|
||||
'min-width: 500px; max-height: 100px',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
@ -2556,6 +2716,23 @@ $class = 'databox filters';
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="row_show_only_data" class="datos">
|
||||
<td class="bolder">
|
||||
<?php
|
||||
echo __('Only data');
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
html_print_checkbox_switch(
|
||||
'only_data',
|
||||
true,
|
||||
$only_data
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="row_event_severity" class="datos">
|
||||
<td class="bolder"><?php echo __('Severity'); ?></td>
|
||||
<td>
|
||||
@ -2924,8 +3101,7 @@ $class = 'databox filters';
|
||||
echo __('Time lapse intervals');
|
||||
ui_print_help_tip(
|
||||
__(
|
||||
'Lapses of time in which the period is divided to make more precise calculations
|
||||
'
|
||||
'Lapses of time in which the period is divided to make more precise calculations'
|
||||
)
|
||||
);
|
||||
?>
|
||||
@ -2936,7 +3112,7 @@ $class = 'databox filters';
|
||||
'lapse',
|
||||
$lapse,
|
||||
'',
|
||||
'',
|
||||
__('None'),
|
||||
'0',
|
||||
10,
|
||||
'',
|
||||
@ -3112,7 +3288,59 @@ $class = 'databox filters';
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr id="row_show_summary" class="datos">
|
||||
<td class="bolder">
|
||||
<?php
|
||||
echo __('Show Summary');
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
html_print_checkbox_switch(
|
||||
'show_summary',
|
||||
true,
|
||||
$show_summary
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="row_group_by" class="datos">
|
||||
<td class="bolder">
|
||||
<?php
|
||||
echo __('Group by');
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
html_print_select(
|
||||
$valuesGroupBy,
|
||||
'group_by',
|
||||
$group_by,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'',
|
||||
false,
|
||||
'',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="row_landscape" class="datos">
|
||||
<td class="bolder">
|
||||
<?php
|
||||
@ -4256,12 +4484,12 @@ $(document).ready (function () {
|
||||
// Load selected modules by default
|
||||
$("#id_agents2").trigger('click');
|
||||
|
||||
$('#combo_server').change (function (){
|
||||
$('#combo_server').change(function () {
|
||||
$("#id_agents").html('');
|
||||
$("#id_agents2").html('');
|
||||
$("#module").html('');
|
||||
$("#inventory_modules").html('');
|
||||
})
|
||||
$("#id_agents2").html('');
|
||||
$("#module").html('');
|
||||
$("#inventory_modules").html('');
|
||||
});
|
||||
|
||||
$("#text-url").keyup (
|
||||
function () {
|
||||
@ -4277,7 +4505,6 @@ $(document).ready (function () {
|
||||
|
||||
$("#combo_group").change (
|
||||
function () {
|
||||
|
||||
// Alert report group must show all matches when selecting All group
|
||||
// ignoring 'recursion' option. #6497.
|
||||
if ($("#combo_group").val() == 0) {
|
||||
@ -4288,7 +4515,12 @@ $(document).ready (function () {
|
||||
}
|
||||
|
||||
$("#id_agents2").html('');
|
||||
// Check agent all.
|
||||
$("#checkbox-id_agents2-check-all").prop('checked', false);
|
||||
$("#module").html('');
|
||||
// Check module all.
|
||||
$("#checkbox-module-check-all").prop('checked', false);
|
||||
|
||||
$("#inventory_modules").html('');
|
||||
jQuery.post ("ajax.php",
|
||||
{"page" : "operation/agentes/ver_agente",
|
||||
@ -4314,7 +4546,6 @@ $(document).ready (function () {
|
||||
);
|
||||
}
|
||||
);
|
||||
$("#combo_group").change();
|
||||
|
||||
$("#checkbox-recursion").change (
|
||||
function () {
|
||||
@ -4328,6 +4559,11 @@ $(document).ready (function () {
|
||||
},
|
||||
function (data, status) {
|
||||
$("#id_agents2").html('');
|
||||
// Check agent all.
|
||||
$("#checkbox-id_agents2-check-all").prop('checked', false);
|
||||
$("#module").html('');
|
||||
// Check module all.
|
||||
$("#checkbox-module-check-all").prop('checked', false);
|
||||
jQuery.each (data, function (id, value) {
|
||||
// Remove keys_prefix from the index
|
||||
id = id.substring(1);
|
||||
@ -4351,14 +4587,17 @@ $(document).ready (function () {
|
||||
"get_modules_group_json" : 1,
|
||||
"id_module_group" : this.value,
|
||||
"id_agents" : $("#id_agents2").val(),
|
||||
"selection" : $("#selection_agent_module").val()
|
||||
"selection" : $("#selection_agent_module").val(),
|
||||
"select_mode": 1
|
||||
},
|
||||
function (data, status) {
|
||||
$("#module").html('');
|
||||
// Check module all.
|
||||
$("#checkbox-module-check-all").prop('checked', false);
|
||||
jQuery.each (data, function (id, value) {
|
||||
option = $("<option></option>")
|
||||
.attr ("value", value["id_agente_modulo"])
|
||||
.html (value["nombre"]);
|
||||
.attr ("value", id)
|
||||
.html (value);
|
||||
$("#module").append (option);
|
||||
});
|
||||
},
|
||||
@ -4372,17 +4611,20 @@ $(document).ready (function () {
|
||||
jQuery.post ("ajax.php",
|
||||
{"page" : "operation/agentes/ver_agente",
|
||||
"get_modules_group_json" : 1,
|
||||
"selection" : $("#selection_agent_module").val(),
|
||||
"id_module_group" : $("#combo_modulegroup").val(),
|
||||
"id_agents" : $("#id_agents2").val(),
|
||||
"selection" : $("#selection_agent_module").val()
|
||||
"select_mode": 1
|
||||
},
|
||||
function (data, status) {
|
||||
$("#module").html('');
|
||||
// Check module all.
|
||||
$("#checkbox-module-check-all").prop('checked', false);
|
||||
if(data){
|
||||
jQuery.each (data, function (id, value) {
|
||||
option = $("<option></option>")
|
||||
.attr ("value", value["id_agente_modulo"])
|
||||
.html (value["nombre"]);
|
||||
.attr ("value", id)
|
||||
.html (value);
|
||||
$("#module").append (option);
|
||||
});
|
||||
}
|
||||
@ -4399,15 +4641,18 @@ $(document).ready (function () {
|
||||
"get_modules_group_json" : 1,
|
||||
"id_module_group" : $("#combo_modulegroup").val(),
|
||||
"id_agents" : $("#id_agents2").val(),
|
||||
"selection" : $("#selection_agent_module").val()
|
||||
"selection" : $("#selection_agent_module").val(),
|
||||
"select_mode": 1
|
||||
},
|
||||
function (data, status) {
|
||||
$("#module").html('');
|
||||
// Check module all.
|
||||
$("#checkbox-module-check-all").prop('checked', false);
|
||||
if(data){
|
||||
jQuery.each (data, function (id, value) {
|
||||
option = $("<option></option>")
|
||||
.attr ("value", value["id_agente_modulo"])
|
||||
.html (value["nombre"]);
|
||||
.attr ("value", id)
|
||||
.html (value);
|
||||
$("#module").append (option);
|
||||
});
|
||||
}
|
||||
@ -4498,6 +4743,15 @@ $(document).ready (function () {
|
||||
}
|
||||
|
||||
switch (type){
|
||||
case 'agent_module':
|
||||
case 'alert_report_actions':
|
||||
var agents_multiple = $('#id_agents2').val();
|
||||
var modules_multiple = $('#module').val();
|
||||
$('#hidden-id_agents2-multiple-text').val(JSON.stringify(agents_multiple));
|
||||
$('#hidden-module-multiple-text').val(JSON.stringify(modules_multiple));
|
||||
$('#id_agents2').val('');
|
||||
$('#module').val('');
|
||||
break;
|
||||
case 'alert_report_module':
|
||||
case 'alert_report_agent':
|
||||
case 'event_report_agent':
|
||||
@ -4522,12 +4776,6 @@ $(document).ready (function () {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'agent_module':
|
||||
if ($("select#id_agents2>option:selected").val() == undefined) {
|
||||
dialog_message('#message_no_agent');
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'inventory':
|
||||
case 'inventory_changes':
|
||||
if ($("select#id_agents>option:selected").val() == undefined) {
|
||||
@ -4572,18 +4820,11 @@ $(document).ready (function () {
|
||||
case 'sumatory':
|
||||
case 'historical_data':
|
||||
case 'increment':
|
||||
|
||||
if ($("#id_agent_module").val() == 0) {
|
||||
dialog_message('#message_no_module');
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'agent_module':
|
||||
if ($("select#module>option:selected").val() == undefined) {
|
||||
dialog_message('#message_no_module');
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'inventory':
|
||||
case 'inventory_changes':
|
||||
if ($("select#inventory_modules>option:selected").val() == 0) {
|
||||
@ -4636,6 +4877,15 @@ $(document).ready (function () {
|
||||
return false;
|
||||
}
|
||||
switch (type){
|
||||
case 'agent_module':
|
||||
case 'alert_report_actions':
|
||||
var agents_multiple = $('#id_agents2').val();
|
||||
var modules_multiple = $('#module').val();
|
||||
$('#hidden-id_agents2-multiple-text').val(JSON.stringify(agents_multiple));
|
||||
$('#hidden-module-multiple-text').val(JSON.stringify(modules_multiple));
|
||||
$('#id_agents2').val('');
|
||||
$('#module').val('');
|
||||
break;
|
||||
case 'alert_report_module':
|
||||
case 'alert_report_agent':
|
||||
case 'event_report_agent':
|
||||
@ -4660,12 +4910,6 @@ $(document).ready (function () {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'agent_module':
|
||||
if ($("select#id_agents2>option:selected").val() == undefined) {
|
||||
dialog_message('#message_no_agent');
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'inventory':
|
||||
if ($("select#id_agents>option:selected").val() == undefined) {
|
||||
dialog_message('#message_no_agent');
|
||||
@ -4705,18 +4949,11 @@ $(document).ready (function () {
|
||||
case 'sumatory':
|
||||
case 'historical_data':
|
||||
case 'increment':
|
||||
|
||||
if ($("#id_agent_module").val() == 0) {
|
||||
dialog_message('#message_no_module');
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'agent_module':
|
||||
if ($("select#module>option:selected").val() == undefined) {
|
||||
dialog_message('#message_no_module');
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'inventory':
|
||||
if ($("select#inventory_modules>option:selected").val() == 0) {
|
||||
dialog_message('#message_no_module');
|
||||
@ -5489,6 +5726,7 @@ function addGeneralRow() {
|
||||
}
|
||||
|
||||
function chooseType() {
|
||||
var meta = '<?php echo (is_metaconsole() === true) ? 1 : 0; ?>';
|
||||
type = $("#type").val();
|
||||
$("#row_description").hide();
|
||||
$("#row_label").hide();
|
||||
@ -5542,6 +5780,8 @@ function chooseType() {
|
||||
$('#row_hide_notinit_agents').hide();
|
||||
$('#row_priority_mode').hide();
|
||||
$("#row_module_group").hide();
|
||||
$("#row_alert_templates").hide();
|
||||
$("#row_alert_actions").hide();
|
||||
$("#row_servers").hide();
|
||||
$("#row_sort").hide();
|
||||
$("#row_date").hide();
|
||||
@ -5566,6 +5806,7 @@ function chooseType() {
|
||||
$("#select_agent_modules").hide();
|
||||
$("#modules_row").hide();
|
||||
$("#row_show_summary_group").hide();
|
||||
$("#row_show_only_data").hide();
|
||||
$("#row_event_severity").hide();
|
||||
$("#row_event_type").hide();
|
||||
$("#row_event_status").hide();
|
||||
@ -5590,6 +5831,8 @@ function chooseType() {
|
||||
$("#row_network_filter").hide();
|
||||
$("#row_alive_ip").hide();
|
||||
$("#row_agent_not_assigned_to_ip").hide();
|
||||
$("#row_show_summary").hide();
|
||||
$("#row_group_by").hide();
|
||||
|
||||
// SLA list default state.
|
||||
$("#sla_list").hide();
|
||||
@ -5900,6 +6143,37 @@ function chooseType() {
|
||||
$("#row_historical_db_check").hide();
|
||||
break;
|
||||
|
||||
case 'alert_report_actions':
|
||||
$("#row_description").show();
|
||||
$("#row_group").show();
|
||||
$("#select_agent_modules").show();
|
||||
$("#agents_modules_row").show();
|
||||
$("#modules_row").show();
|
||||
if(meta == 0){
|
||||
$("#row_alert_templates").show();
|
||||
}
|
||||
$("#row_alert_actions").show();
|
||||
$("#row_period").show();
|
||||
$("#row_lapse").show();
|
||||
$("#row_show_summary").show();
|
||||
$("#row_show_only_data").show();
|
||||
$("#row_group_by").show();
|
||||
if('<?php echo $action; ?>' === 'new'){
|
||||
$("#group_by").html('');
|
||||
var dataDefault = '<?php echo json_encode($valuesGroupByDefaultAlertActions); ?>';
|
||||
Object.entries(JSON.parse(dataDefault)).forEach(function (item) {
|
||||
option = $("<option></option>")
|
||||
.attr ("value", item[0])
|
||||
.html (item[1]);
|
||||
$("#group_by").append(option);
|
||||
});
|
||||
|
||||
$("#lapse_select").attr('disabled', false);
|
||||
$("#lapse_select").val('0').trigger('change');
|
||||
$("#hidden-lapse").val('0');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'event_report_group':
|
||||
$("#row_description").show();
|
||||
$("#row_period").show();
|
||||
|
@ -1676,22 +1676,77 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 'agent_module':
|
||||
$agents_to_report = get_parameter('id_agents2');
|
||||
$modules_to_report = get_parameter(
|
||||
'module',
|
||||
''
|
||||
$agents_to_report_text = get_parameter('id_agents2-multiple-text', '');
|
||||
$modules_to_report_text = get_parameter('module-multiple-text', '');
|
||||
|
||||
// Decode json check modules.
|
||||
$agents_to_report = json_decode(
|
||||
io_safe_output($agents_to_report_text),
|
||||
true
|
||||
);
|
||||
$modules_to_report = json_decode(
|
||||
io_safe_output($modules_to_report_text),
|
||||
true
|
||||
);
|
||||
|
||||
$es['module'] = get_same_modules(
|
||||
$es['module'] = get_same_modules_all(
|
||||
$agents_to_report,
|
||||
$modules_to_report
|
||||
);
|
||||
$es['id_agents'] = $agents_to_report;
|
||||
|
||||
// Encode json modules and agents.
|
||||
$es['module'] = base64_encode(json_encode($es['module']));
|
||||
$es['id_agents'] = base64_encode(json_encode($agents_to_report));
|
||||
|
||||
$values['external_source'] = json_encode($es);
|
||||
$good_format = true;
|
||||
break;
|
||||
|
||||
case 'alert_report_actions':
|
||||
$alert_templates_to_report = get_parameter('alert_templates');
|
||||
$alert_actions_to_report = get_parameter('alert_actions');
|
||||
$show_summary = get_parameter('show_summary', 0);
|
||||
$group_by = get_parameter('group_by');
|
||||
$only_data = get_parameter('only_data', 0);
|
||||
$agents_to_report_text = get_parameter('id_agents2-multiple-text');
|
||||
$modules_to_report_text = get_parameter('module-multiple-text', '');
|
||||
|
||||
// Decode json check modules.
|
||||
$agents_to_report = json_decode(
|
||||
io_safe_output($agents_to_report_text),
|
||||
true
|
||||
);
|
||||
$modules_to_report = json_decode(
|
||||
io_safe_output($modules_to_report_text),
|
||||
true
|
||||
);
|
||||
|
||||
$es['module'] = get_same_modules_all(
|
||||
$agents_to_report,
|
||||
$modules_to_report
|
||||
);
|
||||
|
||||
// Encode json modules and agents.
|
||||
$es['module'] = base64_encode(json_encode($es['module']));
|
||||
$es['id_agents'] = base64_encode(json_encode($agents_to_report));
|
||||
|
||||
$es['templates'] = $alert_templates_to_report;
|
||||
$es['actions'] = $alert_actions_to_report;
|
||||
$es['show_summary'] = $show_summary;
|
||||
$es['group_by'] = $group_by;
|
||||
$es['only_data'] = $only_data;
|
||||
|
||||
$values['external_source'] = json_encode($es);
|
||||
|
||||
$values['period'] = get_parameter('period');
|
||||
$values['lapse_calc'] = get_parameter(
|
||||
'lapse_calc'
|
||||
);
|
||||
$values['lapse'] = get_parameter('lapse');
|
||||
|
||||
$good_format = true;
|
||||
break;
|
||||
|
||||
case 'inventory':
|
||||
$values['period'] = 0;
|
||||
$es['date'] = get_parameter('date');
|
||||
@ -2422,22 +2477,78 @@ switch ($action) {
|
||||
break;
|
||||
|
||||
case 'agent_module':
|
||||
$agents_to_report = get_parameter('id_agents2');
|
||||
$modules_to_report = get_parameter(
|
||||
'module',
|
||||
''
|
||||
$agents_to_report_text = get_parameter('id_agents2-multiple-text');
|
||||
$modules_to_report_text = get_parameter('module-multiple-text', '');
|
||||
|
||||
// Decode json check modules.
|
||||
$agents_to_report = json_decode(
|
||||
io_safe_output($agents_to_report_text),
|
||||
true
|
||||
);
|
||||
$modules_to_report = json_decode(
|
||||
io_safe_output($modules_to_report_text),
|
||||
true
|
||||
);
|
||||
|
||||
$es['module'] = get_same_modules(
|
||||
$es['module'] = get_same_modules_all(
|
||||
$agents_to_report,
|
||||
$modules_to_report
|
||||
);
|
||||
$es['id_agents'] = $agents_to_report;
|
||||
|
||||
// Encode json modules and agents.
|
||||
$es['module'] = base64_encode(json_encode($es['module']));
|
||||
$es['id_agents'] = base64_encode(json_encode($agents_to_report));
|
||||
|
||||
$values['external_source'] = json_encode($es);
|
||||
$good_format = true;
|
||||
break;
|
||||
|
||||
case 'alert_report_actions':
|
||||
$alert_templates_to_report = get_parameter('alert_templates');
|
||||
$alert_actions_to_report = get_parameter('alert_actions');
|
||||
$show_summary = get_parameter('show_summary', 0);
|
||||
$group_by = get_parameter('group_by');
|
||||
$only_data = get_parameter('only_data', 0);
|
||||
|
||||
$agents_to_report_text = get_parameter('id_agents2-multiple-text');
|
||||
$modules_to_report_text = get_parameter('module-multiple-text', '');
|
||||
|
||||
// Decode json check modules.
|
||||
$agents_to_report = json_decode(
|
||||
io_safe_output($agents_to_report_text),
|
||||
true
|
||||
);
|
||||
$modules_to_report = json_decode(
|
||||
io_safe_output($modules_to_report_text),
|
||||
true
|
||||
);
|
||||
|
||||
$es['module'] = get_same_modules_all(
|
||||
$agents_to_report,
|
||||
$modules_to_report
|
||||
);
|
||||
|
||||
// Encode json modules and agents.
|
||||
$es['module'] = base64_encode(json_encode($es['module']));
|
||||
$es['id_agents'] = base64_encode(json_encode($agents_to_report));
|
||||
|
||||
$es['templates'] = $alert_templates_to_report;
|
||||
$es['actions'] = $alert_actions_to_report;
|
||||
$es['show_summary'] = $show_summary;
|
||||
$es['group_by'] = $group_by;
|
||||
$es['only_data'] = $only_data;
|
||||
|
||||
$values['external_source'] = json_encode($es);
|
||||
|
||||
$values['period'] = get_parameter('period');
|
||||
$values['lapse_calc'] = get_parameter(
|
||||
'lapse_calc'
|
||||
);
|
||||
$values['lapse'] = get_parameter('lapse');
|
||||
|
||||
$good_format = true;
|
||||
break;
|
||||
|
||||
case 'inventory_changes':
|
||||
$values['period'] = get_parameter('period');
|
||||
$es['id_agents'] = get_parameter('id_agents');
|
||||
|
BIN
pandora_console/images/building.png
Normal file
BIN
pandora_console/images/building.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
@ -83,10 +83,10 @@ $in_process_event = get_parameter('in_process_event', 0);
|
||||
$validate_event = get_parameter('validate_event', 0);
|
||||
$delete_event = get_parameter('delete_event', 0);
|
||||
$get_event_filters = get_parameter('get_event_filters', 0);
|
||||
$get_comments = get_parameter('get_comments', 0);
|
||||
$get_comments = (bool) get_parameter('get_comments', false);
|
||||
$get_events_fired = (bool) get_parameter('get_events_fired');
|
||||
$get_id_source_event = get_parameter('get_id_source_event');
|
||||
if ($get_comments) {
|
||||
if ($get_comments === true) {
|
||||
$event = get_parameter('event', false);
|
||||
$filter = get_parameter('filter', false);
|
||||
|
||||
@ -94,6 +94,8 @@ if ($get_comments) {
|
||||
return __('Failed to retrieve comments');
|
||||
}
|
||||
|
||||
$eventsGrouped = [];
|
||||
|
||||
if ($filter['group_rep'] == 1) {
|
||||
$events = events_get_all(
|
||||
['te.*'],
|
||||
@ -119,23 +121,52 @@ if ($get_comments) {
|
||||
// True for show comments of validated events.
|
||||
true
|
||||
);
|
||||
|
||||
if ($events !== false) {
|
||||
$event = $events[0];
|
||||
}
|
||||
} else {
|
||||
$events = events_get_event(
|
||||
$event['id_evento'],
|
||||
false,
|
||||
$meta,
|
||||
$history
|
||||
);
|
||||
// Consider if the event is grouped.
|
||||
if (isset($event['event_rep']) === true && $event['event_rep'] > 0) {
|
||||
// Evaluate if we are in metaconsole or not.
|
||||
$eventTable = (is_metaconsole() === true) ? 'tmetaconsole_event' : 'tevento';
|
||||
// Default grouped message filtering (evento and estado).
|
||||
$whereGrouped = sprintf(
|
||||
'`evento` = "%s" AND `estado` = "%s"',
|
||||
io_safe_output($event['evento']),
|
||||
$event['estado']
|
||||
);
|
||||
// If id_agente is reported, filter the messages by them as well.
|
||||
if ((int) $event['id_agente'] > 0) {
|
||||
$whereGrouped .= sprintf(' AND `id_agente` = "%s"', $event['id_agente']);
|
||||
}
|
||||
|
||||
if ($events !== false) {
|
||||
$event = $events;
|
||||
// Get grouped comments.
|
||||
$eventsGrouped = db_get_all_rows_sql(
|
||||
sprintf(
|
||||
'SELECT `user_comment`
|
||||
FROM `%s`
|
||||
WHERE %s',
|
||||
$eventTable,
|
||||
$whereGrouped
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$events = events_get_event(
|
||||
$event['id_evento'],
|
||||
false,
|
||||
is_metaconsole(),
|
||||
$history
|
||||
);
|
||||
|
||||
if ($events !== false) {
|
||||
$event = $events;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo events_page_comments($event, true);
|
||||
// End of get_comments.
|
||||
echo events_page_comments($event, true, $eventsGrouped);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1207,26 +1238,19 @@ if ($dialogue_event_response) {
|
||||
}
|
||||
}
|
||||
|
||||
if ($add_comment) {
|
||||
$aviability_comment = true;
|
||||
$comment = get_parameter('comment');
|
||||
if ($add_comment === true) {
|
||||
$comment = (string) get_parameter('comment');
|
||||
$eventId = (int) get_parameter('event_id');
|
||||
|
||||
// Safe comments for hacks.
|
||||
if (preg_match('/script/i', io_safe_output($comment))) {
|
||||
$aviability_comment = false;
|
||||
$return = false;
|
||||
}
|
||||
|
||||
$event_id = get_parameter('event_id');
|
||||
|
||||
if ($aviability_comment !== false) {
|
||||
$return = events_comment($event_id, $comment, 'Added comment', $meta, $history);
|
||||
}
|
||||
|
||||
if ($return) {
|
||||
echo 'comment_ok';
|
||||
} else {
|
||||
echo 'comment_error';
|
||||
$return = events_comment($eventId, $comment, 'Added comment', $meta, $history);
|
||||
}
|
||||
|
||||
echo ($return === true) ? 'comment_ok' : 'comment_error';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Pandora build version and version
|
||||
*/
|
||||
$build_version = 'PC211207';
|
||||
$build_version = 'PC211214';
|
||||
$pandora_version = 'v7.0NG.758.1';
|
||||
|
||||
// Do not overwrite default timezone set if defined.
|
||||
|
@ -368,12 +368,15 @@ define('MODULE_WUX', 8);
|
||||
define('MODULE_WIZARD', 9);
|
||||
|
||||
// Type of Modules of Prediction.
|
||||
define('MODULE_PREDICTION_PLANNING', 1);
|
||||
define('MODULE_PREDICTION_SERVICE', 2);
|
||||
define('MODULE_PREDICTION_SYNTHETIC', 3);
|
||||
define('MODULE_PREDICTION_NETFLOW', 4);
|
||||
define('MODULE_PREDICTION_CLUSTER', 5);
|
||||
define('MODULE_PREDICTION_CLUSTER_AA', 6);
|
||||
define('MODULE_PREDICTION_CLUSTER_AP', 7);
|
||||
define('MODULE_PREDICTION_TRENDING', 8);
|
||||
|
||||
|
||||
// Forced agent OS ID for cluster agents.
|
||||
define('CLUSTER_OS_ID', 100);
|
||||
|
@ -1295,57 +1295,6 @@ function mysql_db_get_all_row_by_steps_sql($new=true, &$result, $sql=null)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts a database transaction.
|
||||
*/
|
||||
function mysql_db_process_sql_begin()
|
||||
{
|
||||
global $config;
|
||||
|
||||
if ($config['mysqli']) {
|
||||
mysqli_query($config['dbconnection'], 'SET AUTOCOMMIT = 0');
|
||||
mysqli_query($config['dbconnection'], 'START TRANSACTION');
|
||||
} else {
|
||||
mysql_query('SET AUTOCOMMIT = 0');
|
||||
mysql_query('START TRANSACTION');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Commits a database transaction.
|
||||
*/
|
||||
function mysql_db_process_sql_commit()
|
||||
{
|
||||
global $config;
|
||||
|
||||
if ($config['mysqli']) {
|
||||
mysqli_query($config['dbconnection'], 'COMMIT');
|
||||
mysqli_query($config['dbconnection'], 'SET AUTOCOMMIT = 1');
|
||||
} else {
|
||||
mysql_query('COMMIT');
|
||||
mysql_query('SET AUTOCOMMIT = 1');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rollbacks a database transaction.
|
||||
*/
|
||||
function mysql_db_process_sql_rollback()
|
||||
{
|
||||
global $config;
|
||||
|
||||
if ($config['mysqli']) {
|
||||
mysqli_query($config['dbconnection'], 'ROLLBACK ');
|
||||
mysqli_query($config['dbconnection'], 'SET AUTOCOMMIT = 1');
|
||||
} else {
|
||||
mysql_query('ROLLBACK ');
|
||||
mysql_query('SET AUTOCOMMIT = 1');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get last error.
|
||||
*
|
||||
@ -1441,7 +1390,7 @@ function mysql_db_process_file($path, $handle_error=true)
|
||||
$query = '';
|
||||
|
||||
// Begin the transaction
|
||||
mysql_db_process_sql_begin();
|
||||
db_process_sql_begin();
|
||||
|
||||
foreach ($file_content as $sql_line) {
|
||||
if (trim($sql_line) != '' && strpos($sql_line, '--') === false) {
|
||||
@ -1456,7 +1405,7 @@ function mysql_db_process_file($path, $handle_error=true)
|
||||
|
||||
if (!$result = $query_result) {
|
||||
// Error. Rollback the transaction
|
||||
mysql_db_process_sql_rollback();
|
||||
db_process_sql_rollback();
|
||||
|
||||
if ($config['mysqli']) {
|
||||
$error_message = mysqli_error($config['dbconnection']);
|
||||
@ -1493,7 +1442,7 @@ function mysql_db_process_file($path, $handle_error=true)
|
||||
}
|
||||
|
||||
// No errors. Commit the transaction
|
||||
mysql_db_process_sql_commit();
|
||||
db_process_sql_commit();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -1532,7 +1481,7 @@ function db_run_sql_file($location)
|
||||
$mysqli->query($config['dbconnection'], 'START TRANSACTION');
|
||||
} else {
|
||||
// Run commands
|
||||
mysql_db_process_sql_begin();
|
||||
db_process_sql_begin();
|
||||
// Begin transaction
|
||||
}
|
||||
|
||||
@ -1558,7 +1507,7 @@ function db_run_sql_file($location)
|
||||
$mysqli->query($config['dbconnection'], 'COMMIT');
|
||||
$mysqli->query($config['dbconnection'], 'SET AUTOCOMMIT = 1');
|
||||
} else {
|
||||
mysql_db_process_sql_commit();
|
||||
db_process_sql_commit();
|
||||
// Save results
|
||||
}
|
||||
|
||||
@ -1568,7 +1517,7 @@ function db_run_sql_file($location)
|
||||
$mysqli->query($config['dbconnection'], 'ROLLBACK ');
|
||||
$mysqli->query($config['dbconnection'], 'SET AUTOCOMMIT = 1');
|
||||
} else {
|
||||
mysql_db_process_sql_rollback();
|
||||
db_process_sql_rollback();
|
||||
// Undo results
|
||||
}
|
||||
|
||||
|
@ -733,6 +733,63 @@ function agents_get_agents(
|
||||
}
|
||||
|
||||
|
||||
function agents_get_agents_selected($group)
|
||||
{
|
||||
if (is_metaconsole() === true) {
|
||||
$all = agents_get_agents(
|
||||
['id_grupo' => $group],
|
||||
[
|
||||
'id_tagente',
|
||||
'id_tmetaconsole_setup',
|
||||
'id_agente',
|
||||
'alias',
|
||||
],
|
||||
'AR',
|
||||
[
|
||||
'field' => 'alias',
|
||||
'order' => 'ASC',
|
||||
],
|
||||
false,
|
||||
0,
|
||||
true
|
||||
);
|
||||
|
||||
$all = array_reduce(
|
||||
$all,
|
||||
function ($carry, $item) {
|
||||
$carry[$item['id_tmetaconsole_setup'].'|'.$item['id_tagente']] = $item['alias'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
} else {
|
||||
$all = agents_get_agents(
|
||||
['id_grupo' => $group],
|
||||
[
|
||||
'id_agente',
|
||||
'alias',
|
||||
],
|
||||
'AR',
|
||||
[
|
||||
'field' => 'alias',
|
||||
'order' => 'ASC',
|
||||
]
|
||||
);
|
||||
|
||||
$all = array_reduce(
|
||||
$all,
|
||||
function ($carry, $item) {
|
||||
$carry[$item['id_agente']] = $item['alias'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
return $all;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all the alerts of an agent, simple and combined.
|
||||
*
|
||||
@ -1649,6 +1706,85 @@ function agents_get_name($id_agent, $case='none')
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the agents names of an agent.
|
||||
*
|
||||
* @param array $array_ids Agents ids.
|
||||
*
|
||||
* @return array Id => name.
|
||||
*/
|
||||
function agents_get_alias_array($array_ids)
|
||||
{
|
||||
if (is_array($array_ids) === false || empty($array_ids) === true) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ((bool) is_metaconsole() === true) {
|
||||
$agents = array_reduce(
|
||||
$array_ids,
|
||||
function ($carry, $item) {
|
||||
$explode = explode('|', $item);
|
||||
|
||||
$carry[$explode[0]][] = $explode[1];
|
||||
return $carry;
|
||||
}
|
||||
);
|
||||
|
||||
$result = [];
|
||||
foreach ($agents as $tserver => $id_agents) {
|
||||
$sql = sprintf(
|
||||
'SELECT id_tagente as id, alias as `name`
|
||||
FROM tmetaconsole_agent
|
||||
WHERE id_tagente IN (%s) AND id_tmetaconsole_setup = %d',
|
||||
implode(',', $id_agents),
|
||||
$tserver
|
||||
);
|
||||
|
||||
$data_server = db_get_all_rows_sql($sql);
|
||||
|
||||
if ($data_server === false) {
|
||||
$data_server = [];
|
||||
}
|
||||
|
||||
$data_server = array_reduce(
|
||||
$data_server,
|
||||
function ($carry, $item) {
|
||||
$carry[$item['id']] = $item['name'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
$result[$tserver] = $data_server;
|
||||
}
|
||||
} else {
|
||||
$sql = sprintf(
|
||||
'SELECT id_agente as id, alias as `name`
|
||||
FROM tagente
|
||||
WHERE id_agente IN (%s)',
|
||||
implode(',', $array_ids)
|
||||
);
|
||||
|
||||
$result = db_get_all_rows_sql($sql);
|
||||
|
||||
if ($result === false) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
$result = array_reduce(
|
||||
$result,
|
||||
function ($carry, $item) {
|
||||
$carry[$item['id']] = $item['name'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get alias of an agent (cached function).
|
||||
*
|
||||
|
@ -2837,3 +2837,588 @@ function alerts_get_agent_modules(
|
||||
return $agent_modules;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function alerts_get_actions_names($actions, $reduce=false)
|
||||
{
|
||||
$where = '';
|
||||
if (empty($actions) === false) {
|
||||
if (is_array($actions) === true) {
|
||||
$where = sprintf(
|
||||
'WHERE id IN (%s)',
|
||||
implode(',', $actions)
|
||||
);
|
||||
} else {
|
||||
$where = sprintf('WHERE id = %d', $actions);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = sprintf(
|
||||
'SELECT id, `name`
|
||||
FROM talert_actions
|
||||
%s',
|
||||
$where
|
||||
);
|
||||
|
||||
$result = db_get_all_rows_sql($sql);
|
||||
|
||||
if ($result === false) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
if ($reduce === true) {
|
||||
$result = array_reduce(
|
||||
$result,
|
||||
function ($carry, $item) {
|
||||
$carry[$item['id']] = $item['name'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Alert fired.
|
||||
*
|
||||
* @param array $filters Filters.
|
||||
* @param array $groupsBy Groupby and lapse.
|
||||
*
|
||||
* @return array Result data.
|
||||
*/
|
||||
function alerts_get_alert_fired($filters=[], $groupsBy=[])
|
||||
{
|
||||
global $config;
|
||||
|
||||
$table = 'tevento';
|
||||
if (is_metaconsole() === true) {
|
||||
$table = 'tmetaconsole_event';
|
||||
}
|
||||
|
||||
$filter_date = '';
|
||||
if (isset($filters['period']) === true
|
||||
&& empty($filters['period']) === false
|
||||
) {
|
||||
$filter_date = sprintf(
|
||||
'AND %s.utimestamp > %d',
|
||||
$table,
|
||||
(time() - $filters['period'])
|
||||
);
|
||||
}
|
||||
|
||||
$filter_group = '';
|
||||
if (isset($filters['group']) === true
|
||||
&& empty($filters['group']) === false
|
||||
) {
|
||||
$filter_group = sprintf(
|
||||
'AND %s.id_grupo = %d',
|
||||
$table,
|
||||
$filters['group']
|
||||
);
|
||||
}
|
||||
|
||||
$filter_agents = '';
|
||||
if (isset($filters['agents']) === true
|
||||
&& empty($filters['agents']) === false
|
||||
) {
|
||||
if (is_metaconsole() === true) {
|
||||
$agents = array_reduce(
|
||||
$filters['agents'],
|
||||
function ($carry, $item) {
|
||||
$explode = explode('|', $item);
|
||||
|
||||
$carry[$explode[0]][] = $explode[1];
|
||||
return $carry;
|
||||
}
|
||||
);
|
||||
|
||||
$filter_agents .= ' AND ( ';
|
||||
$i = 0;
|
||||
foreach ($agents as $tserver => $agent) {
|
||||
if ($i !== 0) {
|
||||
$filter_agents .= ' OR ';
|
||||
}
|
||||
|
||||
$filter_agents .= sprintf(
|
||||
'( %s.id_agente IN (%s) AND %s.server_id = %d )',
|
||||
$table,
|
||||
implode(',', $agent),
|
||||
$table,
|
||||
(int) $tserver
|
||||
);
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
$filter_agents .= ' )';
|
||||
} else {
|
||||
$filter_agents = sprintf(
|
||||
'AND %s.id_agente IN (%s)',
|
||||
$table,
|
||||
implode(',', $filters['agents'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$filter_modules = '';
|
||||
if (isset($filters['modules']) === true
|
||||
&& empty($filters['modules']) === false
|
||||
) {
|
||||
if (is_metaconsole() === true) {
|
||||
$modules = array_reduce(
|
||||
$filters['modules'],
|
||||
function ($carry, $item) {
|
||||
$explode = explode('|', $item);
|
||||
|
||||
$carry[$explode[0]][] = $explode[1];
|
||||
return $carry;
|
||||
}
|
||||
);
|
||||
|
||||
$filter_modules .= ' AND ( ';
|
||||
$i = 0;
|
||||
foreach ($modules as $tserver => $module) {
|
||||
if ($i !== 0) {
|
||||
$filter_modules .= ' OR ';
|
||||
}
|
||||
|
||||
$filter_modules .= sprintf(
|
||||
'( %s.id_agentmodule IN (%s) AND %s.server_id = %d )',
|
||||
$table,
|
||||
implode(',', $module),
|
||||
$table,
|
||||
(int) $tserver
|
||||
);
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
$filter_modules .= ' )';
|
||||
} else {
|
||||
$filter_modules = sprintf(
|
||||
'AND %s.id_agentmodule IN (%s)',
|
||||
$table,
|
||||
implode(',', $filters['modules'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$filter_templates = '';
|
||||
if (isset($filters['templates']) === true
|
||||
&& empty($filters['templates']) === false
|
||||
) {
|
||||
if (is_metaconsole() === false) {
|
||||
$filter_templates = sprintf(
|
||||
'AND talert_template_modules.id_alert_template IN (%s)',
|
||||
implode(',', $filters['templates'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$total = (bool) $filters['show_summary'];
|
||||
$only_data = (bool) $filters['only_data'];
|
||||
|
||||
$actions_names = alerts_get_actions_names($filters['actions'], true);
|
||||
|
||||
$group_array = [];
|
||||
|
||||
$filter_actions = '';
|
||||
$fields_actions = [];
|
||||
if (isset($filters['actions']) === true
|
||||
&& empty($filters['actions']) === false
|
||||
) {
|
||||
$filter_actions .= 'AND ( ';
|
||||
$first = true;
|
||||
foreach ($actions_names as $name_action) {
|
||||
if ($first === false) {
|
||||
$filter_actions .= ' OR ';
|
||||
}
|
||||
|
||||
$filter_actions .= sprintf(
|
||||
"JSON_CONTAINS(%s.custom_data, '\"%s\"', '\$.actions')",
|
||||
$table,
|
||||
io_safe_output($name_action)
|
||||
);
|
||||
|
||||
$fields_actions[$name_action] = sprintf(
|
||||
"SUM(JSON_CONTAINS(%s.custom_data, '\"%s\"', '\$.actions')) as '%s'",
|
||||
$table,
|
||||
io_safe_output($name_action),
|
||||
io_safe_output($name_action)
|
||||
);
|
||||
|
||||
$first = false;
|
||||
}
|
||||
|
||||
$filter_actions .= ' ) ';
|
||||
} else {
|
||||
foreach ($actions_names as $name_action) {
|
||||
$fields[] = sprintf(
|
||||
"SUM(JSON_CONTAINS(%s.custom_data, '\"%s\"', '\$.actions')) as '%s'",
|
||||
$table,
|
||||
io_safe_output($name_action),
|
||||
io_safe_output($name_action)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($fields_actions) === true
|
||||
&& empty($fields_actions) === false
|
||||
) {
|
||||
foreach ($fields_actions as $name => $field) {
|
||||
$fields[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
$names_search = [];
|
||||
$names_server = [];
|
||||
if (isset($groupsBy['group_by']) === true) {
|
||||
switch ($groupsBy['group_by']) {
|
||||
case 'module':
|
||||
$fields[] = $table.'.id_agentmodule as module';
|
||||
$group_array[] = $table.'.id_agentmodule';
|
||||
$names_search = modules_get_agentmodule_name_array(
|
||||
array_values($filters['modules'])
|
||||
);
|
||||
|
||||
if (is_metaconsole() === true) {
|
||||
$fields[] = $table.'.server_id as server';
|
||||
$group_array[] = $table.'.server_id';
|
||||
$names_server = metaconsole_get_names();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'template':
|
||||
if (is_metaconsole() === false) {
|
||||
$fields[] = 'talert_template_modules.id_alert_template as template';
|
||||
$group_array[] = 'talert_template_modules.id_alert_template';
|
||||
$names_search = alerts_get_templates_name_array(
|
||||
array_values($filters['templates'])
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'agent':
|
||||
$fields[] = $table.'.id_agente as agent';
|
||||
$group_array[] = $table.'.id_agente';
|
||||
$names_search = agents_get_alias_array(
|
||||
array_values($filters['agents'])
|
||||
);
|
||||
|
||||
if (is_metaconsole() === true) {
|
||||
$fields[] = $table.'.server_id as server';
|
||||
$group_array[] = $table.'.server_id';
|
||||
$names_server = metaconsole_get_names();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'group':
|
||||
$fields[] = $table.'.id_grupo as `group`';
|
||||
$group_array[] = $table.'.id_grupo';
|
||||
$names_search = users_get_groups($config['user'], 'AR', false);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Nothing.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($groupsBy['lapse']) === true
|
||||
&& empty($groupsBy['lapse']) === false
|
||||
) {
|
||||
$fields[] = sprintf(
|
||||
'%s.utimestamp AS Period',
|
||||
$table
|
||||
);
|
||||
$group_array[] = 'period';
|
||||
}
|
||||
|
||||
$group_by = '';
|
||||
if (is_array($group_array) === true && empty($group_array) === false) {
|
||||
$group_by = sprintf(' GROUP BY %s', implode(", \n", $group_array));
|
||||
}
|
||||
|
||||
$innerJoin = '';
|
||||
if (is_metaconsole() === false) {
|
||||
$innerJoin = sprintf(
|
||||
'INNER JOIN talert_template_modules
|
||||
ON talert_template_modules.id = %s.id_alert_am',
|
||||
$table
|
||||
);
|
||||
}
|
||||
|
||||
$query = sprintf(
|
||||
'SELECT
|
||||
%s
|
||||
FROM %s
|
||||
%s
|
||||
WHERE custom_data != ""
|
||||
AND %s.event_type="alert_fired"
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
%s',
|
||||
implode(", \n", $fields),
|
||||
$table,
|
||||
$innerJoin,
|
||||
$table,
|
||||
$filter_date,
|
||||
$filter_group,
|
||||
$filter_agents,
|
||||
$filter_modules,
|
||||
$filter_actions,
|
||||
$filter_templates,
|
||||
$group_by
|
||||
);
|
||||
|
||||
$data_query = db_get_all_rows_sql($query);
|
||||
|
||||
if ($data_query === false) {
|
||||
$data_query = [];
|
||||
}
|
||||
|
||||
if (empty($data_query) === false) {
|
||||
$data = array_reduce(
|
||||
$data_query,
|
||||
function ($carry, $item) use ($groupsBy) {
|
||||
$period = (isset($item['Period']) === true) ? (int) $item['Period'] : 0;
|
||||
if (is_metaconsole() === true
|
||||
&& ($groupsBy['group_by'] === 'agent'
|
||||
|| $groupsBy['group_by'] === 'module')
|
||||
) {
|
||||
$grby = $item[$groupsBy['group_by']];
|
||||
$server = $item['server'];
|
||||
unset($item['Period']);
|
||||
unset($item[$groupsBy['group_by']]);
|
||||
unset($item['server']);
|
||||
$carry[$period][$server][$grby] = $item;
|
||||
} else {
|
||||
$grby = $item[$groupsBy['group_by']];
|
||||
unset($item['Period']);
|
||||
unset($item[$groupsBy['group_by']]);
|
||||
$carry[$period][$grby] = $item;
|
||||
}
|
||||
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
$intervals = [];
|
||||
if (isset($groupsBy['lapse']) === true
|
||||
&& empty($groupsBy['lapse']) === false
|
||||
) {
|
||||
$tend = time();
|
||||
$tstart = ($tend - (int) $filters['period']);
|
||||
for ($current_time = $tstart; $current_time < $tend; ($current_time += $groupsBy['lapse'])) {
|
||||
$intervals[] = (int) $current_time;
|
||||
}
|
||||
}
|
||||
|
||||
$first_element = reset($data);
|
||||
$first_element = reset($first_element);
|
||||
if (is_metaconsole() === true
|
||||
&& ($groupsBy['group_by'] === 'agent'
|
||||
|| $groupsBy['group_by'] === 'module')
|
||||
) {
|
||||
$first_element = reset($first_element);
|
||||
}
|
||||
|
||||
$clone = [];
|
||||
foreach ($first_element as $key_clone => $value_clone) {
|
||||
$clone[$key_clone] = 0;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
if (empty($intervals) === true) {
|
||||
foreach ($data as $period => $array_data) {
|
||||
if (is_metaconsole() === true
|
||||
&& ($groupsBy['group_by'] === 'agent'
|
||||
|| $groupsBy['group_by'] === 'module')
|
||||
) {
|
||||
foreach ($names_search as $server => $names) {
|
||||
foreach ($names as $id => $name) {
|
||||
$name = $names_server[$server].' » '.$name;
|
||||
if (isset($array_data[$server][$id]) === true) {
|
||||
$result[$period][$server.'|'.$id] = $array_data[$server][$id];
|
||||
$result[$period][$server.'|'.$id][$groupsBy['group_by']] = $name;
|
||||
} else {
|
||||
if ($only_data === false) {
|
||||
$clone[$groupsBy['group_by']] = $name;
|
||||
$result[$period][$server.'|'.$id] = $clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($names_search as $id => $name) {
|
||||
if (isset($array_data[$id]) === true) {
|
||||
$result[$period][$id] = $array_data[$id];
|
||||
$result[$period][$id][$groupsBy['group_by']] = $name;
|
||||
} else {
|
||||
if ($only_data === false) {
|
||||
$clone[$groupsBy['group_by']] = $name;
|
||||
$result[$period][$id] = $clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$period_lapse = (int) $groupsBy['lapse'];
|
||||
foreach ($intervals as $interval) {
|
||||
$start_interval = $interval;
|
||||
$end_interval = ($interval + $period_lapse);
|
||||
|
||||
if ($only_data === false) {
|
||||
if (is_metaconsole() === true
|
||||
&& ($groupsBy['group_by'] === 'agent'
|
||||
|| $groupsBy['group_by'] === 'module')
|
||||
) {
|
||||
foreach ($names_search as $server => $names) {
|
||||
foreach ($names as $id => $name) {
|
||||
$result_name = $names_server[$server].' » '.$name;
|
||||
$result[$start_interval][$server.'|'.$id] = $clone;
|
||||
$result[$start_interval][$server.'|'.$id][$groupsBy['group_by']] = $result_name;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($names_search as $id => $name) {
|
||||
$result[$start_interval][$id] = $clone;
|
||||
$result[$start_interval][$id][$groupsBy['group_by']] = $name;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($data as $period => $array_data) {
|
||||
if (is_metaconsole() === true
|
||||
&& ($groupsBy['group_by'] === 'agent'
|
||||
|| $groupsBy['group_by'] === 'module')
|
||||
) {
|
||||
foreach ($array_data as $server => $datas) {
|
||||
foreach ($datas as $id_data => $value_data) {
|
||||
$name = $names_server[$server].' » '.$names_search[$server][$id_data];
|
||||
$result[$start_interval][$server.'|'.$id_data] = $clone;
|
||||
$result[$start_interval][$server.'|'.$id_data][$groupsBy['group_by']] = $name;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($array_data as $id_data => $value_data) {
|
||||
$name = $names_search[$id_data];
|
||||
$result[$start_interval][$id_data] = $clone;
|
||||
$result[$start_interval][$id_data][$groupsBy['group_by']] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($data as $period => $array_data) {
|
||||
$period_time = (int) $period;
|
||||
if ($start_interval < $period_time && $period_time <= $end_interval) {
|
||||
if (is_metaconsole() === true
|
||||
&& ($groupsBy['group_by'] === 'agent'
|
||||
|| $groupsBy['group_by'] === 'module')
|
||||
) {
|
||||
foreach ($array_data as $server => $datas) {
|
||||
foreach ($datas as $id_data => $value_data) {
|
||||
foreach ($value_data as $key_data => $v) {
|
||||
if ($key_data !== $groupsBy['group_by']) {
|
||||
if (isset($result[$start_interval][$server.'|'.$id_data][$key_data])) {
|
||||
$result[$start_interval][$server.'|'.$id_data][$key_data] += $v;
|
||||
} else {
|
||||
$result[$start_interval][$server.'|'.$id_data][$key_data] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($array_data as $id_data => $value_data) {
|
||||
foreach ($value_data as $key_data => $v) {
|
||||
if ($key_data !== $groupsBy['group_by']) {
|
||||
if (isset($result[$start_interval][$id_data][$key_data])) {
|
||||
$result[$start_interval][$id_data][$key_data] += $v;
|
||||
} else {
|
||||
$result[$start_interval][$id_data][$key_data] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($data[$period]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result['data'] = $result;
|
||||
|
||||
if ($total === true) {
|
||||
$total_values = [];
|
||||
foreach ($data_query as $key => $array_data) {
|
||||
foreach ($array_data as $key_value => $v) {
|
||||
$total_values[$key_value] = ($total_values[$key_value] + $v);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_metaconsole() === true
|
||||
&& ($groupsBy['group_by'] === 'agent'
|
||||
|| $groupsBy['group_by'] === 'module')
|
||||
) {
|
||||
unset($total_values['server']);
|
||||
}
|
||||
|
||||
unset($total_values['Period']);
|
||||
$result['summary']['total'] = $total_values;
|
||||
$result['summary']['total'][$groupsBy['group_by']] = __('Total');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the templates names of an agent.
|
||||
*
|
||||
* @param array $array_ids Templates ids.
|
||||
*
|
||||
* @return array Id => name.
|
||||
*/
|
||||
function alerts_get_templates_name_array($array_ids)
|
||||
{
|
||||
if (is_array($array_ids) === false || empty($array_ids) === true) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sql = sprintf(
|
||||
'SELECT id, `name`
|
||||
FROM talert_templates
|
||||
WHERE id IN (%s)',
|
||||
implode(',', $array_ids)
|
||||
);
|
||||
|
||||
$result = db_get_all_rows_sql($sql);
|
||||
|
||||
if ($result === false) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
$result = array_reduce(
|
||||
$result,
|
||||
function ($carry, $item) {
|
||||
$carry[$item['id']] = $item['name'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
@ -1377,42 +1377,56 @@ function db_process_sql($sql, $rettype='affected_rows', $dbconnection='', $cache
|
||||
break;
|
||||
}
|
||||
|
||||
if ($rc !== false) {
|
||||
if (enterprise_hook('is_metaconsole') === true
|
||||
&& isset($config['centralized_management']) === true
|
||||
&& (bool) $config['centralized_management'] === true
|
||||
&& $dbconnection === ''
|
||||
) {
|
||||
$errors = null;
|
||||
try {
|
||||
// Synchronize changes to nodes if needed.
|
||||
$sync = new Synchronizer();
|
||||
if ($sync !== null) {
|
||||
if ($sync->queue($sql) === false) {
|
||||
// Launch events per failed query.
|
||||
$errors = $sync->getLatestErrors();
|
||||
if ($errors !== null) {
|
||||
$errors = join(', ', $errors);
|
||||
} else {
|
||||
$errors = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$errors = $e->getMessage();
|
||||
}
|
||||
|
||||
if ($errors !== null) {
|
||||
// TODO: Generate pandora event.
|
||||
error_log($errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
db_sync($dbconnection, $sql, $rc);
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Propagate to nodes.
|
||||
*
|
||||
* @param mixed $dbconnection Dbconnection.
|
||||
* @param mixed $sql Sql.
|
||||
* @param mixed $rc Rc.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function db_sync($dbconnection, $sql, $rc)
|
||||
{
|
||||
global $config;
|
||||
if (enterprise_hook('is_metaconsole') === true
|
||||
&& isset($config['centralized_management']) === true
|
||||
&& (bool) $config['centralized_management'] === true
|
||||
&& $dbconnection === ''
|
||||
) {
|
||||
$errors = null;
|
||||
try {
|
||||
// Synchronize changes to nodes if needed.
|
||||
$sync = new Synchronizer();
|
||||
if ($sync !== null) {
|
||||
if ($sync->queue($sql, $rc) === false) {
|
||||
// Launch events per failed query.
|
||||
$errors = $sync->getLatestErrors();
|
||||
if ($errors !== null) {
|
||||
$errors = join(', ', $errors);
|
||||
} else {
|
||||
$errors = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$errors = $e->getMessage();
|
||||
}
|
||||
|
||||
if ($errors !== null) {
|
||||
// TODO: Generate pandora event.
|
||||
error_log($errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all the rows in a table of the database.
|
||||
*
|
||||
@ -1808,20 +1822,20 @@ function db_process_sql_delete($table, $where, $where_join='AND')
|
||||
function db_process_sql_begin()
|
||||
{
|
||||
global $config;
|
||||
$null = null;
|
||||
|
||||
switch ($config['dbtype']) {
|
||||
case 'mysql':
|
||||
return mysql_db_process_sql_begin();
|
||||
|
||||
break;
|
||||
case 'postgresql':
|
||||
return postgresql_db_process_sql_begin();
|
||||
|
||||
break;
|
||||
case 'oracle':
|
||||
return oracle_db_process_sql_begin();
|
||||
|
||||
break;
|
||||
default:
|
||||
case 'mysql':
|
||||
db_process_sql('SET AUTOCOMMIT = 0', 'affected_rows', '', false, $null, false);
|
||||
db_process_sql('START TRANSACTION', 'affected_rows', '', false, $null, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1832,20 +1846,20 @@ function db_process_sql_begin()
|
||||
function db_process_sql_commit()
|
||||
{
|
||||
global $config;
|
||||
$null = null;
|
||||
|
||||
switch ($config['dbtype']) {
|
||||
case 'mysql':
|
||||
return mysql_db_process_sql_commit();
|
||||
|
||||
break;
|
||||
case 'postgresql':
|
||||
return postgresql_db_process_sql_commit();
|
||||
|
||||
break;
|
||||
case 'oracle':
|
||||
return oracle_db_process_sql_commit();
|
||||
|
||||
break;
|
||||
default:
|
||||
case 'mysql':
|
||||
db_process_sql('COMMIT', 'affected_rows', '', false, $null, false);
|
||||
db_process_sql('SET AUTOCOMMIT = 1', 'affected_rows', '', false, $null, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1856,20 +1870,20 @@ function db_process_sql_commit()
|
||||
function db_process_sql_rollback()
|
||||
{
|
||||
global $config;
|
||||
$null = null;
|
||||
|
||||
switch ($config['dbtype']) {
|
||||
case 'mysql':
|
||||
return mysql_db_process_sql_rollback();
|
||||
|
||||
break;
|
||||
case 'postgresql':
|
||||
return postgresql_db_process_sql_rollback();
|
||||
|
||||
break;
|
||||
case 'oracle':
|
||||
return oracle_db_process_sql_rollback();
|
||||
|
||||
break;
|
||||
default:
|
||||
case 'mysql':
|
||||
db_process_sql('ROLLBACK', 'affected_rows', '', false, $null, false);
|
||||
db_process_sql('SET AUTOCOMMIT = 1', 'affected_rows', '', false, $null, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1889,6 +1903,7 @@ function db_print_database_debug()
|
||||
|
||||
echo '<div class="database_debug_title">'.__('Database debug').'</div>';
|
||||
|
||||
$table = new stdClass();
|
||||
$table->id = 'database_debug';
|
||||
$table->cellpadding = '0';
|
||||
$table->width = '95%';
|
||||
@ -1946,18 +1961,15 @@ function db_get_last_error()
|
||||
global $config;
|
||||
|
||||
switch ($config['dbtype']) {
|
||||
case 'mysql':
|
||||
return mysql_db_get_last_error();
|
||||
|
||||
break;
|
||||
case 'postgresql':
|
||||
return postgresql_db_get_last_error();
|
||||
|
||||
break;
|
||||
case 'oracle':
|
||||
return oracle_db_get_last_error();
|
||||
|
||||
break;
|
||||
case 'mysql':
|
||||
default:
|
||||
return mysql_db_get_last_error();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1975,18 +1987,15 @@ function db_get_type_field_table($table, $field)
|
||||
global $config;
|
||||
|
||||
switch ($config['dbtype']) {
|
||||
case 'mysql':
|
||||
return mysql_db_get_type_field_table($table, $field);
|
||||
|
||||
break;
|
||||
case 'postgresql':
|
||||
return postgresql_db_get_type_field_table($table, $field);
|
||||
|
||||
break;
|
||||
case 'oracle':
|
||||
return oracle_db_get_type_field_table($table, $field);
|
||||
|
||||
break;
|
||||
case 'mysql':
|
||||
default:
|
||||
return mysql_db_get_type_field_table($table, $field);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
// Begin.
|
||||
global $config;
|
||||
|
||||
require_once $config['homedir'].'/include/functions_ui.php';
|
||||
@ -35,7 +37,7 @@ enterprise_include_once('include/functions_metaconsole.php');
|
||||
enterprise_include_once('meta/include/functions_events_meta.php');
|
||||
enterprise_include_once('meta/include/functions_agents_meta.php');
|
||||
enterprise_include_once('meta/include/functions_modules_meta.php');
|
||||
if (is_metaconsole()) {
|
||||
if (is_metaconsole() === true) {
|
||||
$id_source_event = get_parameter('id_source_event');
|
||||
}
|
||||
|
||||
@ -1619,14 +1621,14 @@ function events_get_events($filter=false, $fields=false)
|
||||
*/
|
||||
function events_get_event($id, $fields=false, $meta=false, $history=false)
|
||||
{
|
||||
if (empty($id)) {
|
||||
if (empty($id) === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
global $config;
|
||||
|
||||
if (is_array($fields)) {
|
||||
if (! in_array('id_grupo', $fields)) {
|
||||
if (is_array($fields) === true) {
|
||||
if (in_array('id_grupo', $fields) === false) {
|
||||
$fields[] = 'id_grupo';
|
||||
}
|
||||
}
|
||||
@ -1634,7 +1636,7 @@ function events_get_event($id, $fields=false, $meta=false, $history=false)
|
||||
$table = events_get_events_table($meta, $history);
|
||||
|
||||
$event = db_get_row($table, 'id_evento', $id, $fields);
|
||||
if (! check_acl($config['id_user'], $event['id_grupo'], 'ER')) {
|
||||
if ((bool) check_acl($config['id_user'], $event['id_grupo'], 'ER') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2255,7 +2257,7 @@ function events_comment(
|
||||
// If comments are not stored in json, the format is old.
|
||||
$event_comments_array = json_decode($event_comments[0]['user_comment']);
|
||||
|
||||
if (empty($event_comments_array)) {
|
||||
if (empty($event_comments_array) === true) {
|
||||
$comments_format = 'old';
|
||||
} else {
|
||||
$comments_format = 'new';
|
||||
@ -2268,6 +2270,7 @@ function events_comment(
|
||||
$comment_for_json['action'] = $action;
|
||||
$comment_for_json['id_user'] = $config['id_user'];
|
||||
$comment_for_json['utimestamp'] = time();
|
||||
$comment_for_json['event_id'] = $first_event;
|
||||
|
||||
$event_comments_array[] = $comment_for_json;
|
||||
|
||||
@ -2282,11 +2285,11 @@ function events_comment(
|
||||
break;
|
||||
|
||||
case 'old':
|
||||
// Give old ugly format to comment. TODO: Change this method for
|
||||
// aux table or json.
|
||||
// Give old ugly format to comment.
|
||||
// Change this method for aux table or json.
|
||||
$comment = str_replace(["\r\n", "\r", "\n"], '<br>', $comment);
|
||||
|
||||
if ($comment != '') {
|
||||
if ($comment !== '') {
|
||||
$commentbox = '<div class="comment_box">'.io_safe_input($comment).'</div>';
|
||||
} else {
|
||||
$commentbox = '';
|
||||
@ -5106,11 +5109,13 @@ function events_page_general($event)
|
||||
/**
|
||||
* Generate 'comments' page for event viewer.
|
||||
*
|
||||
* @param array $event Event.
|
||||
* @param array $event Event.
|
||||
* @param boolean $ajax If the query come from AJAX.
|
||||
* @param boolean $grouped If the event must shown comments grouped.
|
||||
*
|
||||
* @return string HTML.
|
||||
*/
|
||||
function events_page_comments($event, $ajax=false)
|
||||
function events_page_comments($event, $ajax=false, $groupedComments=[])
|
||||
{
|
||||
// Comments.
|
||||
global $config;
|
||||
@ -5121,23 +5126,53 @@ function events_page_comments($event, $ajax=false)
|
||||
$table_comments->head = [];
|
||||
$table_comments->class = 'table_modal_alternate';
|
||||
|
||||
$comments = ($event['user_comment'] ?? '');
|
||||
$comments = (empty($groupedComments) === true) ? $event['user_comment'] : $groupedComments;
|
||||
|
||||
if (empty($comments)) {
|
||||
if (empty($comments) === true) {
|
||||
$table_comments->style[0] = 'text-align:center;';
|
||||
$table_comments->colspan[0][0] = 2;
|
||||
$data = [];
|
||||
$data[0] = __('There are no comments');
|
||||
$table_comments->data[] = $data;
|
||||
} else {
|
||||
if (is_array($comments)) {
|
||||
if (is_array($comments) === true) {
|
||||
$comments_array = [];
|
||||
foreach ($comments as $comm) {
|
||||
if (empty($comm)) {
|
||||
if (empty($comm) === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If exists user_comments, come from grouped events and must be handled like this.
|
||||
if (isset($comm['user_comment']) === true) {
|
||||
$comm = $comm['user_comment'];
|
||||
}
|
||||
|
||||
$comments_array[] = io_safe_output(json_decode($comm, true));
|
||||
}
|
||||
|
||||
// Plain comments. Can be improved.
|
||||
$sortedCommentsArray = [];
|
||||
foreach ($comments_array as $comm) {
|
||||
foreach ($comm as $subComm) {
|
||||
$sortedCommentsArray[] = $subComm;
|
||||
}
|
||||
}
|
||||
|
||||
// Sorting the comments by utimestamp (newer is first).
|
||||
usort(
|
||||
$sortedCommentsArray,
|
||||
function ($a, $b) {
|
||||
if ($a['utimestamp'] == $b['utimestamp']) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($a['utimestamp'] > $b['utimestamp']) ? -1 : 1;
|
||||
}
|
||||
);
|
||||
|
||||
// Clean the unsorted comments and return it to the original array.
|
||||
$comments_array = [];
|
||||
$comments_array[] = $sortedCommentsArray;
|
||||
} else {
|
||||
$comments = str_replace(["\n", '
'], '<br>', $comments);
|
||||
// If comments are not stored in json, the format is old.
|
||||
@ -5145,23 +5180,28 @@ function events_page_comments($event, $ajax=false)
|
||||
}
|
||||
|
||||
foreach ($comments_array as $comm) {
|
||||
// Show the comments more recent first.
|
||||
if (is_array($comm)) {
|
||||
$comm = array_reverse($comm);
|
||||
}
|
||||
|
||||
if (empty($comm)) {
|
||||
$comments_format = 'old';
|
||||
} else {
|
||||
$comments_format = 'new';
|
||||
}
|
||||
$comments_format = (empty($comm) === true) ? 'old' : 'new';
|
||||
|
||||
switch ($comments_format) {
|
||||
case 'new':
|
||||
foreach ($comm as $c) {
|
||||
$data[0] = '<b>'.$c['action'].' by '.$c['id_user'].'</b>';
|
||||
$data[0] .= '<br><br><i>'.date($config['date_format'], $c['utimestamp']).'</i>';
|
||||
$eventIdExplanation = (empty($groupedComments) === false) ? sprintf(' (#%d)', $c['event_id']) : '';
|
||||
|
||||
$data[0] = sprintf(
|
||||
'<b>%s %s %s%s</b>',
|
||||
$c['action'],
|
||||
__('by'),
|
||||
$c['id_user'],
|
||||
$eventIdExplanation
|
||||
);
|
||||
|
||||
$data[0] .= sprintf(
|
||||
'<br><br><i>%s</i>',
|
||||
date($config['date_format'], $c['utimestamp'])
|
||||
);
|
||||
|
||||
$data[1] = '<p class="break_word">'.stripslashes(str_replace(['\n', '\r'], '<br/>', $c['comment'])).'</p>';
|
||||
|
||||
$table_comments->data[] = $data;
|
||||
}
|
||||
break;
|
||||
@ -5251,7 +5291,7 @@ function events_page_comments($event, $ajax=false)
|
||||
);
|
||||
}
|
||||
|
||||
if ($ajax) {
|
||||
if ($ajax === true) {
|
||||
return $comments_form.html_print_table($table_comments, true);
|
||||
}
|
||||
|
||||
|
@ -729,7 +729,8 @@ function html_print_select(
|
||||
$required=false,
|
||||
$truncate_size=false,
|
||||
$select2_enable=true,
|
||||
$multiple_select2=false
|
||||
$select2_multiple_enable=false,
|
||||
$select2_multiple_enable_all=false
|
||||
) {
|
||||
$output = "\n";
|
||||
|
||||
@ -791,6 +792,12 @@ function html_print_select(
|
||||
$required = 'required';
|
||||
}
|
||||
|
||||
if ($select2_multiple_enable === true
|
||||
&& $select2_multiple_enable_all === true
|
||||
) {
|
||||
$output .= '<div class="flex-row-center">';
|
||||
}
|
||||
|
||||
$output .= '<select '.$required.' onclick="'.$script.'" id="'.$id.'" name="'.$name.'"'.$attributes.' '.$styleText.'>';
|
||||
|
||||
if ($nothing !== false) {
|
||||
@ -890,6 +897,24 @@ function html_print_select(
|
||||
}
|
||||
|
||||
$output .= '</select>';
|
||||
|
||||
if ($select2_multiple_enable === true
|
||||
&& $select2_multiple_enable_all === true
|
||||
) {
|
||||
$output .= '<div class="margin-left-2 flex-column">';
|
||||
$output .= '<span>'.__('All').'</span>';
|
||||
$output .= html_print_checkbox_switch(
|
||||
$id.'-check-all',
|
||||
1,
|
||||
false,
|
||||
true,
|
||||
$disabled,
|
||||
'checkMultipleAll('.$id.')'
|
||||
);
|
||||
$output .= '</div>';
|
||||
$output .= '</div>';
|
||||
}
|
||||
|
||||
if ($modal && !enterprise_installed()) {
|
||||
$output .= "
|
||||
<div id='".$message."' class='publienterprise publicenterprise_div' title='Community version'><img data-title='".__('Enterprise version not installed')."' class='img_help forced_title' data-use_title_for_force_title='1' src='images/alert_enterprise.png'></div>
|
||||
@ -901,8 +926,7 @@ function html_print_select(
|
||||
$select2 = 'select2_dark.min';
|
||||
}
|
||||
|
||||
// Note that multiple_select2 is introduced as a workaround to overcome the pointless limitation of preventing "multiple" select inputs from using select2 library without affecting the existing calls to this function.
|
||||
if ($multiple === false && $select2_enable === true || $multiple_select2 === true) {
|
||||
if (($multiple === false || $select2_multiple_enable === true) && $select2_enable === true) {
|
||||
if (is_ajax()) {
|
||||
$output .= '<script src="';
|
||||
$output .= ui_get_full_url(
|
||||
@ -944,6 +968,32 @@ function html_print_select(
|
||||
});';
|
||||
}
|
||||
|
||||
if ($select2_multiple_enable === true
|
||||
&& $select2_multiple_enable_all === true
|
||||
) {
|
||||
$output .= '$("#'.$id.'").on("change", function(e) {
|
||||
var checked = false;
|
||||
if(e.target.length !== $("#'.$id.' > option:selected").length) {
|
||||
checked = false;
|
||||
} else {
|
||||
checked = true;
|
||||
}
|
||||
|
||||
$("#checkbox-'.$id.'-check-all").prop("checked", checked);
|
||||
});';
|
||||
|
||||
$output .= '$("#'.$id.'").trigger("change");';
|
||||
|
||||
$output .= 'function checkMultipleAll(id){
|
||||
if ($("#checkbox-"+id.id+"-check-all").is(":checked")) {
|
||||
$("#"+id.id+" > option").prop("selected", "selected");
|
||||
$("#"+id.id).trigger("change");
|
||||
} else {
|
||||
$("#"+id.id).val(null).trigger("change");
|
||||
}
|
||||
}';
|
||||
}
|
||||
|
||||
$output .= '</script>';
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
use PandoraFMS\Enterprise\Metaconsole\Node;
|
||||
|
||||
// Begin.
|
||||
require_once $config['homedir'].'/include/functions_agents.php';
|
||||
require_once $config['homedir'].'/include/functions_users.php';
|
||||
@ -1435,6 +1437,90 @@ function modules_get_agentmodule_name($id_agente_modulo)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the module names of an agent module.
|
||||
*
|
||||
* @param array $array_ids Agents module ids.
|
||||
*
|
||||
* @return array Id => name.
|
||||
*/
|
||||
function modules_get_agentmodule_name_array($array_ids)
|
||||
{
|
||||
if (is_array($array_ids) === false || empty($array_ids) === true) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ((bool) is_metaconsole() === true) {
|
||||
$modules = array_reduce(
|
||||
$array_ids,
|
||||
function ($carry, $item) {
|
||||
$explode = explode('|', $item);
|
||||
|
||||
$carry[$explode[0]][] = $explode[1];
|
||||
return $carry;
|
||||
}
|
||||
);
|
||||
|
||||
$result = [];
|
||||
foreach ($modules as $tserver => $id_modules) {
|
||||
if (metaconsole_connect(null, $tserver) == NOERR) {
|
||||
$result_modules = modules_get_agentmodule_name_array_data(
|
||||
$id_modules
|
||||
);
|
||||
|
||||
$result[$tserver] = $result_modules;
|
||||
metaconsole_restore_db();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$result = modules_get_agentmodule_name_array_data(
|
||||
$array_ids
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Data names.
|
||||
*
|
||||
* @param array $array_ids Ids.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function modules_get_agentmodule_name_array_data($array_ids)
|
||||
{
|
||||
if (is_array($array_ids) === false || empty($array_ids) === true) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sql = sprintf(
|
||||
'SELECT id_agente_modulo as id, nombre as `name`
|
||||
FROM tagente_modulo
|
||||
WHERE id_agente_modulo IN (%s)',
|
||||
implode(',', $array_ids)
|
||||
);
|
||||
|
||||
$result = db_get_all_rows_sql($sql);
|
||||
|
||||
if ($result === false) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
$result = array_reduce(
|
||||
$result,
|
||||
function ($carry, $item) {
|
||||
$carry[$item['id']] = $item['name'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the module descripcion of an agent module.
|
||||
*
|
||||
@ -3469,32 +3555,271 @@ function modules_get_agentmodule_mininterval_no_async($id_agent)
|
||||
}
|
||||
|
||||
|
||||
function get_same_modules($agents, $modules)
|
||||
function get_modules_agents($id_module_group, $id_agents, $selection, $select_mode=true)
|
||||
{
|
||||
$modules_to_report = [];
|
||||
if ($modules != '') {
|
||||
foreach ($modules as $m) {
|
||||
$module_name = modules_get_agentmodule_name($m);
|
||||
foreach ($agents as $a) {
|
||||
$module_in_agent = db_get_value_filter(
|
||||
'id_agente_modulo',
|
||||
'tagente_modulo',
|
||||
[
|
||||
'id_agente' => $a,
|
||||
'nombre' => $module_name,
|
||||
]
|
||||
);
|
||||
if ($module_in_agent) {
|
||||
$modules_to_report[] = $module_in_agent;
|
||||
if ((bool) is_metaconsole() === true) {
|
||||
if ($select_mode === true) {
|
||||
$agents = array_reduce(
|
||||
$id_agents,
|
||||
function ($carry, $item) {
|
||||
$explode = explode('|', $item);
|
||||
|
||||
$carry[$explode[0]][] = $explode[1];
|
||||
return $carry;
|
||||
}
|
||||
);
|
||||
} else {
|
||||
if (count($id_agents) > 0) {
|
||||
$rows = db_get_all_rows_sql(
|
||||
sprintf(
|
||||
'SELECT `id_agente`, `id_tagente`, `id_tmetaconsole_setup`
|
||||
FROM `tmetaconsole_agent`
|
||||
WHERE `id_agente` IN (%s)',
|
||||
implode(',', $id_agents)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$rows = [];
|
||||
}
|
||||
|
||||
$agents = array_reduce(
|
||||
$rows,
|
||||
function ($carry, $item) {
|
||||
if ($carry[$item['id_tmetaconsole_setup']] === null) {
|
||||
$carry[$item['id_tmetaconsole_setup']] = [];
|
||||
}
|
||||
|
||||
$carry[$item['id_tmetaconsole_setup']][] = $item['id_tagente'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
$modules = [];
|
||||
foreach ($agents as $tserver => $id_agents) {
|
||||
if (metaconsole_connect(null, $tserver) == NOERR) {
|
||||
$modules[$tserver] = select_modules_for_agent_group(
|
||||
$id_module_group,
|
||||
$id_agents,
|
||||
$selection,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
metaconsole_restore_db();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$selection) {
|
||||
// Common modules.
|
||||
$final_modules = [];
|
||||
$nodes_consulted = count($modules);
|
||||
|
||||
foreach ($modules as $tserver => $mods) {
|
||||
foreach ($mods as $module) {
|
||||
if ($final_modules[$module['nombre']] === null) {
|
||||
$final_modules[$module['nombre']] = 0;
|
||||
}
|
||||
|
||||
$final_modules[$module['nombre']]++;
|
||||
}
|
||||
}
|
||||
|
||||
$modules = [];
|
||||
foreach ($final_modules as $module_name => $occurrences) {
|
||||
if ($occurrences === $nodes_consulted) {
|
||||
// Module already present in ALL nodes.
|
||||
$modules[] = [
|
||||
'id_agente_modulo' => $module_name,
|
||||
'nombre' => $module_name,
|
||||
];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// All modules.
|
||||
$return = [];
|
||||
$nodes = [];
|
||||
foreach ($agents as $tserver => $id_agents) {
|
||||
try {
|
||||
$nodes[$tserver] = new Node($tserver);
|
||||
} catch (Exception $e) {
|
||||
hd($e);
|
||||
}
|
||||
|
||||
$return = array_reduce(
|
||||
$modules[$tserver],
|
||||
function ($carry, $item) use ($tserver, $nodes) {
|
||||
$t = [];
|
||||
foreach ($item as $k => $v) {
|
||||
$t[$k] = $v;
|
||||
}
|
||||
|
||||
$t['id_node'] = $tserver;
|
||||
if ($nodes[$tserver] !== null) {
|
||||
$t['nombre'] = io_safe_output(
|
||||
$nodes[$tserver]->server_name().' » '.$t['nombre']
|
||||
);
|
||||
}
|
||||
|
||||
$carry[] = $t;
|
||||
return $carry;
|
||||
},
|
||||
$return
|
||||
);
|
||||
}
|
||||
|
||||
$modules = $return;
|
||||
}
|
||||
|
||||
$modules = array_reduce(
|
||||
$modules,
|
||||
function ($carry, $item) {
|
||||
$carry[$item['id_node'].'|'.$item['id_agente_modulo']] = $item['nombre'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
} else {
|
||||
$modules = select_modules_for_agent_group(
|
||||
$id_module_group,
|
||||
$id_agents,
|
||||
$selection,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
$modules_to_report = array_merge($modules_to_report, $modules);
|
||||
return $modules;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List all modules in agents selection.
|
||||
*
|
||||
* @param array $agents Agents ids array.
|
||||
* @param array $modules Modules ids array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_same_modules($agents, $modules)
|
||||
{
|
||||
if (is_array($agents) === false || empty($agents) === true) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$name_modules = modules_get_agentmodule_name_array_data(
|
||||
array_values($modules)
|
||||
);
|
||||
|
||||
$sql = sprintf(
|
||||
'SELECT id_agente_modulo as id,
|
||||
nombre as `name`
|
||||
FROM tagente_modulo
|
||||
WHERE id_agente IN (%s)',
|
||||
implode(',', array_values($agents))
|
||||
);
|
||||
|
||||
$all = db_get_all_rows_sql($sql);
|
||||
|
||||
if ($all === false) {
|
||||
$all = [];
|
||||
}
|
||||
|
||||
$all = array_reduce(
|
||||
$all,
|
||||
function ($carry, $item) use ($name_modules) {
|
||||
if (array_search($item['name'], $name_modules)) {
|
||||
$carry[$item['id']] = $item['id'];
|
||||
}
|
||||
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
$modules_to_report = array_merge($all, $modules);
|
||||
$modules_to_report = array_unique($modules_to_report);
|
||||
|
||||
return $modules_to_report;
|
||||
return $all;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List all modules in agents selection to metaconsole or node.
|
||||
*
|
||||
* @param array $agents Agents ids array.
|
||||
* @param array $modules Modules ids array.
|
||||
*
|
||||
* @return array List modules [server|id_module, ...].
|
||||
*/
|
||||
function get_same_modules_all($agents, $modules, $select_mode=true)
|
||||
{
|
||||
if (is_array($agents) === false || empty($agents) === true) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (is_metaconsole() === true) {
|
||||
$modules = array_reduce(
|
||||
$modules,
|
||||
function ($carry, $item) {
|
||||
$explode = explode('|', $item);
|
||||
|
||||
$carry[$explode[0]][] = $explode[1];
|
||||
return $carry;
|
||||
}
|
||||
);
|
||||
|
||||
if ($select_mode === true) {
|
||||
$agents = array_reduce(
|
||||
$agents,
|
||||
function ($carry, $item) {
|
||||
$explode = explode('|', $item);
|
||||
|
||||
$carry[$explode[0]][] = $explode[1];
|
||||
return $carry;
|
||||
}
|
||||
);
|
||||
} else {
|
||||
$rows = db_get_all_rows_sql(
|
||||
sprintf(
|
||||
'SELECT `id_agente`, `id_tagente`, `id_tmetaconsole_setup`
|
||||
FROM `tmetaconsole_agent`
|
||||
WHERE `id_agente` IN (%s)',
|
||||
implode(',', $agents)
|
||||
)
|
||||
);
|
||||
|
||||
$agents = array_reduce(
|
||||
$rows,
|
||||
function ($carry, $item) {
|
||||
if ($carry[$item['id_tmetaconsole_setup']] === null) {
|
||||
$carry[$item['id_tmetaconsole_setup']] = [];
|
||||
}
|
||||
|
||||
$carry[$item['id_tmetaconsole_setup']][] = $item['id_tagente'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($agents as $tserver => $id_agents) {
|
||||
if (metaconsole_connect(null, $tserver) == NOERR) {
|
||||
$same_modules = get_same_modules($id_agents, $modules[$tserver]);
|
||||
foreach ($same_modules as $id_module) {
|
||||
$result[] = $tserver.'|'.$id_module;
|
||||
}
|
||||
|
||||
metaconsole_restore_db();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$result = get_same_modules($agents, $modules);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -734,6 +734,13 @@ function reporting_make_reporting_data(
|
||||
);
|
||||
break;
|
||||
|
||||
case 'alert_report_actions':
|
||||
$report['contents'][] = reporting_alert_report_actions(
|
||||
$report,
|
||||
$content
|
||||
);
|
||||
break;
|
||||
|
||||
case 'agents_inventory':
|
||||
$report['contents'][] = reporting_agents_inventory(
|
||||
$report,
|
||||
@ -2666,15 +2673,119 @@ function reporting_inventory($report, $content, $type)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build data for report alert actions.
|
||||
*
|
||||
* @param array $report Report info.
|
||||
* @param array $content Content.
|
||||
*
|
||||
* @return array Result data.
|
||||
*/
|
||||
function reporting_alert_report_actions($report, $content)
|
||||
{
|
||||
$return = [];
|
||||
|
||||
$return['type'] = 'alert_report_actions';
|
||||
if (empty($content['name']) === true) {
|
||||
$content['name'] = __('Alert actions');
|
||||
}
|
||||
|
||||
$return['title'] = io_safe_output($content['name']);
|
||||
$return['landscape'] = $content['landscape'];
|
||||
$return['pagebreak'] = $content['pagebreak'];
|
||||
|
||||
$return['subtitle'] = __('Actions');
|
||||
$return['description'] = io_safe_output($content['description']);
|
||||
$return['date'] = reporting_get_date_text($report, $content);
|
||||
|
||||
$return['data'] = [];
|
||||
|
||||
$es = json_decode($content['external_source'], true);
|
||||
if (isset($report['id_template']) === true
|
||||
&& empty($report['id_template']) === false
|
||||
) {
|
||||
if (is_metaconsole() === true) {
|
||||
$server_id = metaconsole_get_id_server($content['server_name']);
|
||||
$modules = [$server_id.'|'.$content['id_agent_module']];
|
||||
$agents = [$server_id.'|'.$content['id_agent']];
|
||||
} else {
|
||||
$modules = [$content['id_agent_module']];
|
||||
$agents = [$content['id_agent']];
|
||||
}
|
||||
} else {
|
||||
$modules = json_decode(
|
||||
io_safe_output(base64_decode($es['module'])),
|
||||
true
|
||||
);
|
||||
$agents = json_decode(
|
||||
io_safe_output(base64_decode($es['id_agents'])),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
$period = $content['period'];
|
||||
$id_group = $content['id_group'];
|
||||
$templates = $es['templates'];
|
||||
$actions = $es['actions'];
|
||||
$show_summary = $es['show_summary'];
|
||||
$group_by = $es['group_by'];
|
||||
$lapse = $content['lapse'];
|
||||
$only_data = $es['only_data'];
|
||||
|
||||
$filters = [
|
||||
'group' => $id_group,
|
||||
'agents' => $agents,
|
||||
'modules' => $modules,
|
||||
'templates' => $templates,
|
||||
'actions' => $actions,
|
||||
'period' => $period,
|
||||
'show_summary' => (bool) $show_summary,
|
||||
'only_data' => (bool) $only_data,
|
||||
];
|
||||
|
||||
$groupsBy = [
|
||||
'group_by' => $group_by,
|
||||
'lapse' => $lapse,
|
||||
];
|
||||
|
||||
$return['filters'] = $filters;
|
||||
$return['groupsBy'] = $groupsBy;
|
||||
|
||||
$return['data'] = alerts_get_alert_fired($filters, $groupsBy);
|
||||
|
||||
return reporting_check_structure_content($return);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Data report agent/module.
|
||||
*
|
||||
* @param array $report Report info.
|
||||
* @param array $content Content info.
|
||||
*
|
||||
* @return array Structure Content.
|
||||
*/
|
||||
function reporting_agent_module($report, $content)
|
||||
{
|
||||
global $config;
|
||||
$agents_and_modules = json_decode($content['external_source'], true);
|
||||
$agents = [];
|
||||
$agents = $agents_and_modules['id_agents'];
|
||||
$modules = $agents_and_modules['module'];
|
||||
$id_group = $content['id_group'];
|
||||
$id_module_group = $content['id_module_group'];
|
||||
$external_source = json_decode(
|
||||
$content['external_source'],
|
||||
true
|
||||
);
|
||||
|
||||
$agents = json_decode(
|
||||
io_safe_output(
|
||||
base64_decode($external_source['id_agents'])
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$modules = json_decode(
|
||||
io_safe_output(
|
||||
base64_decode($external_source['module'])
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$return['type'] = 'agent_module';
|
||||
|
||||
@ -2708,7 +2819,9 @@ function reporting_agent_module($report, $content)
|
||||
$cont = 0;
|
||||
|
||||
foreach ($modules as $modul_id) {
|
||||
$modules_by_name[$cont]['name'] = io_safe_output(modules_get_agentmodule_name($modul_id));
|
||||
$modules_by_name[$cont]['name'] = io_safe_output(
|
||||
modules_get_agentmodule_name($modul_id)
|
||||
);
|
||||
$modules_by_name[$cont]['id'] = $modul_id;
|
||||
$cont++;
|
||||
}
|
||||
|
@ -377,6 +377,10 @@ function reporting_html_print_report($report, $mini=false, $report_info=1)
|
||||
reporting_html_agent_module($table, $item);
|
||||
break;
|
||||
|
||||
case 'alert_report_actions':
|
||||
reporting_html_alert_report_actions($table, $item);
|
||||
break;
|
||||
|
||||
case 'agents_inventory':
|
||||
reporting_html_agents_inventory($table, $item);
|
||||
break;
|
||||
@ -2733,6 +2737,101 @@ function reporting_html_group_configuration($table, $item, $pdf=0)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Html output report alert actions
|
||||
*
|
||||
* @param object $table Table.
|
||||
* @param array $item Data for draw report.
|
||||
* @param integer $pdf PDF output.
|
||||
*
|
||||
* @return string Html output.
|
||||
*/
|
||||
function reporting_html_alert_report_actions($table, $item, $pdf=0)
|
||||
{
|
||||
$data = $item['data'];
|
||||
$groupsBy = $item['groupsBy'];
|
||||
|
||||
$output = '';
|
||||
if (isset($data['data']) === true
|
||||
&& empty($data['data']) === false
|
||||
) {
|
||||
foreach ($data['data'] as $period => $data_array) {
|
||||
if (empty($period) === false) {
|
||||
$output .= '<h1 class="h1-report-alert-actions">';
|
||||
$output .= __('From').' ';
|
||||
$output .= date(
|
||||
'd-m-Y H:i:s',
|
||||
$period
|
||||
);
|
||||
$output .= ' '.__('to').' ';
|
||||
$output .= date('d-m-Y H:i:s', ($period + (int) $groupsBy['lapse']));
|
||||
$output .= '</h1>';
|
||||
}
|
||||
|
||||
$output .= get_alert_table($data_array);
|
||||
}
|
||||
|
||||
if (isset($data['summary']) === true
|
||||
&& empty($data['summary']) === false
|
||||
) {
|
||||
$output .= '<h1 class="h1-report-alert-actions">';
|
||||
$output .= __('Total summary');
|
||||
$output .= '</h1>';
|
||||
|
||||
$output .= get_alert_table($data['summary']);
|
||||
}
|
||||
} else {
|
||||
$output .= ui_print_empty_data(
|
||||
__('No alerts fired'),
|
||||
'',
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if ($pdf === 0) {
|
||||
$table->colspan['alert_report_action']['cell'] = 3;
|
||||
$table->cellstyle['alert_report_action']['cell'] = 'text-align: center;';
|
||||
$table->data['alert_report_action']['cell'] = $output;
|
||||
} else {
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw alert action table.
|
||||
*
|
||||
* @param array $data Data.
|
||||
*
|
||||
* @return string Html output.
|
||||
*/
|
||||
function get_alert_table($data)
|
||||
{
|
||||
$table = new StdCLass();
|
||||
$table->width = '100%';
|
||||
$table->data = [];
|
||||
$table->head = [];
|
||||
$table->headstyle = [];
|
||||
$table->cellstyle = [];
|
||||
$table->headstyle[0] = 'text-align:left;';
|
||||
|
||||
$head = reset($data);
|
||||
foreach (array_reverse(array_keys($head)) as $name) {
|
||||
$table->head[] = ucfirst($name);
|
||||
}
|
||||
|
||||
foreach ($data as $key => $params) {
|
||||
$table->cellstyle[$key][0] = 'text-align:left;';
|
||||
foreach (array_reverse($params) as $name => $value) {
|
||||
$table->data[$key][] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return html_print_table($table, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This type of report element will generate the interface graphs
|
||||
* of all those devices that belong to the selected group.
|
||||
|
@ -834,6 +834,7 @@ function reports_get_report_types($template=false, $not_editor=false)
|
||||
'optgroup' => __('Alerts'),
|
||||
'name' => __('Agent alert report '),
|
||||
];
|
||||
|
||||
if (!$template) {
|
||||
$types['alert_report_group'] = [
|
||||
'optgroup' => __('Alerts'),
|
||||
@ -841,6 +842,11 @@ function reports_get_report_types($template=false, $not_editor=false)
|
||||
];
|
||||
}
|
||||
|
||||
$types['alert_report_actions'] = [
|
||||
'optgroup' => __('Alerts'),
|
||||
'name' => __('Actions alert report '),
|
||||
];
|
||||
|
||||
$types['event_report_module'] = [
|
||||
'optgroup' => __('Events'),
|
||||
'name' => __('Module event report'),
|
||||
|
@ -329,7 +329,7 @@ function ui_print_message($message, $class='', $attributes='', $return=false, $t
|
||||
if (!$no_close_bool) {
|
||||
// Use the no_meta parameter because this image is only in
|
||||
// the base console.
|
||||
$output .= '<a href="javascript: close_info_box(\''.$id.'\')">'.html_print_image('images/blade.png', true, false, false, true).'</a>';
|
||||
$output .= '<a href="javascript: close_info_box(\''.$id.'\')">'.html_print_image('images/blade.png', true, false, false, false).'</a>';
|
||||
}
|
||||
|
||||
$output .= '</td>
|
||||
@ -3460,6 +3460,11 @@ function ui_print_datatable(array $parameters)
|
||||
}
|
||||
}
|
||||
|
||||
$export_columns = '';
|
||||
if ($parameters['csv_exclude_latest'] === true) {
|
||||
$export_columns = ',columns: \'th:not(:last-child)\'';
|
||||
}
|
||||
|
||||
$js .= '
|
||||
if (dt_'.$table_id.'.page.info().pages > 1) {
|
||||
$("#'.$table_id.'_wrapper > .dataTables_paginate.paging_simple_numbers").show()
|
||||
@ -3490,8 +3495,7 @@ function ui_print_datatable(array $parameters)
|
||||
order : "current",
|
||||
page : "All",
|
||||
search : "applied"
|
||||
},
|
||||
columns: [1,'.$columns.']
|
||||
}'.$export_columns.'
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -576,7 +576,6 @@ function event_comment(current_event) {
|
||||
return;
|
||||
}
|
||||
|
||||
var event_id = event.id_evento;
|
||||
var comment = $("#textarea_comment").val();
|
||||
var meta = 0;
|
||||
if ($("#hidden-meta").val() != undefined) {
|
||||
@ -596,7 +595,11 @@ function event_comment(current_event) {
|
||||
var params = [];
|
||||
params.push("page=include/ajax/events");
|
||||
params.push("add_comment=1");
|
||||
params.push("event_id=" + event_id);
|
||||
if (event.event_rep > 0) {
|
||||
params.push("event_id=" + event.max_id_evento);
|
||||
} else {
|
||||
params.push("event_id=" + event.id_evento);
|
||||
}
|
||||
params.push("comment=" + comment);
|
||||
params.push("meta=" + meta);
|
||||
params.push("history=" + history);
|
||||
|
@ -43,6 +43,13 @@ abstract class Entity
|
||||
*/
|
||||
protected $existsInDB;
|
||||
|
||||
/**
|
||||
* Fields to identify register.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $primaryKeys;
|
||||
|
||||
/**
|
||||
* Entity fields (from table).
|
||||
*
|
||||
@ -152,6 +159,8 @@ abstract class Entity
|
||||
|
||||
if (is_array($filters) === true) {
|
||||
// New one.
|
||||
$this->primaryKeys = array_keys($filters);
|
||||
|
||||
$data = \db_get_row_filter(
|
||||
$this->table,
|
||||
$filters,
|
||||
@ -318,8 +327,94 @@ abstract class Entity
|
||||
* Saves current object definition to database.
|
||||
*
|
||||
* @return boolean Success or not.
|
||||
* @throws \Exception On error.
|
||||
*/
|
||||
public abstract function save();
|
||||
public function save()
|
||||
{
|
||||
$updates = $this->fields;
|
||||
// Clean null fields.
|
||||
foreach ($updates as $k => $v) {
|
||||
if ($v === null) {
|
||||
unset($updates[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->existsInDB === true) {
|
||||
// Update.
|
||||
$where = [];
|
||||
|
||||
foreach ($this->primaryKeys as $key) {
|
||||
$where[$key] = $this->fields[$key];
|
||||
}
|
||||
|
||||
if (empty($where) === true) {
|
||||
throw new \Exception(
|
||||
__METHOD__.' error: Cannot identify object'
|
||||
);
|
||||
}
|
||||
|
||||
$rs = \db_process_sql_update(
|
||||
$this->table,
|
||||
$updates,
|
||||
$where
|
||||
);
|
||||
|
||||
if ($rs === false) {
|
||||
global $config;
|
||||
throw new \Exception(
|
||||
__METHOD__.' error: '.$config['dbconnection']->error
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// New register.
|
||||
$rs = \db_process_sql_insert(
|
||||
$this->table,
|
||||
$updates
|
||||
);
|
||||
|
||||
if ($rs === false) {
|
||||
global $config;
|
||||
|
||||
throw new \Exception(
|
||||
__METHOD__.' error: '.$config['dbconnection']->error
|
||||
);
|
||||
}
|
||||
|
||||
$this->existsInDB = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove this entity.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception If no primary keys are defined.
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ($this->existsInDB === true) {
|
||||
$where = [];
|
||||
|
||||
foreach ($this->primaryKeys as $key) {
|
||||
$where[$key] = $this->fields[$key];
|
||||
}
|
||||
|
||||
if (empty($where) === true) {
|
||||
throw new \Exception(
|
||||
__METHOD__.' error: Cannot identify object on deletion'
|
||||
);
|
||||
}
|
||||
|
||||
\db_process_sql_delete(
|
||||
$this->table,
|
||||
$where
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -8392,3 +8392,41 @@ div.stat-win-spinner img {
|
||||
#license_error_msg_dialog {
|
||||
min-height: 350px !important;
|
||||
}
|
||||
|
||||
.select2-container--default
|
||||
.select2-selection--multiple
|
||||
.select2-selection__rendered {
|
||||
padding: 5px 10px 10px !important;
|
||||
max-height: 120px;
|
||||
overflow: auto !important;
|
||||
}
|
||||
|
||||
.select2-container--default
|
||||
.select2-selection--multiple
|
||||
.select2-selection__choice {
|
||||
background-color: #82b92e !important;
|
||||
border: 1px solid #82b92e !important;
|
||||
padding: 0.3em 0.6em !important;
|
||||
color: #fff;
|
||||
font-size: 1em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.select2-container--default
|
||||
.select2-selection--multiple
|
||||
.select2-selection__choice__remove {
|
||||
color: #fff !important;
|
||||
font-size: 1.2em;
|
||||
margin-right: 5px !important;
|
||||
}
|
||||
|
||||
.h1-report-alert-actions {
|
||||
text-transform: none;
|
||||
text-align: left;
|
||||
margin: 5px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
@ -129,7 +129,7 @@
|
||||
<div style='height: 10px'>
|
||||
<?php
|
||||
$version = '7.0NG.758.1';
|
||||
$build = '211207';
|
||||
$build = '211214';
|
||||
$banner = "v$version Build $build";
|
||||
|
||||
error_reporting(0);
|
||||
|
@ -192,126 +192,25 @@ if (is_ajax()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($get_modules_group_json) {
|
||||
if ($get_modules_group_json === true) {
|
||||
$id_group = (int) get_parameter('id_module_group', 0);
|
||||
$id_agents = get_parameter('id_agents', null);
|
||||
$selection = get_parameter('selection');
|
||||
$select_mode = (bool) get_parameter('select_mode', 0);
|
||||
|
||||
if ($id_agents === null) {
|
||||
echo '[]';
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bool) is_metaconsole() === true) {
|
||||
if (count($id_agents) > 0) {
|
||||
$rows = db_get_all_rows_sql(
|
||||
sprintf(
|
||||
'SELECT `id_agente`, `id_tagente`, `id_tmetaconsole_setup`
|
||||
FROM `tmetaconsole_agent`
|
||||
WHERE `id_agente` IN (%s)',
|
||||
implode(',', $id_agents)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$rows = [];
|
||||
}
|
||||
|
||||
$agents = array_reduce(
|
||||
$rows,
|
||||
function ($carry, $item) {
|
||||
if ($carry[$item['id_tmetaconsole_setup']] === null) {
|
||||
$carry[$item['id_tmetaconsole_setup']] = [];
|
||||
}
|
||||
|
||||
$carry[$item['id_tmetaconsole_setup']][] = $item['id_tagente'];
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
$modules = [];
|
||||
|
||||
foreach ($agents as $tserver => $id_agents) {
|
||||
if (metaconsole_connect(null, $tserver) == NOERR) {
|
||||
$modules[$tserver] = select_modules_for_agent_group(
|
||||
$id_group,
|
||||
$id_agents,
|
||||
$selection,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
metaconsole_restore_db();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!$selection) {
|
||||
// Common modules.
|
||||
$final_modules = [];
|
||||
$nodes_consulted = count($modules);
|
||||
|
||||
foreach ($modules as $tserver => $mods) {
|
||||
foreach ($mods as $module) {
|
||||
if ($final_modules[$module['nombre']] === null) {
|
||||
$final_modules[$module['nombre']] = 0;
|
||||
}
|
||||
|
||||
$final_modules[$module['nombre']]++;
|
||||
}
|
||||
}
|
||||
|
||||
$modules = [];
|
||||
foreach ($final_modules as $module_name => $occurrences) {
|
||||
if ($occurrences === $nodes_consulted) {
|
||||
// Module already present in ALL nodes.
|
||||
$modules[] = [
|
||||
'id_agente_modulo' => $module_name,
|
||||
'nombre' => $module_name,
|
||||
];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// All modules.
|
||||
$return = [];
|
||||
$nodes = [];
|
||||
foreach ($agents as $tserver => $id_agents) {
|
||||
try {
|
||||
$nodes[$tserver] = new Node($tserver);
|
||||
} catch (Exception $e) {
|
||||
hd($e);
|
||||
}
|
||||
|
||||
$return = array_reduce(
|
||||
$modules[$tserver],
|
||||
function ($carry, $item) use ($tserver, $nodes) {
|
||||
$t = [];
|
||||
foreach ($item as $k => $v) {
|
||||
$t[$k] = $v;
|
||||
}
|
||||
|
||||
$t['id_node'] = $tserver;
|
||||
if ($nodes[$tserver] !== null) {
|
||||
$t['nombre'] = io_safe_output(
|
||||
$nodes[$tserver]->server_name().' » '.$t['nombre']
|
||||
);
|
||||
}
|
||||
|
||||
$carry[] = $t;
|
||||
return $carry;
|
||||
},
|
||||
$return
|
||||
);
|
||||
}
|
||||
|
||||
$modules = $return;
|
||||
}
|
||||
|
||||
echo json_encode($modules);
|
||||
} else {
|
||||
select_modules_for_agent_group($id_group, $id_agents, $selection);
|
||||
}
|
||||
$modules = get_modules_agents(
|
||||
$id_group,
|
||||
$id_agents,
|
||||
$selection,
|
||||
$select_mode
|
||||
);
|
||||
echo json_encode($modules);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($filter_modules_group_json) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
%define name pandorafms_console
|
||||
%define version 7.0NG.758.1
|
||||
%define release 211207
|
||||
%define release 211214
|
||||
|
||||
# User and Group under which Apache is running
|
||||
%define httpd_name httpd
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
%define name pandorafms_console
|
||||
%define version 7.0NG.758.1
|
||||
%define release 211207
|
||||
%define release 211214
|
||||
|
||||
# User and Group under which Apache is running
|
||||
%define httpd_name httpd
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
%define name pandorafms_console
|
||||
%define version 7.0NG.758.1
|
||||
%define release 211207
|
||||
%define release 211214
|
||||
%define httpd_name httpd
|
||||
# User and Group under which Apache is running
|
||||
%define httpd_name apache2
|
||||
|
@ -3959,6 +3959,18 @@ CREATE TABLE IF NOT EXISTS `tipam_network_location` (
|
||||
UNIQUE (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Table `tipam_sites`
|
||||
-- ----------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `tipam_sites` (
|
||||
`id` serial,
|
||||
`name` varchar(100) UNIQUE NOT NULL default '',
|
||||
`description` text,
|
||||
`parent` bigint unsigned null,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`parent`) REFERENCES `tipam_sites`(`id`) ON UPDATE CASCADE ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------------------------------------------------
|
||||
-- Table `tipam_network`
|
||||
-- ----------------------------------------------------------------------
|
||||
@ -3974,9 +3986,13 @@ CREATE TABLE IF NOT EXISTS `tipam_network` (
|
||||
`id_group` mediumint(8) unsigned NULL default 0,
|
||||
`lightweight_mode` tinyint(2) default 0,
|
||||
`users_operator` text,
|
||||
`id_site` bigint unsigned,
|
||||
`vrf` int(10) unsigned,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`id_recon_task`) REFERENCES trecon_task(`id_rt`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`location`) REFERENCES `tipam_network_location`(`id`) ON DELETE CASCADE
|
||||
FOREIGN KEY (`location`) REFERENCES `tipam_network_location`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`id_site`) REFERENCES `tipam_sites`(`id`) ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
FOREIGN KEY (`vrf`) REFERENCES `tagente`(`id_agente`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------------------------------------------------
|
||||
@ -4043,7 +4059,9 @@ CREATE TABLE IF NOT EXISTS `tipam_supernet` (
|
||||
`address` varchar(250) NOT NULL,
|
||||
`mask` varchar(250) NOT NULL,
|
||||
`subneting_mask` varchar(250) default '',
|
||||
PRIMARY KEY (`id`)
|
||||
`id_site` bigint unsigned,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`id_site`) REFERENCES `tipam_sites`(`id`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------------------------------------------------
|
||||
@ -4069,6 +4087,7 @@ CREATE TABLE IF NOT EXISTS `tsync_queue` (
|
||||
`operation` text,
|
||||
`table` text,
|
||||
`error` MEDIUMTEXT,
|
||||
`result` TEXT,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
package: pandorafms-server
|
||||
Version: 7.0NG.758.1-211207
|
||||
Version: 7.0NG.758.1-211214
|
||||
Architecture: all
|
||||
Priority: optional
|
||||
Section: admin
|
||||
|
@ -14,7 +14,7 @@
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
pandora_version="7.0NG.758.1-211207"
|
||||
pandora_version="7.0NG.758.1-211214"
|
||||
|
||||
package_cpan=0
|
||||
package_pandora=1
|
||||
|
@ -46,7 +46,7 @@ our @EXPORT = qw(
|
||||
|
||||
# version: Defines actual version of Pandora Server for this module only
|
||||
my $pandora_version = "7.0NG.758.1";
|
||||
my $pandora_build = "211207";
|
||||
my $pandora_build = "211214";
|
||||
our $VERSION = $pandora_version." ".$pandora_build;
|
||||
|
||||
# Setup hash
|
||||
|
@ -34,7 +34,7 @@ our @ISA = qw(Exporter);
|
||||
|
||||
# version: Defines actual version of Pandora Server for this module only
|
||||
my $pandora_version = "7.0NG.758.1";
|
||||
my $pandora_build = "211207";
|
||||
my $pandora_build = "211214";
|
||||
our $VERSION = $pandora_version." ".$pandora_build;
|
||||
|
||||
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
|
||||
|
@ -26,7 +26,7 @@ use Thread::Semaphore;
|
||||
|
||||
use IO::Socket::INET;
|
||||
use Net::Ping;
|
||||
use POSIX qw(strftime);
|
||||
use POSIX qw(floor strftime);
|
||||
|
||||
# Default lib dir for RPM and DEB packages
|
||||
use lib '/usr/lib/perl5';
|
||||
@ -35,6 +35,7 @@ use PandoraFMS::Tools;
|
||||
use PandoraFMS::DB;
|
||||
use PandoraFMS::Core;
|
||||
use PandoraFMS::ProducerConsumerServer;
|
||||
use PandoraFMS::Statistics::Regression;
|
||||
|
||||
#For debug
|
||||
#use Data::Dumper;
|
||||
@ -224,134 +225,136 @@ sub exec_prediction_module ($$$$) {
|
||||
return;
|
||||
}
|
||||
|
||||
# Get a full hash for target agent_module record reference ($target_module)
|
||||
my $target_module = get_db_single_row ($dbh, 'SELECT * FROM tagente_modulo WHERE id_agente_modulo = ?', $agent_module->{'custom_integer_1'});
|
||||
return unless defined $target_module;
|
||||
|
||||
# Prediction mode explanation
|
||||
#
|
||||
# 0 is for target type of generic_proc. It compares latest data with current data. Needs to get
|
||||
# data on a "middle" interval, so if interval is 300, get data to compare with 150 before
|
||||
# and 150 in the future. If current data is ABOVE or BELOW average +- typical_deviation
|
||||
# this is a BAD value (0), if not is ok (1) and written in target module as is.
|
||||
# more interval configured for this module, more "margin" has to compare data.
|
||||
#
|
||||
# 1 is for target type of generic_data. It get's data in the future, using the interval given in
|
||||
# module. It gets average from current timestamp to INTERVAL in the future and gets average
|
||||
# value. Typical deviation is not used here.
|
||||
|
||||
# 0 proc, 1 data
|
||||
my $prediction_mode = ($agent_module->{'id_tipo_modulo'} == 2) ? 0 : 1;
|
||||
|
||||
# Initialize another global sub variables.
|
||||
my $module_data = 0; # 0 data for default
|
||||
|
||||
# Get current timestamp
|
||||
my $utimestamp = time ();
|
||||
my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime($utimestamp));
|
||||
|
||||
# Get different data from each week one month ago (4 values)
|
||||
# $agent_module->{'module_interval'} uses a margin of interval to get average data from the past
|
||||
my @week_data;
|
||||
my @week_utimestamp;
|
||||
|
||||
for (my $i=0; $i<4; $i++) {
|
||||
$week_utimestamp[$i] = $utimestamp - (84600*7*($i+1));
|
||||
# Adjust for proc prediction
|
||||
if ($prediction_mode == 0) {
|
||||
$week_utimestamp[$i] = $week_utimestamp[$i] - ($agent_module->{'module_interval'} / 2);
|
||||
}
|
||||
# Trend module.
|
||||
if ($agent_module->{'prediction_module'} == 8) {
|
||||
logger ($pa_config, "Executing trend module " . $agent_module->{'nombre'}, 10);
|
||||
enterprise_hook ('exec_trend_module', [$pa_config, $agent_module, $server_id, $dbh]);
|
||||
return;
|
||||
}
|
||||
|
||||
# Let's calculate statistical average using past data
|
||||
# n = total of real data values
|
||||
my ($n, $average, $temp1) = (0, 0, 0);
|
||||
for (my $i=0; $i < 4; $i++) {
|
||||
my ($first_data, $last_data, $average_interval);
|
||||
my $sum_data = 0;
|
||||
|
||||
$temp1 = $week_utimestamp[$i] + $agent_module->{'module_interval'};
|
||||
# Get data for week $i in the past
|
||||
|
||||
$average_interval = get_db_value ($dbh, 'SELECT AVG(datos)
|
||||
FROM tagente_datos
|
||||
WHERE id_agente_modulo = ?
|
||||
AND utimestamp > ?
|
||||
AND utimestamp < ?', $target_module->{'id_agente_modulo'}, $week_utimestamp[$i], $temp1);
|
||||
|
||||
# Need to get data outside interval because no data.
|
||||
if (!(defined($average_interval)) || ($average_interval == 0)) {
|
||||
$last_data = get_db_value ($dbh, 'SELECT datos
|
||||
FROM tagente_datos
|
||||
WHERE id_agente_modulo = ?
|
||||
AND utimestamp > ?
|
||||
LIMIT 1', $target_module->{'id_agente_modulo'}, $week_utimestamp[$i]);
|
||||
next unless defined ($last_data);
|
||||
$first_data = get_db_value ($dbh, 'SELECT datos
|
||||
FROM tagente_datos
|
||||
WHERE id_agente_modulo = ?
|
||||
AND utimestamp < ?
|
||||
LIMIT 1', $target_module->{'id_agente_modulo'}, $temp1);
|
||||
next unless defined ($first_data);
|
||||
$sum_data++ if ($last_data != 0);
|
||||
$sum_data++ if ($first_data != 0);
|
||||
$week_data[$i] = ($sum_data > 0) ? (($last_data + $first_data) / $sum_data) : 0;
|
||||
}
|
||||
else {
|
||||
$week_data[$i] = $average_interval;
|
||||
}
|
||||
|
||||
# It's possible that one of the week_data[i] values was not valid (NULL)
|
||||
# so recheck it and relay on n=0 for "no data" values set to 0 in result
|
||||
# Calculate total ammount of valida data for each data sample
|
||||
if ((is_numeric($week_data[$i])) && ($week_data[$i] > 0)) {
|
||||
$n++;
|
||||
# Average SUM
|
||||
$average = $average + $week_data[$i];
|
||||
}
|
||||
|
||||
# Capacity planning module.
|
||||
exec_capacity_planning_module($pa_config, $agent_module, $server_id, $dbh);
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Execute a capacity planning module.
|
||||
########################################################################
|
||||
sub exec_capacity_planning_module($$$$) {
|
||||
my ($pa_config, $module, $server_id, $dbh) = @_;
|
||||
my $pred;
|
||||
|
||||
# Retrieve the target module.
|
||||
my $target_module = get_db_single_row($dbh, 'SELECT * FROM tagente_modulo WHERE id_agente_modulo = ?', $module->{'custom_integer_1'});
|
||||
if (!defined($target_module)) {
|
||||
pandora_update_module_on_error ($pa_config, $module, $dbh);
|
||||
return;
|
||||
}
|
||||
|
||||
# Real average value
|
||||
$average = ($n > 0) ? ($average / $n) : 0;
|
||||
|
||||
# (PROC) Compare with current data
|
||||
if ($prediction_mode == 0) {
|
||||
# Calculate typical deviation
|
||||
my $typical_deviation = 0;
|
||||
for (my $i=0; $i< $n; $i++) {
|
||||
if ((is_numeric($week_data[$i])) && ($week_data[$i] > 0)) {
|
||||
$typical_deviation = $typical_deviation + (($week_data[$i] - $average)**2);
|
||||
|
||||
# Set the period.
|
||||
my $period;
|
||||
|
||||
# Weekly.
|
||||
if ($module->{'custom_integer_2'} == 0) {
|
||||
$period = 604800;
|
||||
}
|
||||
# Monthly.
|
||||
elsif ($module->{'custom_integer_2'} == 1) {
|
||||
$period = 2678400;
|
||||
}
|
||||
# Daily.
|
||||
else {
|
||||
$period = 86400;
|
||||
}
|
||||
|
||||
# Set other parameters.
|
||||
my $now = time();
|
||||
my $from = $now - $period;
|
||||
my $type = $module->{'custom_string_2'};
|
||||
my $target_value = $module->{'custom_string_1'};
|
||||
|
||||
# Fit a line of the form: y = theta_0 + x * theta_1
|
||||
my ($theta_0, $theta_1);
|
||||
eval {
|
||||
($theta_0, $theta_1) = linear_regression($target_module, $from, $now, $dbh);
|
||||
};
|
||||
if (!defined($theta_0) || !defined($theta_1)) {
|
||||
pandora_update_module_on_error ($pa_config, $module, $dbh);
|
||||
return;
|
||||
}
|
||||
|
||||
# Predict the value.
|
||||
if ($type eq 'estimation_absolute') {
|
||||
# y = theta_0 + x * theta_1
|
||||
$pred = $theta_0 + ($now + $target_value) * $theta_1;
|
||||
}
|
||||
# Predict the date.
|
||||
else {
|
||||
# Infinity.
|
||||
if ($theta_1 == 0) {
|
||||
$pred = -1;
|
||||
} else {
|
||||
# x = (y - theta_0) / theta_1
|
||||
$pred = ($target_value - $theta_0) / $theta_1;
|
||||
|
||||
# Convert the prediction from a unix timestamp to days from now.
|
||||
$pred = ($pred - $now) / 86400;
|
||||
|
||||
# We are not interested in past dates.
|
||||
if ($pred < 0) {
|
||||
$pred = -1;
|
||||
}
|
||||
}
|
||||
$typical_deviation = ($n > 1) ? sqrt ($typical_deviation / ($n-1)) : 0;
|
||||
|
||||
my $current_value = get_db_value ($dbh, 'SELECT datos
|
||||
FROM tagente_estado
|
||||
WHERE id_agente_modulo = ?', $target_module->{'id_agente_modulo'});
|
||||
if ( ($current_value > ($average - $typical_deviation)) && ($current_value < ($average + $typical_deviation)) ){
|
||||
$module_data = 1; # OK !!
|
||||
}
|
||||
else {
|
||||
$module_data = 0; # Out of predictions
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Prediction based on data
|
||||
$module_data = $average;
|
||||
}
|
||||
|
||||
my %data = ("data" => $module_data);
|
||||
pandora_process_module ($pa_config, \%data, '', $agent_module, '', $timestamp, $utimestamp, $server_id, $dbh);
|
||||
|
||||
my $agent_os_version = get_db_value ($dbh, 'SELECT os_version
|
||||
FROM tagente
|
||||
WHERE id_agente = ?', $agent_module->{'id_agente'});
|
||||
# Update the module.
|
||||
my %data = ("data" => $pred);
|
||||
my $utimestamp = time ();
|
||||
my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime($utimestamp));
|
||||
pandora_process_module ($pa_config, \%data, '', $module, '', $timestamp, $utimestamp, $server_id, $dbh);
|
||||
|
||||
# Update the agent.
|
||||
my $agent_os_version = get_db_value ($dbh, 'SELECT os_version FROM tagente WHERE id_agente = ?', $module->{'id_agente'});
|
||||
if ($agent_os_version eq ''){
|
||||
$agent_os_version = $pa_config->{'servername'}.'_Prediction';
|
||||
}
|
||||
|
||||
pandora_update_agent ($pa_config, $timestamp, $agent_module->{'id_agente'}, undef, undef, -1, $dbh);
|
||||
pandora_update_agent ($pa_config, $timestamp, $module->{'id_agente'}, undef, undef, -1, $dbh);
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Perform linear regression on the given module.
|
||||
########################################################################
|
||||
sub linear_regression($$$$) {
|
||||
my ($module, $from, $to, $dbh) = @_;
|
||||
|
||||
# Should not happen.
|
||||
return if ($module->{'module_interval'} < 1);
|
||||
|
||||
# Retrieve the data.
|
||||
my @rows = get_db_rows($dbh, 'SELECT datos, utimestamp FROM tagente_datos WHERE id_agente_modulo = ? AND utimestamp > ? AND utimestamp < ? ORDER BY utimestamp ASC', $module->{'id_agente_modulo'}, $from, $to);
|
||||
return if scalar(@rows) <= 0;
|
||||
|
||||
# Perform linear regression on the data.
|
||||
my $reg = PandoraFMS::Statistics::Regression->new( "linear regression", ["const", "x"] );
|
||||
my $prev_utimestamp = $from;
|
||||
foreach my $row (@rows) {
|
||||
my ($utimestamp, $data) = ($row->{'utimestamp'}, $row->{'datos'});
|
||||
|
||||
# Elapsed time.
|
||||
my $elapsed = $utimestamp - $prev_utimestamp;
|
||||
$elapsed = 1 unless $elapsed > 0;
|
||||
$prev_utimestamp = $utimestamp;
|
||||
|
||||
# Number of points (Pandora compresses data!)
|
||||
my $local_count = floor($elapsed / $module->{'module_interval'});
|
||||
$local_count = 1 if $local_count <= 0;
|
||||
|
||||
# Add the points.
|
||||
for (my $i = 0; $i < $local_count; $i++) {
|
||||
$reg->include($data, [1.0, $utimestamp]);
|
||||
}
|
||||
}
|
||||
|
||||
return $reg->theta();
|
||||
}
|
||||
|
||||
1;
|
||||
|
776
pandora_server/lib/PandoraFMS/Statistics/Regression.pm
Normal file
776
pandora_server/lib/PandoraFMS/Statistics/Regression.pm
Normal file
@ -0,0 +1,776 @@
|
||||
################################################################
|
||||
# Statistics::Regression package included in Pandora FMS.
|
||||
# See: https://metacpan.org/pod/Statistics::Regression
|
||||
################################################################
|
||||
package PandoraFMS::Statistics::Regression;
|
||||
|
||||
$VERSION = '0.53';
|
||||
my $DATE = "2007/07/07";
|
||||
my $MNAME= "$0::Statistics::Regression";
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => qw{ uninitialized };
|
||||
|
||||
use Carp;
|
||||
|
||||
################################################################
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Regression.pm - weighted linear regression package (line+plane fitting)
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Statistics::Regression;
|
||||
|
||||
# Create regression object
|
||||
my $reg = Statistics::Regression->new( "sample regression", [ "const", "someX", "someY" ] );
|
||||
|
||||
# Add data points
|
||||
$reg->include( 2.0, [ 1.0, 3.0, -1.0 ] );
|
||||
$reg->include( 1.0, [ 1.0, 5.0, 2.0 ] );
|
||||
$reg->include( 20.0, [ 1.0, 31.0, 0.0 ] );
|
||||
$reg->include( 15.0, [ 1.0, 11.0, 2.0 ] );
|
||||
|
||||
or
|
||||
|
||||
my %d;
|
||||
$d{const} = 1.0; $d{someX}= 5.0; $d{someY}= 2.0; $d{ignored}="anything else";
|
||||
$reg->include( 3.0, \%d ); # names are picked off the Regression specification
|
||||
|
||||
Please note that *you* must provide the constant if you want one.
|
||||
|
||||
# Finally, print the result
|
||||
$reg->print();
|
||||
|
||||
This prints the following:
|
||||
|
||||
****************************************************************
|
||||
Regression 'sample regression'
|
||||
****************************************************************
|
||||
Name Theta StdErr T-stat
|
||||
[0='const'] 0.2950 6.0512 0.05
|
||||
[1='someX'] 0.6723 0.3278 2.05
|
||||
[2='someY'] 1.0688 2.7954 0.38
|
||||
|
||||
R^2= 0.808, N= 4
|
||||
****************************************************************
|
||||
|
||||
|
||||
|
||||
The hash input method has the advantage that you can now just
|
||||
fill the observation hashes with all your variables, and use the
|
||||
same code to run regression, changing the regression
|
||||
specification at one and only one spot (the new() invokation).
|
||||
You do not need to change the inputs in the include() statement.
|
||||
For example,
|
||||
|
||||
my @obs; ## a global variable. observations are like: %oneobs= %{$obs[1]};
|
||||
|
||||
sub run_regression {
|
||||
my $reg = Statistics::Regression->new( $_[0], $_[2] );
|
||||
foreach my $obshashptr (@obs) { $reg->include( $_[1], $_[3] ); }
|
||||
$reg->print();
|
||||
}
|
||||
|
||||
run_regression("bivariate regression", $obshashptr->{someY}, [ "const", "someX" ] );
|
||||
run_regression("trivariate regression", $obshashptr->{someY}, [ "const", "someX", "someZ" ] );
|
||||
|
||||
|
||||
|
||||
Of course, you can use the subroutines to do the printing work yourself:
|
||||
|
||||
my @theta = $reg->theta();
|
||||
my @se = $reg->standarderrors();
|
||||
my $rsq = $reg->rsq();
|
||||
my $adjrsq = $reg->adjrsq();
|
||||
my $ybar = $reg->ybar(); ## the average of the y vector
|
||||
my $sst = $reg->sst(); ## the sum-squares-total
|
||||
my $sigmasq= $reg->sigmasq(); ## the variance of the residual
|
||||
my $k = $reg->k(); ## the number of variables
|
||||
my $n = $reg->n(); ## the number of observations
|
||||
|
||||
In addition, there are some other helper routines, and a
|
||||
subroutine linearcombination_variance(). If you don't know what
|
||||
this is, don't use it.
|
||||
|
||||
|
||||
=head1 BACKGROUND WARNING
|
||||
|
||||
You should have an understanding of OLS regressions if you want
|
||||
to use this package. You can get this from an introductory
|
||||
college econometrics class and/or from most intermediate college
|
||||
statistics classes. If you do not have this background
|
||||
knowledge, then this package will remain a mystery to you.
|
||||
There is no support for this package--please don't expect any.
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Regression.pm is a multivariate linear regression package. That
|
||||
is, it estimates the c coefficients for a line-fit of the type
|
||||
|
||||
y= c(0)*x(0) + c(1)*x1 + c(2)*x2 + ... + c(k)*xk
|
||||
|
||||
given a data set of N observations, each with k independent x
|
||||
variables and one y variable. Naturally, N must be greater than
|
||||
k---and preferably considerably greater. Any reasonable
|
||||
undergraduate statistics book will explain what a regression is.
|
||||
Most of the time, the user will provide a constant ('1') as x(0)
|
||||
for each observation in order to allow the regression package to
|
||||
fit an intercept.
|
||||
|
||||
|
||||
=head1 ALGORITHM
|
||||
|
||||
=head2 Original Algorithm (ALGOL-60):
|
||||
|
||||
W. M. Gentleman, University of Waterloo, "Basic
|
||||
Description For Large, Sparse Or Weighted Linear Least
|
||||
Squares Problems (Algorithm AS 75)," Applied Statistics
|
||||
(1974) Vol 23; No. 3
|
||||
|
||||
Gentleman's algorithm is I<the> statistical standard. Insertion
|
||||
of a new observation can be done one observation at any time
|
||||
(WITH A WEIGHT!), and still only takes a low quadratic time.
|
||||
The storage space requirement is of quadratic order (in the
|
||||
indep variables). A practically infinite number of observations
|
||||
can easily be processed!
|
||||
|
||||
=head2 Internal Data Structures
|
||||
|
||||
R=Rbar is an upperright triangular matrix, kept in normalized
|
||||
form with implicit 1's on the diagonal. D is a diagonal scaling
|
||||
matrix. These correspond to "standard Regression usage" as
|
||||
|
||||
X' X = R' D R
|
||||
|
||||
A backsubsitution routine (in thetacov) allows to invert the R
|
||||
matrix (the inverse is upper-right triangular, too!). Call this
|
||||
matrix H, that is H=R^(-1).
|
||||
|
||||
(X' X)^(-1) = [(R' D^(1/2)') (D^(1/2) R)]^(-1)
|
||||
= [ R^-1 D^(-1/2) ] [ R^-1 D^(-1/2) ]'
|
||||
|
||||
|
||||
=head1 BUGS/PROBLEMS
|
||||
|
||||
None known.
|
||||
|
||||
=over 4
|
||||
|
||||
=item Perl Problem
|
||||
|
||||
Unfortunately, perl is unaware of IEEE number representations.
|
||||
This makes it a pain to test whether an observation contains any
|
||||
missing variables (coded as 'NaN' in Regression.pm).
|
||||
|
||||
=back
|
||||
|
||||
=for comment
|
||||
pod2html -noindex -title "perl weighted least squares regression package" Regression.pm > Regression.html
|
||||
|
||||
|
||||
=head1 VERSION and RECENT CHANGES
|
||||
|
||||
2007/04/04: Added Coefficient Standard Errors
|
||||
|
||||
2007/07/01: Added self-test use (if invoked as perl Regression.pm)
|
||||
at the end. cleaned up some print sprintf.
|
||||
changed syntax on new() to eliminate passing K.
|
||||
|
||||
2007/07/07: allowed passing hash with names to include().
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Naturally, Gentleman invented this algorithm. It was adaptated
|
||||
by Ivo Welch. Alan Miller (alan\@dmsmelb.mel.dms.CSIRO.AU)
|
||||
pointed out nicer ways to compute the R^2. Ivan Tubert-Brohman
|
||||
helped wrap the module as as a standard CPAN distribution.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This module is released for free public use under a GPL license.
|
||||
|
||||
(C) Ivo Welch, 2001,2004, 2007.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
################################################################
|
||||
#### let's start with handling of missing data ("nan" or "NaN")
|
||||
################################################################
|
||||
use constant TINY => 1e-8;
|
||||
my $nan= "NaN";
|
||||
|
||||
sub isNaN {
|
||||
if ($_[0] !~ /[0-9nan]/) { confess "$MNAME:isNaN: definitely not a number in NaN: '$_[0]'"; }
|
||||
return ($_[0]=~ /NaN/i) || ($_[0] != $_[0]);
|
||||
}
|
||||
|
||||
|
||||
################################################################
|
||||
### my $reg = Statistics::Regression->new($regname, \@var_names)
|
||||
###
|
||||
### Receives the number of variables on each observations (i.e.,
|
||||
### an integer) and returns the blessed data structure as a
|
||||
### Statistics::Regression object. Also takes an optional name
|
||||
### for this regression to remember, as well as a reference to a
|
||||
### k*1 array of names for the X coefficients.
|
||||
###
|
||||
### I have now made it mandatory to give some names.
|
||||
###
|
||||
################################################################
|
||||
sub new {
|
||||
my $classname= shift; (!ref($classname)) or confess "$MNAME:new: bad class call to new ($classname).\n";
|
||||
my $regname= shift || "no-name";
|
||||
my $xnameptr= shift;
|
||||
|
||||
(defined($regname)) or confess "$MNAME:new: bad name in for regression. no undef allowed.\n";
|
||||
(!ref($regname)) or confess "$MNAME:new: bad name in for regression.\n";
|
||||
(defined($xnameptr)) or confess "$MNAME:new: You must provide variable names, because this tells me the number of columns. no undef allowed.\n";
|
||||
(ref($xnameptr) eq "ARRAY") or confess "$MNAME:new: bad xnames for regression. Must be pointer.\n";
|
||||
|
||||
my $K= (@{$xnameptr});
|
||||
|
||||
if (!defined($K)) { confess "$MNAME:new: cannot determine the number of variables"; }
|
||||
if ($K<=1) { confess "$MNAME:new: Cannot run a regression without at least two variables."; }
|
||||
|
||||
sub zerovec {
|
||||
my @rv;
|
||||
for (my $i=0; $i<=$_[0]; ++$i) { $rv[$i]=0; }
|
||||
return \@rv;
|
||||
}
|
||||
|
||||
bless {
|
||||
k => $K,
|
||||
regname => $regname,
|
||||
xnames => $xnameptr,
|
||||
|
||||
# constantly updated
|
||||
n => 0,
|
||||
sse => 0,
|
||||
syy => 0,
|
||||
sy => 0,
|
||||
wghtn => 0,
|
||||
d => zerovec($K),
|
||||
thetabar => zerovec($K),
|
||||
rbarsize => ($K+1)*$K/2+1,
|
||||
rbar => zerovec(($K+1)*$K/2+1),
|
||||
|
||||
# other constants
|
||||
neverabort => 0,
|
||||
|
||||
# computed on demand
|
||||
theta => undef,
|
||||
sigmasq => undef,
|
||||
rsq => undef,
|
||||
adjrsq => undef
|
||||
}, $classname;
|
||||
}
|
||||
|
||||
|
||||
################################################################
|
||||
### $reg->include( $y, [ $x1, $x2, $x3 ... $xk ], $weight );
|
||||
###
|
||||
### Add one new observation. The weight is optional. Note that
|
||||
### inclusion with a weight of -1 can be used to delete an
|
||||
### observation.
|
||||
###
|
||||
### The error checking and transfer of arguments is clutzy, but
|
||||
### works. if I had POSIX assured, I could do better number
|
||||
### checking. right now, I don't do any.
|
||||
###
|
||||
### Returns the number of observations so far included.
|
||||
################################################################
|
||||
sub include {
|
||||
my $this = shift;
|
||||
my $yelement= shift;
|
||||
my $xin= shift;
|
||||
my $weight= shift || 1.0;
|
||||
|
||||
# modest input checking;
|
||||
(ref($this)) or confess "$MNAME:include: bad class call to include.\n";
|
||||
(defined($yelement)) or confess "$MNAME:include: bad call for y to include. no undef allowed.\n";
|
||||
(!ref($yelement)) or confess "$MNAME:include: bad call for y to include. need scalar.\n";
|
||||
(defined($xin)) or confess "$MNAME:include: bad call for x to include. no undef allowed.\n";
|
||||
(ref($xin)) or confess "$MNAME:include: bad call for x to include. need reference.\n";
|
||||
(!ref($weight)) or confess "$MNAME:include: bad call for weight to include. need scalar.\n";
|
||||
|
||||
|
||||
# omit observations with missing observations;
|
||||
(defined($yelement)) or confess "$MNAME:include: you must give a y value (predictor).";
|
||||
(isNaN($yelement)) and return $this->{n}; # ignore this observation;
|
||||
## should check for number, not string
|
||||
|
||||
|
||||
# check and transfer the X vector
|
||||
my @xrow;
|
||||
if (ref($xin) eq "ARRAY") { @xrow= @{$xin}; }
|
||||
else {
|
||||
my $xctr=0;
|
||||
foreach my $nm (@{$this->{xnames}}) {
|
||||
(defined($xin->{$nm})) or confess "$MNAME:include: Variable '$nm' needs to be set in hash.\n";
|
||||
$xrow[$xctr]= $xin->{$nm};
|
||||
++$xctr;
|
||||
}
|
||||
}
|
||||
|
||||
my @xcopy;
|
||||
for (my $i=1; $i<=$this->{k}; ++$i) {
|
||||
(defined($xrow[$i-1]))
|
||||
or confess "$MNAME:include: Internal Error: at N=".($this->{n}).", the x[".($i-1)."] is undef. use NaN for missing.";
|
||||
(isNaN($xrow[$i-1])) and return $this->{n};
|
||||
$xcopy[$i]= $xrow[$i-1];
|
||||
## should check for number, not string
|
||||
}
|
||||
|
||||
################ now comes the real routine
|
||||
|
||||
$this->{syy}+= ($weight*($yelement*$yelement));
|
||||
$this->{sy}+= ($weight*($yelement));
|
||||
if ($weight>=0.0) { ++$this->{n}; } else { --$this->{n}; }
|
||||
|
||||
$this->{wghtn}+= $weight;
|
||||
|
||||
for (my $i=1; $i<=$this->{k};++$i) {
|
||||
if ($weight==0.0) { return $this->{n}; }
|
||||
if (abs($xcopy[$i])>(TINY)) {
|
||||
my $xi=$xcopy[$i];
|
||||
|
||||
my $di=$this->{d}->[$i];
|
||||
my $dprimei=$di+$weight*($xi*$xi);
|
||||
my $cbar= $di/$dprimei;
|
||||
my $sbar= $weight*$xi/$dprimei;
|
||||
$weight*=($cbar);
|
||||
$this->{d}->[$i]=$dprimei;
|
||||
my $nextr=int( (($i-1)*( (2.0*$this->{k}-$i))/2.0+1) );
|
||||
if (!($nextr<=$this->{rbarsize}) ) { confess "$MNAME:include: Internal Error 2"; }
|
||||
my $xk;
|
||||
for (my $kc=$i+1;$kc<=$this->{k};++$kc) {
|
||||
$xk=$xcopy[$kc]; $xcopy[$kc]=$xk-$xi*$this->{rbar}->[$nextr];
|
||||
$this->{rbar}->[$nextr]= $cbar * $this->{rbar}->[$nextr]+$sbar*$xk;
|
||||
++$nextr;
|
||||
}
|
||||
$xk=$yelement; $yelement-= $xi*$this->{thetabar}->[$i];
|
||||
$this->{thetabar}->[$i]= $cbar*$this->{thetabar}->[$i]+$sbar*$xk;
|
||||
}
|
||||
}
|
||||
$this->{sse}+=$weight*($yelement*$yelement);
|
||||
|
||||
# indicate that Theta is garbage now
|
||||
$this->{theta}= undef;
|
||||
$this->{sigmasq}= undef; $this->{rsq}= undef; $this->{adjrsq}= undef;
|
||||
|
||||
return $this->{n};
|
||||
}
|
||||
|
||||
|
||||
################################################################
|
||||
###
|
||||
### $reg->rsq(), $reg->adjrsq(), $reg->sigmasq(), $reg->ybar(),
|
||||
### $reg->sst(), $reg->k(), $reg->n()
|
||||
###
|
||||
### These methods provide common auxiliary information. rsq,
|
||||
### adjrsq, sigmasq, sst, and ybar have not been checked but are
|
||||
### likely correct. The results are stored for later usage,
|
||||
### although this is somewhat unnecessary because the
|
||||
### computation is so simple anyway.
|
||||
################################################################
|
||||
|
||||
sub rsq {
|
||||
my $this= shift;
|
||||
return $this->{rsq}= 1.0- $this->{sse} / $this->sst();
|
||||
}
|
||||
|
||||
sub adjrsq {
|
||||
my $this= shift;
|
||||
return $this->{adjrsq}= 1.0- (1.0- $this->rsq())*($this->{n}-1)/($this->{n} - $this->{k});
|
||||
}
|
||||
|
||||
sub sigmasq {
|
||||
my $this= shift;
|
||||
return $this->{sigmasq}= ($this->{n}<=$this->{k}) ? "Inf" : ($this->{sse}/($this->{n} - $this->{k}));
|
||||
}
|
||||
|
||||
sub ybar {
|
||||
my $this= shift;
|
||||
return $this->{ybar}= $this->{sy}/$this->{wghtn};
|
||||
}
|
||||
|
||||
sub sst {
|
||||
my $this= shift;
|
||||
return $this->{sst}= ($this->{syy} - $this->{wghtn}*($this->ybar())**2);
|
||||
}
|
||||
|
||||
sub k {
|
||||
my $this= shift;
|
||||
return $this->{k};
|
||||
}
|
||||
sub n {
|
||||
my $this= shift;
|
||||
return $this->{n};
|
||||
}
|
||||
|
||||
|
||||
|
||||
################################################################
|
||||
### $reg->print() [no arguments!]
|
||||
###
|
||||
### prints the estimated coefficients, and R^2 and N. For an
|
||||
### example see the Synopsis.
|
||||
################################################################
|
||||
sub print {
|
||||
my $this= shift;
|
||||
|
||||
print "****************************************************************\n";
|
||||
print "Regression '$this->{regname}'\n";
|
||||
print "****************************************************************\n";
|
||||
|
||||
my $theta= $this->theta();
|
||||
my @standarderrors= $this->standarderrors();
|
||||
|
||||
printf "%-15s\t%12s\t%12s\t%7s\n", "Name", "Theta", "StdErr", "T-stat";
|
||||
for (my $i=0; $i< $this->k(); ++$i) {
|
||||
my $name= "[$i".(defined($this->{xnames}->[$i]) ? "='$this->{xnames}->[$i]'":"")."]";
|
||||
printf "%-15s\t", $name;
|
||||
printf "%12.4f\t", $theta->[$i];
|
||||
printf "%12.4f\t", $standarderrors[$i];
|
||||
printf "%7.2f", ($theta->[$i]/$standarderrors[$i]);
|
||||
printf "\n";
|
||||
}
|
||||
|
||||
print "\nR^2= ".sprintf("%.3f", $this->rsq()).", N= ".$this->n().", K= ".$this->k()."\n";
|
||||
print "****************************************************************\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
################################################################
|
||||
### $theta = $reg->theta or @theta = $reg->theta
|
||||
###
|
||||
### This is the work horse. It estimates and returns the vector
|
||||
### of coefficients. In scalar context returns an array
|
||||
### reference; in list context it returns the list of
|
||||
### coefficients.
|
||||
################################################################
|
||||
sub theta {
|
||||
my $this= shift;
|
||||
|
||||
if (defined($this->{theta})) {
|
||||
return wantarray ? @{$this->{theta}} : $this->{theta};
|
||||
}
|
||||
|
||||
if ($this->{n} < $this->{k}) { return; }
|
||||
for (my $i=($this->{k}); $i>=1; --$i) {
|
||||
$this->{theta}->[$i]= $this->{thetabar}->[$i];
|
||||
my $nextr= int (($i-1)*((2.0*$this->{k}-$i))/2.0+1);
|
||||
if (!($nextr<=$this->{rbarsize})) { confess "$MNAME:theta: Internal Error 3"; }
|
||||
for (my $kc=$i+1;$kc<=$this->{k};++$kc) {
|
||||
$this->{theta}->[$i]-=($this->{rbar}->[$nextr]*$this->{theta}->[$kc]);
|
||||
++$nextr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $ref = $this->{theta}; shift(@$ref); # we are counting from 0
|
||||
|
||||
# if in a scalar context, otherwise please return the array directly
|
||||
wantarray ? @{$this->{theta}} : $this->{theta};
|
||||
}
|
||||
|
||||
################################################################
|
||||
### @se= $reg->standarderrors()
|
||||
###
|
||||
### This is the most difficult routine. Take it on faith.
|
||||
###
|
||||
### R=Rbar is an upperright triangular matrix, kept in normalized
|
||||
### form with implicit 1's on the diagonal. D is a diagonal scaling
|
||||
### matrix. These correspond to "standard Regression usage" as
|
||||
###
|
||||
### X' X = R' D R
|
||||
###
|
||||
### A backsubsitution routine (in thetacov) allows to invert the R
|
||||
### matrix (the inverse is upper-right triangular, too!). Call this
|
||||
### matrix H, that is H=R^(-1).
|
||||
###
|
||||
### (X' X)^(-1) = [(R' D^(1/2)') (D^(1/2) R)]^(-1)
|
||||
### = [ R^-1 D^(-1/2) ] [ R^-1 D^(-1/2) ]'
|
||||
###
|
||||
### Let's work this for our example, where
|
||||
###
|
||||
### $reg->include( 2.0, [ 1.0, 3.0, -1.0 ] );
|
||||
### $reg->include( 1.0, [ 1.0, 5.0, 2.0 ] );
|
||||
### $reg->include( 20.0, [ 1.0, 31.0, 0.0 ] );
|
||||
### $reg->include( 15.0, [ 1.0, 11.0, 2.0 ] );
|
||||
###
|
||||
### For debuggin, the X'X matrix for our example is
|
||||
### 4, 50, 3
|
||||
### 50 1116 29
|
||||
### 3 29 9
|
||||
###
|
||||
### Its inverse is
|
||||
### 0.70967 -0.027992 -0.146360
|
||||
### -0.02799 0.002082 0.002622
|
||||
### -0.14636 0.002622 0.151450
|
||||
###
|
||||
### Internally, this is kept as follows
|
||||
###
|
||||
### R is 1, 0, 0
|
||||
### 12.5 1 0
|
||||
### 0.75 -0.0173 1
|
||||
###
|
||||
### d is the diagonal(4,491,6.603) matrix, which as 1/sqrt becomes dhi= 0.5, 0.04513, 0.3892
|
||||
###
|
||||
### R * d * R' is indeed the X' X matrix.
|
||||
###
|
||||
### The inverse of R is
|
||||
###
|
||||
### 1, 0, 0
|
||||
### -12.5 1 0
|
||||
### -0.9664 0.01731 1
|
||||
###
|
||||
### in R, t(solve(R) %*% dhi) %*% t( t(solve(R) %*% dhi) ) is the correct inverse.
|
||||
###
|
||||
### The routine has a debug switch which makes it come out very verbose.
|
||||
################################################################
|
||||
my $debug=0;
|
||||
|
||||
sub standarderrors {
|
||||
my $this= shift;
|
||||
our $K= $this->{k}; # convenience
|
||||
|
||||
our @u;
|
||||
sub ui {
|
||||
if ($debug) {
|
||||
($_[0]<1)||($_[0]>$K) and confess "$MNAME:standarderrors: bad index 0 $_[0]\n";
|
||||
($_[1]<1)||($_[1]>$K) and confess "$MNAME:standarderrors: bad index 1 $_[0]\n";
|
||||
}
|
||||
return (($K*($_[0]-1))+($_[1]-1));
|
||||
}
|
||||
sub giveuclear {
|
||||
for (my $i=0; $i<($K**2); ++$i) { $u[$i]=0.0; }
|
||||
return (wantarray) ? @u : \@u;
|
||||
}
|
||||
|
||||
sub u { return $u[ui($_[0], $_[1])]; }
|
||||
sub setu { return $u[ui($_[0], $_[1])]= $_[2]; }
|
||||
sub add2u { return $u[ui($_[0], $_[1])]+= $_[2]; }
|
||||
sub mult2u { return $u[ui($_[0], $_[1])]*= $_[2]; }
|
||||
|
||||
(defined($K)) or confess "$MNAME:standarderrors: Internal Error: I forgot the number of variables.\n";
|
||||
if ($debug) {
|
||||
print "The Start Matrix is:\n";
|
||||
for (my $i=1; $i<=$K; ++$i) {
|
||||
print "[$i]:\t";
|
||||
for (my $j=1; $j<=$K; ++$j) {
|
||||
print $this->rbr($i, $j)."\t";
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
print "The Start d vector is:\n";
|
||||
for (my $i=1; $i<=$K; ++$i) {
|
||||
print "".$this->{d}[$i]."\t";
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
sub rbrindex {
|
||||
return ($_[0] == $_[1]) ? -9 :
|
||||
($_[0]>$_[1]) ? -8 :
|
||||
((($_[0]-1.0)* (2.0*$K-$_[0])/2.0+1.0) + $_[1] - 1 - $_[0] ); }
|
||||
|
||||
# now a real member routine;
|
||||
sub rbr {
|
||||
my $this= shift;
|
||||
return ($_[0] == $_[1]) ? 1 : ( ($_[0]>$_[1]) ? 0 : ($this->{rbar}[rbrindex($_[0],$_[1])]));
|
||||
}
|
||||
|
||||
my $u= giveuclear();
|
||||
|
||||
for (my $j=$K; $j>=1; --$j) {
|
||||
setu($j,$j, 1.0/($this->rbr($j,$j)));
|
||||
for (my $k=$j-1; $k>=1; --$k) {
|
||||
setu($k,$j,0);
|
||||
for (my $i=$k+1; $i<=$j; ++$i) { add2u($k,$j, $this->rbr($k,$i)*u($i,$j)); }
|
||||
mult2u($k,$j, (-1.0)/$this->rbr($k,$k));
|
||||
}
|
||||
}
|
||||
|
||||
if ($debug) {
|
||||
print "The Inverse Matrix of R is:\n";
|
||||
for (my $i=1; $i<=$K; ++$i) {
|
||||
print "[$i]:\t";
|
||||
for (my $j=1; $j<=$K; ++$j) {
|
||||
print $u[ui($i,$j)]."\t";
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
|
||||
for (my $i=1;$i<=$K;++$i) {
|
||||
for (my $j=1;$j<=$K;++$j) {
|
||||
if (abs($this->{d}[$j])<TINY) {
|
||||
mult2u($i,$j, sqrt(1.0/TINY));
|
||||
if (abs($this->{d}[$j])==0.0) {
|
||||
if ($this->{neverabort}) {
|
||||
for (my $i=0; $i<($K**2); ++$i) { $u[$i]= "NaN"; }
|
||||
return undef;
|
||||
}
|
||||
else { confess "$MNAME:standarderrors: I cannot compute the theta-covariance matrix for variable $j ".($this->{d}[$j])."\n"; }
|
||||
}
|
||||
}
|
||||
else { mult2u($i,$j, sqrt(1.0/$this->{d}[$j])); }
|
||||
}
|
||||
}
|
||||
|
||||
if ($debug) {
|
||||
print "The Inverse Matrix of R multipled by D^(-1/2) is:\n";
|
||||
for (my $i=1; $i<=$K; ++$i) {
|
||||
print "[$i]:\t";
|
||||
for (my $j=1; $j<=$K; ++$j) {
|
||||
print $u[ui($i,$j)]."\t";
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$this->{sigmasq}= ($this->{n}<=$K) ? "Inf" : ($this->{sse}/($this->{n} - $K));
|
||||
my @xpxinv;
|
||||
for (my $i=1;$i<=$K; ++$i) {
|
||||
for (my $j=$i;$j<=$K;++$j) {
|
||||
my $indexij= ui($i,$j);
|
||||
$xpxinv[$indexij]= 0.0;
|
||||
for (my $k=1;$k<=$K;++$k) {
|
||||
$xpxinv[$indexij] += $u[ui($i,$k)]*$u[ui($j,$k)];
|
||||
}
|
||||
$xpxinv[ui($j,$i)]= $xpxinv[$indexij]; # this is symmetric
|
||||
}
|
||||
}
|
||||
|
||||
if ($debug) {
|
||||
print "The full inverse matrix of X'X is:\n";
|
||||
for (my $i=1; $i<=$K; ++$i) {
|
||||
print "[$i]:\t";
|
||||
for (my $j=1; $j<=$K; ++$j) {
|
||||
print $xpxinv[ui($i,$j)]."\t";
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
print "The sigma^2 is ".$this->{sigmasq}."\n";
|
||||
}
|
||||
|
||||
## 99% of the usage here will be to print the diagonal elements of sqrt ( (X' X) sigma^2 )
|
||||
## so, let's make this our first returned object;
|
||||
|
||||
my @secoefs;
|
||||
for (my $i=1; $i<=$K; ++$i) {
|
||||
$secoefs[$i-1]= sqrt($xpxinv[ui($i,$i)] * $this->{sigmasq});
|
||||
}
|
||||
if ($debug) { for (my $i=0; $i<$K; ++$i) { print " $secoefs[$i] "; } print "\n"; }
|
||||
|
||||
# the following are clever return methods; if the user goes over the secoefs,
|
||||
# almost surely an error will result, because he will run into xpxinv. For special
|
||||
# usage, however, xpxinv may still be useful.
|
||||
|
||||
return ( @secoefs, \@xpxinv, $this->sigmasq );
|
||||
}
|
||||
|
||||
|
||||
################################
|
||||
sub linearcombination_variance {
|
||||
my $this= shift;
|
||||
our $K= $this->{k}; # convenience
|
||||
|
||||
my @linear= @_;
|
||||
|
||||
($#linear+1 == $K) or confess "$MNAME:linearcombination_variance: ".
|
||||
"Sorry, you must give a vector of length $K, not ".($#linear+1)."\n";
|
||||
|
||||
my @allback= $this->standarderrors(); # compute everything we need;
|
||||
|
||||
my $xpxinv= $allback[$this->{k}];
|
||||
my $sigmasq= $allback[$this->{k}+1];
|
||||
|
||||
my $sum=0;
|
||||
for (my $i=1; $i<=$K; ++$i) {
|
||||
for (my $j=1; $j<=$K; ++$j) {
|
||||
$sum+= $linear[$i-1]*$linear[$j-1]*$xpxinv->[ui($i,$j)];
|
||||
}
|
||||
}
|
||||
$sum*=$sigmasq;
|
||||
return $sum;
|
||||
}
|
||||
|
||||
|
||||
################################################################
|
||||
### sub dump() was used internally for debugging.
|
||||
################################################################
|
||||
sub dump {
|
||||
my $this= $_[0];
|
||||
print "****************************************************************\n";
|
||||
print "Regression '$this->{regname}'\n";
|
||||
print "****************************************************************\n";
|
||||
sub print1val {
|
||||
no strict;
|
||||
print "$_[1]($_[2])=\t". ((defined($_[0]->{ $_[2] }) ? $_[0]->{ $_[2] } : "intentionally undef"));
|
||||
|
||||
my $ref=$_[0]->{ $_[2] };
|
||||
|
||||
if (ref($ref) eq 'ARRAY') {
|
||||
my $arrayref= $ref;
|
||||
print " $#$arrayref+1 elements:\n";
|
||||
if ($#$arrayref>30) {
|
||||
print "\t";
|
||||
for(my $i=0; $i<$#$arrayref+1; ++$i) { print "$i='$arrayref->[$i]';"; }
|
||||
print "\n";
|
||||
}
|
||||
else {
|
||||
for(my $i=0; $i<$#$arrayref+1; ++$i) { print "\t$i=\t'$arrayref->[$i]'\n"; }
|
||||
}
|
||||
}
|
||||
elsif (ref($ref) eq 'HASH') {
|
||||
my $hashref= $ref;
|
||||
print " ".scalar(keys(%$hashref))." elements\n";
|
||||
while (my ($key, $val) = each(%$hashref)) {
|
||||
print "\t'$key'=>'$val';\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
print " [was scalar]\n"; }
|
||||
}
|
||||
|
||||
while (my ($key, $val) = each(%$this)) {
|
||||
$this->print1val($key, $key);
|
||||
}
|
||||
print "****************************************************************\n";
|
||||
}
|
||||
|
||||
################################################################
|
||||
### The Test Program. Invoke as "perl Regression.pm".
|
||||
################################################################
|
||||
|
||||
|
||||
if ($0 eq "Regression.pm") {
|
||||
|
||||
# Create regression object
|
||||
my $reg = Statistics::Regression->new( "sample regression", [ "const", "someX", "someY" ] );
|
||||
|
||||
# Add data points
|
||||
$reg->include( 2.0, [ 1.0, 3.0, -1.0 ] );
|
||||
$reg->include( 1.0, [ 1.0, 5.0, 2.0 ] );
|
||||
$reg->include( 20.0, [ 1.0, 31.0, 0.0 ] );
|
||||
|
||||
my %inhash= ( const => 1.0, someX => 11.0, someY => 2.0, ignored => "ignored" );
|
||||
$reg->include( 15.0, \%inhash );
|
||||
# $reg->include( 15.0, [ 1.0, 11.0, 2.0 ] );
|
||||
|
||||
# Print the result
|
||||
$reg->print();
|
||||
}
|
||||
|
||||
|
||||
1;
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
%define name pandorafms_server
|
||||
%define version 7.0NG.758.1
|
||||
%define release 211207
|
||||
%define release 211214
|
||||
|
||||
Summary: Pandora FMS Server
|
||||
Name: %{name}
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
%define name pandorafms_server
|
||||
%define version 7.0NG.758.1
|
||||
%define release 211207
|
||||
%define release 211214
|
||||
|
||||
Summary: Pandora FMS Server
|
||||
Name: %{name}
|
||||
|
@ -9,7 +9,7 @@
|
||||
# **********************************************************************
|
||||
|
||||
PI_VERSION="7.0NG.758.1"
|
||||
PI_BUILD="211207"
|
||||
PI_BUILD="211214"
|
||||
|
||||
MODE=$1
|
||||
if [ $# -gt 1 ]; then
|
||||
|
@ -35,7 +35,7 @@ use PandoraFMS::Config;
|
||||
use PandoraFMS::DB;
|
||||
|
||||
# version: define current version
|
||||
my $version = "7.0NG.758.1 Build 211207";
|
||||
my $version = "7.0NG.758.1 Build 211214";
|
||||
|
||||
# Pandora server configuration
|
||||
my %conf;
|
||||
|
@ -36,7 +36,7 @@ use Encode::Locale;
|
||||
Encode::Locale::decode_argv;
|
||||
|
||||
# version: define current version
|
||||
my $version = "7.0NG.758.1 Build 211207";
|
||||
my $version = "7.0NG.758.1 Build 211214";
|
||||
|
||||
# save program name for logging
|
||||
my $progname = basename($0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user