Merge remote-tracking branch 'origin/develop' into ent-8558-inventario-pasa-de-enterprise-open

This commit is contained in:
Calvo 2023-01-13 09:08:17 +01:00
commit ce224d67ba
78 changed files with 1690 additions and 672 deletions

View File

@ -18,6 +18,7 @@ WORKDIR=/opt/pandora/deploy
S_VERSION='2022052501'
LOGFILE="/tmp/pandora-deploy-community-$(date +%F).log"
rm -f $LOGFILE &> /dev/null # remove last log before start
# define default variables
[ "$TZ" ] || TZ="Europe/Madrid"
@ -271,8 +272,10 @@ echo -en "${cyan}Installing phantomjs...${reset}"
/usr/bin/phantomjs --version &>> "$LOGFILE"
check_cmd_status "Error Installing phanromjs"
# Chromium
execute_cmd "apt install -y chromium-browser" "Instaling chromium browser"
# Chrome
execute_cmd "wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" "Downloading google chrome"
execute_cmd "apt install -y ./google-chrome-stable_current_amd64.deb" "Intalling google chrome"
execute_cmd "ln -s /usr/bin/google-chrome /usr/bin/chromium-browser" "Creating /usr/bin/chromium-browser Symlink"
# SDK VMware perl dependencies
vmware_dependencies=" \

View File

@ -1,5 +1,5 @@
package: pandorafms-agent-unix
Version: 7.0NG.767-221228
Version: 7.0NG.767-230113
Architecture: all
Priority: optional
Section: admin

View File

@ -14,7 +14,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
pandora_version="7.0NG.767-221228"
pandora_version="7.0NG.767-230113"
echo "Test if you has the tools for to make the packages."
whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null

View File

@ -1015,7 +1015,7 @@ my $Sem = undef;
my $ThreadSem = undef;
use constant AGENT_VERSION => '7.0NG.767';
use constant AGENT_BUILD => '221228';
use constant AGENT_BUILD => '230113';
# Agent log default file size maximum and instances
use constant DEFAULT_MAX_LOG_SIZE => 600000;

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_agent_unix
%define version 7.0NG.767
%define release 221228
%define release 230113
Summary: Pandora FMS Linux agent, PERL version
Name: %{name}

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_agent_unix
%define version 7.0NG.767
%define release 221228
%define release 230113
Summary: Pandora FMS Linux agent, PERL version
Name: %{name}

View File

@ -10,7 +10,7 @@
# **********************************************************************
PI_VERSION="7.0NG.767"
PI_BUILD="221228"
PI_BUILD="230113"
OS_NAME=`uname -s`
FORCE=0

View File

@ -186,7 +186,7 @@ UpgradeApplicationID
{}
Version
{221228}
{230113}
ViewReadme
{Yes}

View File

@ -30,7 +30,7 @@ using namespace Pandora;
using namespace Pandora_Strutils;
#define PATH_SIZE _MAX_PATH+1
#define PANDORA_VERSION ("7.0NG.767 Build 221228")
#define PANDORA_VERSION ("7.0NG.767 Build 230113")
string pandora_path;
string pandora_dir;

View File

@ -11,7 +11,7 @@ BEGIN
VALUE "LegalCopyright", "Artica ST"
VALUE "OriginalFilename", "PandoraAgent.exe"
VALUE "ProductName", "Pandora FMS Windows Agent"
VALUE "ProductVersion", "(7.0NG.767(Build 221228))"
VALUE "ProductVersion", "(7.0NG.767(Build 230113))"
VALUE "FileVersion", "1.0.0.0"
END
END

View File

@ -1,5 +1,5 @@
package: pandorafms-console
Version: 7.0NG.767-221228
Version: 7.0NG.767-230113
Architecture: all
Priority: optional
Section: admin

View File

@ -14,7 +14,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
pandora_version="7.0NG.767-221228"
pandora_version="7.0NG.767-230113"
package_pear=0
package_pandora=1

View File

@ -1,66 +0,0 @@
<?php
// Pandora FMS - http://pandorafms.com
// ==================================================
// Copyright (c) 2005-2021 Artica Soluciones Tecnologicas
// Please see http://pandorafms.org for full contribution list
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; version 2
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
require_once __DIR__.'/../include/config.php';
require_once __DIR__.'/../include/auth/mysql.php';
require_once __DIR__.'/../include/functions.php';
require_once __DIR__.'/../include/functions_db.php';
/*
* Review if sample agent is active and deploys configuration for
* visual consoles if necessary
*/
global $config;
// Deployment of sample agent for visual consoles.
if ($config['sample_agent'] == 1 && !isset($config['sample_agent_deployed'])) {
$id_agente = db_get_sql('SELECT id_agente FROM tagente WHERE nombre = "Sample_Agent";');
$modules = db_get_all_rows_filter('tagente_modulo', ['id_agente' => $id_agente], 'id_agente_modulo');
$count_modules = count($modules);
// Update of layout 1 (Rack sample).
$images_rack_server = [
'rack_server_rack',
'rack_server',
'rack_switch',
'rack_firewall',
'rack_double_server',
'rack_frame',
'rack_pdu',
];
$query = 'UPDATE `tlayout_data` SET `id_agent` = '.$id_agente.', `id_agente_modulo` = CASE ';
for ($i = 0; $i < $count_modules; $i++) {
$query .= 'WHEN `image` = "'.$images_rack_server[$i].'" THEN '.$modules[$i]['id_agente_modulo'].' ';
}
$query .= 'END WHERE `id_layout` = 1 AND `image` IN ("'.implode('","', $images_rack_server).'");';
db_process_sql($query);
// Update of layout 2 (Dashboard).
$query = 'UPDATE `tlayout_data` SET `id_agent`= '.$id_agente.', `id_agente_modulo` = CASE ';
$query .= 'WHEN `id` = 107 THEN '.$modules[0]['id_agente_modulo'].' ';
$query .= 'WHEN `id` = 108 THEN '.$modules[1]['id_agente_modulo'].' ';
$query .= 'WHEN `id` = 109 THEN '.$modules[2]['id_agente_modulo'].' ';
$query .= 'WHEN `id` = 110 THEN '.$modules[2]['id_agente_modulo'].' ';
$query .= 'WHEN `id` = 111 THEN '.$modules[3]['id_agente_modulo'].' ';
$query .= 'WHEN `id` = 112 THEN '.$modules[4]['id_agente_modulo'].' ';
$query .= 'WHEN `id` = 113 THEN '.$modules[5]['id_agente_modulo'].' ';
$query .= 'WHEN `id` = 114 THEN '.$modules[6]['id_agente_modulo'].' ';
$query .= 'END WHERE `id_layout` = 2 AND `id` IN (107,108,109,110,111,112,113,114);';
db_process_sql($query);
// This setting will avoid regenerate all the times the visual consoles.
config_update_value('sample_agent_deployed', 1);
}
extensions_add_main_function('sample_agent_deployment');

View File

@ -224,6 +224,7 @@ if ($result === false) {
$result = [];
}
$table = new stdClass();
$table->width = '100%';
$table->cellpadding = 0;
$table->cellspacing = 0;

View File

@ -1177,7 +1177,11 @@ foreach ($modules as $module) {
$data[6] = ui_print_status_image(
$status,
htmlspecialchars($title),
true
true,
false,
false,
false,
($module['ip_target']) ? 'IP: '.$module['ip_target'] : false
);
// MAX / MIN values.

View File

@ -40,6 +40,7 @@ $update_command = (bool) get_parameter('update_command');
$create_command = (bool) get_parameter('create_command');
$delete_command = (bool) get_parameter('delete_command');
$copy_command = (bool) get_parameter('copy_command');
$content_type = (string) get_parameter('content_type', 'text/plain');
$url = 'index.php?sec='.$sec.'&sec2=godmode/alerts/alert_commands';
@ -226,7 +227,7 @@ if (is_ajax()) {
'field'.$i.'_value',
'text/plain',
'',
'',
$content_type == 'text/plain',
$is_management_allowed,
'',
'',
@ -238,7 +239,7 @@ if (is_ajax()) {
'field'.$i.'_value',
'text/html',
'',
'text/html',
$content_type == 'text/html',
$is_management_allowed,
'',
'',

View File

@ -353,9 +353,18 @@ if ($delete_action) {
if ($enable_alert) {
$searchFlag = true;
$id_alert = (int) get_parameter('id_alert');
$id_agente = ($id_agente !== 0) ? $id_agente : alerts_get_agent_by_alert($id_alert);
$result = alerts_agent_module_disable($id_alert, false);
if ($id_agente) {
db_process_sql(
'UPDATE tagente
SET update_alert_count = 1
WHERE id_agente = '.$id_agente
);
}
if ($result) {
db_pandora_audit(
AUDIT_LOG_ALERT_MANAGEMENT,
@ -380,9 +389,18 @@ if ($enable_alert) {
if ($disable_alert) {
$searchFlag = true;
$id_alert = (int) get_parameter('id_alert');
$id_agente = ($id_agente !== 0) ? $id_agente : alerts_get_agent_by_alert($id_alert);
$result = alerts_agent_module_disable($id_alert, true);
if ($id_agente) {
db_process_sql(
'UPDATE tagente
SET update_alert_count = 1
WHERE id_agente = '.$id_agente
);
}
if ($result) {
db_pandora_audit(
AUDIT_LOG_ALERT_MANAGEMENT,

View File

@ -109,6 +109,8 @@ if ($id) {
$text_agent = '';
}
}
$server_id = ($filter['server_id'] ?? '');
} else {
$id_group = '';
$id_group_filter = '';
@ -134,6 +136,7 @@ if ($id) {
$filter_only_alert = '';
$search_secondary_groups = 0;
$search_recursive_groups = 0;
$server_id = '';
}
if ($update || $create) {
@ -183,6 +186,12 @@ if ($update || $create) {
$custom_data = get_parameter('custom_data', '');
$custom_data_filter_type = get_parameter('custom_data_filter_type', '');
$server_id = '';
if (is_metaconsole() === true) {
$servers_array = get_parameter('server_id', []);
$server_id = implode(',', $servers_array);
}
$values = [
'id_name' => $id_name,
'id_group_filter' => $id_group_filter,
@ -212,6 +221,7 @@ if ($update || $create) {
'search_recursive_groups' => $search_recursive_groups,
'custom_data' => $custom_data,
'custom_data_filter_type' => $custom_data_filter_type,
'server_id' => $server_id,
];
$severity = explode(',', $severity);
@ -708,6 +718,55 @@ if (is_metaconsole()) {
);
}
if (is_metaconsole() === true) {
$servers = metaconsole_get_servers();
if (is_array($servers) === true) {
$servers = array_reduce(
$servers,
function ($carry, $item) {
$carry[$item['id']] = $item['server_name'];
return $carry;
}
);
} else {
$servers = [];
}
$servers[0] = __('Metaconsola');
if ($server_id === '') {
$server_id = array_keys($servers);
} else {
if (is_array($server_id) === false) {
if (is_numeric($server_id) === true) {
if ($server_id !== 0) {
$server_id = [$server_id];
} else {
$server_id = array_keys($servers);
}
} else {
$server_id = explode(',', $server_id);
}
}
}
$table->data[29][0] = '<b>'.__('Server').'</b>';
$table->data[29][1] = html_print_select(
$servers,
'server_id[]',
$server_id,
'',
'',
0,
true,
true,
true,
'',
false,
'height: 60px;'
);
}
echo '<form method="post" action="index.php?sec=geventos&sec2=godmode/events/events&section=edit_filter&pure='.$config['pure'].'">';
html_print_table($table);

View File

@ -1,4 +1,5 @@
<?php
/**
* Godmode menu.
*
@ -424,10 +425,10 @@ if ((bool) check_acl($config['id_user'], 0, 'PM') === true || (bool) check_acl($
if (is_user_admin($config['id_user']) === true) {
$sub['extensions/db_status']['text'] = __('DB Schema Check');
$sub['extensions/db_status']['id'] = 'DB Schema Check';
$sub['extensions/db_status']['sec'] = 'gbman';
$sub['extensions/db_status']['sec'] = 'gextensions';
$sub['extensions/dbmanager']['text'] = __('DB Interface');
$sub['extensions/dbmanager']['id'] = 'DB Interface';
$sub['extensions/dbmanager']['sec'] = 'gbman';
$sub['extensions/dbmanager']['sec'] = 'gextensions';
enterprise_hook('dbBackupManager');
enterprise_hook('elasticsearch_interface_menu');
}
@ -580,6 +581,14 @@ if ($access_console_node === true) {
}
}
if ($access_console_node === true) {
// About.
$menu_godmode['about']['text'] = __('About');
$menu_godmode['about']['id'] = 'about';
}
if ((bool) $config['pure'] === false) {
menu_print_menu($menu_godmode);
}
echo '<div id="about-div"></div>';

View File

@ -1599,6 +1599,10 @@ $(document).ready (function () {
name: "get_recovery_fields",
value: "0"
});
values.push({
name: "content_type",
value: "<?php echo $al_field4; ?>"
})
jQuery.post (<?php echo "'".ui_get_full_url('ajax.php', false, false, false)."'"; ?>,
values,
function (data, status) {
@ -1624,8 +1628,9 @@ $(document).ready (function () {
// The row provided has a predefined class. We delete it.
$('#table_macros-field' + i)
.removeAttr('class');
$("[name=field" + i + "_value]").val(old_value).trigger('change');
if(old_value && i != 4){
$("[name=field" + i + "_value]").val(old_value).trigger('change');
}
$('#table_macros-field').show();
}
}

View File

@ -1643,13 +1643,18 @@ if ($config['admin_can_add_user']) {
}
echo '</div>';
if ($new_user === true) {
html_print_input_hidden('json_profile', $json_profile);
}
html_print_input_hidden('json_profile', $json_profile);
echo '</form>';
profile_print_profile_table($id, io_safe_output($json_profile));
if ($is_err === true && $new_user === true) {
profile_print_profile_table($id, io_safe_output($json_profile), false, true);
} else {
profile_print_profile_table($id, io_safe_output($json_profile));
}
echo '<br />';
@ -1869,6 +1874,8 @@ $(document).ready (function () {
});
$('input:image[name="del"]').click(function (e) {
if($(json_profile).length > 0) return;
if (!confirm ('Are you sure?')) return;
e.preventDefault();
var rows = $("#table_profiles tr").length;
if (((is_metaconsole === '1' && rows <= 4) || (is_metaconsole === '' && rows <= 3)) && user_is_global_admin !== '1') {

View File

@ -1288,6 +1288,37 @@ class HostDevices extends Wizard
],
],
[
'label' => '<b>'.__('Security level').'</b>',
'arguments' => [
'name' => 'snmp_security_level',
'type' => 'select',
'fields' => [
'noAuthNoPriv' => __('Not auth and not privacy method'),
'authNoPriv' => __('Auth and not privacy method'),
'authPriv' => __('Auth and privacy method'),
],
'selected' => $this->task['snmp_security_level'],
'size' => 15,
'return' => true,
],
],
[
'label' => '<b>'.__('Auth method').'</b>',
'arguments' => [
'name' => 'snmp_auth_method',
'type' => 'select',
'fields' => [
'MD5' => __('MD5'),
'SHA' => __('SHA'),
],
'selected' => $this->task['snmp_auth_method'],
'size' => 15,
'return' => true,
],
],
[
'label' => '<b>'.__('Auth password').'</b>'.ui_print_help_tip(
__(
@ -1335,38 +1366,6 @@ class HostDevices extends Wizard
],
],
[
'label' => '<b>'.__('Auth method').'</b>',
'arguments' => [
'name' => 'snmp_auth_method',
'type' => 'select',
'fields' => [
'MD5' => __('MD5'),
'SHA' => __('SHA'),
],
'selected' => $this->task['snmp_auth_method'],
'size' => 15,
'return' => true,
],
],
[
'label' => '<b>'.__('Security level').'</b>',
'arguments' => [
'name' => 'snmp_security_level',
'type' => 'select',
'fields' => [
'noAuthNoPriv' => __('Not auth and not privacy method'),
'authNoPriv' => __('Auth and not privacy method'),
'authPriv' => __('Auth and privacy method'),
],
'selected' => $this->task['snmp_security_level'],
'size' => 15,
'return' => true,
],
],
],
];

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 B

View File

@ -850,7 +850,7 @@ if ($get_agent_alerts_datatable === true) {
} else {
$options_simple = [
'order' => $order,
'limit' => $length,
'limit' => ($length > 0) ? $length : 1844674407370955161,
'offset' => $start,
];
}
@ -915,7 +915,6 @@ if ($get_agent_alerts_datatable === true) {
$data[] = ui_format_alert_row($alert, true, $url, 'font-size: 7pt;');
}
$data = array_reduce(
$data,
function ($carry, $row) {
@ -923,17 +922,29 @@ if ($get_agent_alerts_datatable === true) {
// of objects, making a post-process of certain fields.
$tmp = new stdClass();
// Standby.
$tmp->policy = $row[0];
$tmp->standby = $row[1];
$tmp->force = $row[2];
$tmp->agent_name = $row[3];
$tmp->agent_module_name = $row[4];
$tmp->template_name = $row[5];
$tmp->action = $row[6];
$tmp->last_fired = $row[7];
$tmp->status = $row[8];
$tmp->validate = $row[9];
if (enterprise_installed() === true) {
$tmp->policy = $row[0];
$tmp->standby = $row[1];
$tmp->force = $row[2];
$tmp->agent_name = $row[3];
$tmp->agent_module_name = $row[4];
$tmp->template_name = $row[5];
$tmp->action = $row[6];
$tmp->last_fired = $row[7];
$tmp->status = $row[8];
$tmp->validate = $row[9];
} else {
// Open.
$tmp->standby = $row[0];
$tmp->force = $row[1];
$tmp->agent_name = $row[2];
$tmp->agent_module_name = $row[3];
$tmp->template_name = $row[4];
$tmp->action = $row[5];
$tmp->last_fired = $row[6];
$tmp->status = $row[7];
$tmp->validate = $row[8];
}
$carry[] = $tmp;
return $carry;

View File

@ -59,6 +59,7 @@ $drawConsoleSound = (bool) get_parameter('drawConsoleSound', false);
$process_buffers = (bool) get_parameter('process_buffers', false);
$get_extended_event = (bool) get_parameter('get_extended_event');
$change_status = (bool) get_parameter('change_status');
$get_Acknowledged = (bool) get_parameter('get_Acknowledged');
$change_owner = (bool) get_parameter('change_owner');
$add_comment = (bool) get_parameter('add_comment');
$dialogue_event_response = (bool) get_parameter('dialogue_event_response');
@ -1513,6 +1514,12 @@ if ($change_status === true) {
return;
}
if ($get_Acknowledged === true) {
$event_id = get_parameter('event_id');
echo events_page_general_acknowledged($event_id);
return;
}
if ($change_owner === true) {
$new_owner = get_parameter('new_owner', '');
$event_id = (int) get_parameter('event_id', 0);

View File

@ -1176,8 +1176,8 @@ if (check_login()) {
$status,
$title
);
$last_status_change_text = 'Time elapsed since last status change: ';
$last_status_change_text = ($module['ip_target']) ? 'IP: '.$module['ip_target'].'<br />' : '';
$last_status_change_text .= 'Time elapsed since last status change: ';
$last_status_change_text .= !empty($module['last_status_change']) ? human_time_comparation($module['last_status_change']) : __('N/A');
$data[5] = ui_print_status_image($status, htmlspecialchars($title), true, false, false, false, $last_status_change_text);

View File

@ -148,67 +148,23 @@ function process_user_login_local($login, $pass, $api=false)
{
global $config, $mysql_cache;
// Connect to Database
switch ($config['dbtype']) {
case 'mysql':
if (!$api) {
$sql = sprintf(
"SELECT `id_user`, `password`
FROM `tusuario`
WHERE `id_user` = '%s' AND `not_login` = 0
AND `disabled` = 0",
$login
);
} else {
$sql = sprintf(
"SELECT `id_user`, `password`
FROM `tusuario`
WHERE `id_user` = '%s'
AND `disabled` = 0",
$login
);
}
break;
case 'postgresql':
if (!$api) {
$sql = sprintf(
'SELECT "id_user", "password"
FROM "tusuario"
WHERE "id_user" = \'%s\' AND "not_login" = 0
AND "disabled" = 0',
$login
);
} else {
$sql = sprintf(
'SELECT "id_user", "password"
FROM "tusuario"
WHERE "id_user" = \'%s\'
AND "disabled" = 0',
$login
);
}
break;
case 'oracle':
if (!$api) {
$sql = sprintf(
'SELECT id_user, password
FROM tusuario
WHERE id_user = \'%s\' AND not_login = 0
AND disabled = 0',
$login
);
} else {
$sql = sprintf(
'SELECT id_user, password
FROM tusuario
WHERE id_user = \'%s\'
AND disabled = 0',
$login
);
}
break;
// Connect to Database.
if (!$api) {
$sql = sprintf(
"SELECT `id_user`, `password`
FROM `tusuario`
WHERE `id_user` = '%s' AND `not_login` = 0
AND `disabled` = 0",
$login
);
} else {
$sql = sprintf(
"SELECT `id_user`, `password`
FROM `tusuario`
WHERE `id_user` = '%s'
AND `disabled` = 0",
$login
);
}
$row = db_get_row_sql($sql);
@ -666,8 +622,16 @@ function process_user_contact(string $id_user)
function create_user($id_user, $password, $user_info)
{
$values = $user_info;
$column_type = db_get_column_type('tusuario', 'password');
if (empty($column_type) === false && isset($column_type[0]['COLUMN_TYPE'])) {
$column_type = ($column_type[0]['COLUMN_TYPE'] === 'varchar(60)');
} else {
$column_type = false;
}
$values['id_user'] = $id_user;
$values['password'] = password_hash($password, PASSWORD_BCRYPT);
$values['password'] = ($column_type === false) ? md5($password) : password_hash($password, PASSWORD_BCRYPT);
$values['last_connect'] = 0;
$values['registered'] = get_system_time();
@ -775,9 +739,19 @@ function update_user_password(string $user, string $password_new)
return false;
}
$column_type = db_get_column_type('tusuario', 'password');
if (empty($column_type) === false && isset($column_type[0]['COLUMN_TYPE'])) {
$column_type = ($column_type[0]['COLUMN_TYPE'] === 'varchar(60)');
} else {
$column_type = false;
}
if (isset($config['auth']) === true && $config['auth'] === 'pandora') {
$sql = sprintf(
"UPDATE tusuario SET password = '".password_hash($password_new, PASSWORD_BCRYPT)."', last_pass_change = '".date('Y-m-d H:i:s', get_system_time())."' WHERE id_user = '".$user."'"
"UPDATE tusuario SET password = '%s', last_pass_change = '%s' WHERE id_user = '%s'",
($column_type === false) ? md5($password_new) : password_hash($password_new, PASSWORD_BCRYPT),
date('Y-m-d H:i:s', get_system_time()),
$user
);
$connection = mysql_connect_db(
@ -797,7 +771,7 @@ function update_user_password(string $user, string $password_new)
return db_process_sql_update(
'tusuario',
[
'password' => password_hash($password_new, PASSWORD_BCRYPT),
'password' => ($column_type === false) ? md5($password_new) : password_hash($password_new, PASSWORD_BCRYPT),
'last_pass_change' => date('Y/m/d H:i:s', get_system_time()),
],
['id_user' => $user]
@ -1061,7 +1035,14 @@ function create_user_and_permisions_ldap(
$values['id_user'] = $id_user;
if ($config['ldap_save_password'] || $config['ad_save_password']) {
$values['password'] = password_hash($password, PASSWORD_BCRYPT);
$column_type = db_get_column_type('tusuario', 'password');
if (empty($column_type) === false && isset($column_type[0]['COLUMN_TYPE'])) {
$column_type = ($column_type[0]['COLUMN_TYPE'] === 'varchar(60)');
} else {
$column_type = false;
}
$values['password'] = ($column_type === false) ? md5($password) : password_hash($password, PASSWORD_BCRYPT);
}
$values['last_connect'] = 0;
@ -1493,11 +1474,26 @@ function change_local_user_pass_ldap($id_user, $password)
$local_user_pass = db_get_value_filter('password', 'tusuario', ['id_user' => $id_user]);
$return = false;
if (password_hash($password, PASSWORD_BCRYPT) !== $local_user_pass) {
$values_update = [];
$values_update['password'] = password_hash($password, PASSWORD_BCRYPT);
$return = db_process_sql_update('tusuario', $values_update, ['id_user' => $id_user]);
$column_type = db_get_column_type('tusuario', 'password');
if (empty($column_type) === false && isset($column_type[0]['COLUMN_TYPE'])) {
$column_type = ($column_type[0]['COLUMN_TYPE'] === 'varchar(60)');
} else {
$column_type = false;
}
$values_update = [];
if ($column_type === false) {
if (md5($password) !== $local_user_pass) {
$values_update['password'] = md5($password);
$return = db_process_sql_update('tusuario', $values_update, ['id_user' => $id_user]);
}
} else {
if (password_hash($password, PASSWORD_BCRYPT) !== $local_user_pass) {
$values_update['password'] = password_hash($password, PASSWORD_BCRYPT);
$return = db_process_sql_update('tusuario', $values_update, ['id_user' => $id_user]);
}
}
return $return;

View File

@ -1276,11 +1276,16 @@ class Diagnostics extends Wizard
FROM tagente_datos'
);
$modulesDataCount = db_get_value_sql(
'SELECT count(*) * 300 FROM (SELECT * FROM tagente_datos GROUP BY id_agente_modulo) AS totalmodules'
);
$modulesDataCount = ($modulesDataCount >= 500000) ? $modulesDataCount : 500000;
$taMsg = __(
'The tagente_datos table contains too much data. A historical database is recommended.'
);
$taStatus = 0;
if ($agentDataCount <= 3000000) {
if ($agentDataCount <= $modulesDataCount) {
$taMsg = __(
'The tagente_datos table contains an acceptable amount of data.'
);

View File

@ -20,7 +20,7 @@
/**
* Pandora build version and version
*/
$build_version = 'PC221228';
$build_version = 'PC230113';
$pandora_version = 'v7.0NG.767';
// Do not overwrite default timezone set if defined.

View File

@ -2828,6 +2828,25 @@ function alerts_get_agent_modules(
}
/**
* Return the id_agent of the alert
*
* @param integer $id_agent_module
* @return integer id_agent
*/
function alerts_get_agent_by_alert($id_agent_module)
{
$sql = sprintf(
'SELECT id_agente FROM talert_template_modules atm INNER JOIN tagente_modulo am ON am.id_agente_modulo = atm.id_agent_module WHERE atm.id = %d
',
$id_agent_module
);
$id_agente = db_get_row_sql($sql)['id_agente'];
return $id_agente;
}
function alerts_get_actions_names($actions, $reduce=false)
{
$where = '';

View File

@ -7509,7 +7509,7 @@ function api_set_planned_downtimes_additem($id, $thrash1, $other, $thrash3)
$bad_agents = [];
$i = 0;
foreach ($total_agents as $agent_id) {
$result_agent = agents_check_access_agent($agent_id, 'AD');
$result_agent = agents_check_access_agent($agent_id, 'AR');
if (!$result_agent) {
$bad_agents[] = $agent_id;
unset($agents[$i]);
@ -9601,6 +9601,7 @@ function api_set_new_user($id, $thrash2, $other, $thrash3)
$values['default_event_filter'] = $other['data'][10];
$values['section'] = $other['data'][11];
$values['session_time'] = $other['data'][12];
$values['metaconsole_access_node'] = $other['data'][13];
if (empty($password) === true) {
returnError('Password cannot be empty.');

View File

@ -2530,3 +2530,28 @@ function db_unlock_tables()
return $result;
}
/**
* Get column type. Example: 'varchar(60)'.
*
* @param string $table Table name.
* @param string $column Column name.
*
* @return array|boolean
*/
function db_get_column_type(string $table, string $column='')
{
$sql = sprintf(
'SELECT column_type FROM information_schema.columns WHERE table_name = "%s"',
$table
);
if (empty($column) === false) {
$sql .= sprintf(' AND column_name="%s"', $column);
}
$result = db_process_sql($sql);
return $result;
}

View File

@ -4921,12 +4921,46 @@ function events_page_general($event)
}
/**
* Return Acknowledged by value
*
* @param integer $event_id Event_id to return Acknowledged.
*
* @return string String with user and date.
*/
function events_page_general_acknowledged($event_id)
{
global $config;
$Acknowledged = '';
$event = db_get_all_rows_filter('tevento', 'id_evento', $event_id);
if ($event) {
$user_ack = db_get_value(
'fullname',
'tusuario',
'id_user',
$config['id_user']
);
if (empty($user_ack) === true) {
$user_ack = $config['id_user'];
}
$Acknowledged = $user_ack.'&nbsp;(&nbsp;'.date($config['date_format'], $event['ack_utimestamp_raw']).'&nbsp;)&nbsp;';
} else {
$Acknowledged = 'N/A';
}
return $Acknowledged;
}
/**
* Generate 'comments' page for event viewer.
*
* @param array $event Event.
* @param boolean $ajax If the query come from AJAX.
* @param boolean $grouped If the event must shown comments grouped.
* @param array $event Event.
* @param boolean $ajax If the query come from AJAX.
* @param boolean $groupedComments If the event must shown comments grouped.
*
* @return string HTML.
*/

View File

@ -772,3 +772,292 @@ function menu_pepare_acl_select_data($pages, $sec)
return $pages;
}
if (is_ajax()) {
$about = (bool) get_parameter('about');
if ($about) {
global $config;
global $pandora_version;
global $build_version;
$product_name = io_safe_output(get_product_name());
include_once $config['homedir'].'/include/class/Diagnostics.class.php';
$d = new Diagnostics;
$db_health = json_decode($d->getDatabaseHealthStatus());
$db_info = json_decode($d->getDatabaseStatusInfo());
$db_fragmentation = json_decode($d->getTablesFragmentation());
$sys_info = json_decode($d->getSystemInfo());
$php_sys = json_decode($d->getPHPSetup());
$fragmentation_status = '';
if ($db_fragmentation->data->tablesFragmentationStatus->status === 1) {
$fragmentation_status = html_print_image(
'images/exito.png',
true,
[
'title' => __('Successfully'),
'style' => 'width:15px;',
]
);
} else {
$fragmentation_status = html_print_image(
'images/error_1.png',
true,
[
'title' => __('Error'),
'style' => 'width:15px;',
]
);
}
$dialog = '
<div id="about-tabs" class="invisible overflow-hidden">
<ul>
<li><a href="#tab-general-view">'.__('Information').'</a></li>
<li><a href="#tab-database">'.__('Database').'</a></li>
<li><a href="#tab-system-info">'.__('System Info').'</a></li>
<li><a href="#tab-php-system">'.__('PHP System').'</a></li>
<li class="ui-tabs-close-button" style="float:right!important;">
<img id="about-close" style="cursor: pointer;" src="'.ui_get_full_url('/include/styles/images/dialog-titlebar-close.png', false, false, false).'" alt="'.__('Close').'" title="'.__('Close').'" width="25px">
</li>
</ul>
<div id="tab-general-view">
<table class="table-about">
<tbody>
<tr>
<th style="width: 40%;">
<img src="'.ui_get_full_url('/images/custom_logo/'.$config['custom_logo'], false, false, false).'" alt="logo" width="70%">
</th>
<th style="width: 60%; text-align: left;">
<h1>'.$product_name.'</h1>
<p><span>'.__('Version').' '.$pandora_version.' - '.(enterprise_installed() ? 'Enterprise' : 'Community').'</span></p>
<p><span>'.__('MR version').'</span> MR'.$config['MR'].'</p>
<p><span>'.__('Build').'</span> '.$build_version.'</p>
<p style="margin-bottom: 20px!important;"><span>'.__('Support expires').'</span> 2023/04/26</p>';
if ((bool) check_acl($config['id_user'], 0, 'PM') === true) {
$dialog .= '
<div style="display: inline;">
<button class="sub" onclick="location.href=\''.ui_get_full_url('/index.php?sec=gsetup&sec2=godmode/update_manager/update_manager&tab=history', false, false, false).'\'">'.__('Update manager').'</button>
<button class="sub" onclick="location.href=\''.ui_get_full_url('/index.php?sec=gextensions&sec2=tools/diagnostics', false, false, false).'\'">'.__('System report').'</button>
</div>
';
}
$dialog .= '</th>
</tr>
</tbody>
</table>
<p class="trademark-copyright">Trademark and copyright 2004 - '.date('Y').' Pandora FMS. All rights reserved</p>
</div>
<div id="tab-database" class="div-scroll">
<table class="table-about">
<tbody style="text-align: left;">
<tr>
<th colspan="2">
<h2><span> - </span>'.__('Database health status').'</h2>
</th>
</tr>
<tr>
<th style="width: 50%;">
<p><span>'.$db_health->data->unknownAgents->name.'</span></p>
</th>
<th style="width: 50%;">
<p>'.$db_health->data->unknownAgents->value.'</p>
</th>
</tr>
<tr>
<th style="width: 50%;">
<p><span>'.$db_health->data->notInitAgents->name.'</span></p>
</th>
<th style="width: 50%;">
<p>'.$db_health->data->notInitAgents->value.'</p>
</th>
</tr>
<tr class="about-last-tr">
<th style="width: 50%;">
<p class="about-last-p"><span>'.$db_health->data->pandoraDbLastRun->name.'</span></p>
</th>
<th style="width: 50%;">
<p class="about-last-p">'.$db_health->data->pandoraDbLastRun->value.'</p>
</th>
</tr>
<tr>
<th colspan="2">
<h2><span> - </span>'.__('Database status info').'</h2>
</th>
</tr>
<tr>
<th style="width: 50%;">
<p><span>'.$db_info->data->dbSchemeFirstVersion->name.'</span></p>
</th>
<th style="width: 50%;">
<p>'.$db_info->data->dbSchemeFirstVersion->value.'</p>
</th>
</tr>
<tr>
<th style="width: 50%;">
<p><span>'.$db_info->data->dbSchemeVersion->name.'</span></p>
</th>
<th style="width: 50%;">
<p>'.$db_info->data->dbSchemeVersion->value.'</p>
</th>
</tr>
<tr>
<th style="width: 50%;">
<p><span>'.$db_info->data->dbSchemeBuild->name.'</span></p>
</th>
<th style="width: 50%;">
<p>'.$db_info->data->dbSchemeBuild->value.'</p>
</th>
</tr>
<tr class="about-last-tr">
<th style="width: 50%;">
<p class="about-last-p"><span>'.$db_info->data->dbSize->name.'</span></p>
</th>
<th style="width: 50%;">
<p class="about-last-p">'.$db_info->data->dbSize->value.'</p>
</th>
</tr>
<tr>
<th colspan="2">
<h2><span> - </span>'.__('Tables fragmentation in the %s database', $product_name).'</h2>
</th>
</tr>
<tr>
<th style="width: 50%;">
<p><span>'.$db_fragmentation->data->tablesFragmentationMax->name.'</span></p>
</th>
<th style="width: 50%;">
<p>'.$db_fragmentation->data->tablesFragmentationMax->value.'</p>
</th>
</tr>
<tr>
<th style="width: 50%;">
<p><span>'.$db_fragmentation->data->tablesFragmentationValue->name.'</span></p>
</th>
<th style="width: 50%;">
<p>'.$db_fragmentation->data->tablesFragmentationValue->value.'</p>
</th>
</tr>
<tr>
<th style="width: 50%;">
<p><span>'.$db_fragmentation->data->tablesFragmentationStatus->name.'</span></p>
</th>
<th style="width: 50%;">
<p>'.$fragmentation_status.'</p>
</th>
</tr>
</tbody>
</table>
</div>
<div id="tab-system-info">
<table class="table-about">
<tbody style="text-align: left;">
<tr>
<th colspan="2">
<h2><span> - </span>'.__('System Info').'</h2>
</th>
</tr>
<tr>
<th style="width: 15%;">
<p><span>'.$sys_info->data->cpuInfo->name.'</span></p>
</th>
<th style="width: 85%;">
<p>'.$sys_info->data->cpuInfo->value.'</p>
</th>
</tr>
<tr>
<th style="width: 15%;">
<p><span>'.$sys_info->data->ramInfo->name.'</span></p>
</th>
<th style="width: 85%;">
<p>'.$sys_info->data->ramInfo->value.'</p>
</th>
</tr>
<tr>
<th style="width: 15%;">
<p><span>'.$sys_info->data->osInfo->name.'</span></p>
</th>
<th style="width: 85%;">
<p>'.$sys_info->data->osInfo->value.'</p>
</th>
</tr>
<tr>
<th style="width: 15%;">
<p><span>'.$sys_info->data->hostnameInfo->name.'</span></p>
</th>
<th style="width: 85%;">
<p>'.$sys_info->data->hostnameInfo->value.'</p>
</th>
</tr>
<tr>
<th style="width: 15%;">
<p><span>'.$sys_info->data->ipInfo->name.'</span></p>
</th>
<th style="width: 85%;">
<p>'.$sys_info->data->ipInfo->value.'</p>
</th>
</tr>
</tbody>
</table>
</div>
<div id="tab-php-system">
<table class="table-about">
<tbody style="text-align: left;">
<tr>
<th colspan="2">
<h2><span> - </span>'.__('PHP system').'</h2>
</th>
</tr>
<tr>
<th style="width: 35%;">
<p><span>'.$php_sys->data->phpVersion->name.'</span></p>
</th>
<th style="width: 65%;">
<p>'.$php_sys->data->phpVersion->value.'</p>
</th>
</tr>
<tr>
<th style="width: 35%;">
<p><span>'.$php_sys->data->maxExecutionTime->name.'</span></p>
</th>
<th style="width: 65%;">
<p>'.$php_sys->data->maxExecutionTime->value.'</p>
</th>
</tr>
<tr>
<th style="width: 35%;">
<p><span>'.$php_sys->data->maxInputTime->name.'</span></p>
</th>
<th style="width: 65%;">
<p>'.$php_sys->data->maxInputTime->value.'</p>
</th>
</tr>
<tr>
<th style="width: 35%;">
<p><span>'.$php_sys->data->memoryLimit->name.'</span></p>
</th>
<th style="width: 65%;">
<p>'.$php_sys->data->memoryLimit->value.'</p>
</th>
</tr>
<tr>
<th style="width: 35%;">
<p><span>'.$php_sys->data->sessionLifetime->name.'</span></p>
</th>
<th style="width: 65%;">
<p>'.$php_sys->data->sessionLifetime->value.'</p>
</th>
</tr>
</tbody>
</table>
</div>
</div>
';
echo $dialog;
}
}

View File

@ -181,7 +181,7 @@ function profile_delete_profile_and_clean_users($id_profile)
* @param int User id
* @param bool Show the tags select or not
*/
function profile_print_profile_table($id, $json_profile=false, $return=false)
function profile_print_profile_table($id, $json_profile=false, $return=false, $create_user=false)
{
global $config;
@ -296,12 +296,26 @@ function profile_print_profile_table($id, $json_profile=false, $return=false)
$data['hierarchy'] = $profile['no_hierarchy'] ? __('Yes') : __('No');
$data['actions'] = '<form method="post" onsubmit="if (!confirm (\''.__('Are you sure?').'\')) return false">';
$data['actions'] .= html_print_input_image('del', 'images/cross.png', 1, ['class' => 'invert_filter'], true);
$data['actions'] .= html_print_input_hidden('delete_profile', 1, true);
$data['actions'] .= html_print_input_hidden('id_user_profile', $profile['id_up'], true);
$data['actions'] .= html_print_input_hidden('id_user', $id, true);
$data['actions'] .= '</form>';
if ($create_user) {
$data['actions'] .= html_print_input_image(
'del',
'images/cross.png',
1,
'',
true,
[
'onclick' => 'delete_profile(event, this)',
'class' => 'invert_filter',
]
);
} else {
$data['actions'] = '<form method="post" onsubmit="if (!confirm (\''.__('Are you sure?').'\')) return false">';
$data['actions'] .= html_print_input_image('del', 'images/cross.png', 1, ['class' => 'invert_filter'], true);
$data['actions'] .= html_print_input_hidden('delete_profile', 1, true);
$data['actions'] .= html_print_input_hidden('id_user_profile', $profile['id_up'], true);
$data['actions'] .= html_print_input_hidden('id_user', $id, true);
$data['actions'] .= '</form>';
}
array_push($table->data, $data);
}

View File

@ -653,18 +653,18 @@ function reporting_html_SLA($table, $item, $mini, $pdf=0)
$row[] = round($sla['sla_limit'], 2).'%';
if (reporting_sla_is_not_init_from_array($sla)) {
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.' !important; color: '.COL_NOTINIT.';">'.__('N/A').'</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.' !important; color: '.COL_NOTINIT.';">'.__('Not init').'</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_NOTINIT.';">'.__('N/A').'</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_NOTINIT.';">'.__('Not init').'</span>';
} else if (reporting_sla_is_ignored_from_array($sla)) {
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.' !important; color: '.COL_IGNORED.';">'.__('N/A').'</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.' !important; color: '.COL_IGNORED.';">'.__('No data').'</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_IGNORED.';">'.__('N/A').'</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_IGNORED.';">'.__('No data').'</span>';
// Normal calculation.
} else if ($sla['sla_status']) {
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.' !important; color: '.COL_NORMAL.';">'.sla_truncate($sla['sla_value'], $config['graph_precision']).'%</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.' !important; color: '.COL_NORMAL.';">'.__('OK').'</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_NORMAL.';">'.sla_truncate($sla['sla_value'], $config['graph_precision']).'%</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_NORMAL.';">'.__('OK').'</span>';
} else {
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.' !important; color: '.COL_CRITICAL.';">'.sla_truncate($sla['sla_value'], $config['graph_precision']).'%</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.' !important; color: '.COL_CRITICAL.';">'.__('Fail').'</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_CRITICAL.';">'.sla_truncate($sla['sla_value'], $config['graph_precision']).'%</span>';
$row[] = '<span style="font-weight: bold; font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_CRITICAL.';">'.__('Fail').'</span>';
}
// Second table for time globals.
@ -3464,10 +3464,10 @@ function reporting_html_monitor_report($table, $item, $mini, $pdf=0)
$table1->head = [];
$table1->data = [];
if ($item['data']['unknown'] == 1) {
$table1->data['data']['unknown'] = '<p class="bolder" style="font-size: '.$font_size.' !important; color: '.COL_UNKNOWN.';">';
$table1->data['data']['unknown'] = '<p class="bolder" style="font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_UNKNOWN.';">';
$table1->data['data']['unknown'] .= __('Unknown').'</p>';
} else {
$table1->data['data']['ok'] = '<p class="bolder" style="font-size: '.$font_size.' !important; color: '.COL_NORMAL.';">';
$table1->data['data']['ok'] = '<p class="bolder" style="font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_NORMAL.';">';
$table1->data['data']['ok'] .= html_print_image(
'images/module_ok.png',
true
@ -3480,7 +3480,7 @@ function reporting_html_monitor_report($table, $item, $mini, $pdf=0)
)
).' %</p>';
$table1->data['data']['fail'] = '<p class="bolder" style="font-size: '.$font_size.' !important; color: '.COL_CRITICAL.';">';
$table1->data['data']['fail'] = '<p class="bolder" style="font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.COL_CRITICAL.';">';
$table1->data['data']['fail'] .= html_print_image(
'images/module_critical.png',
true
@ -4684,7 +4684,7 @@ function reporting_html_availability_graph($table, $item, $pdf=0)
$checks_resume_text = '<span style = "font-size: '.$font_mini.';">';
$checks_resume_text .= $checks_resume;
$checks_resume_text .= '</span>';
$sla_value_text = "<span style = 'font-weight: bold; font-size: ".$font_size.' !important; color: '.$color."'>".$sla_value.'</span>';
$sla_value_text = "<span style = 'font-weight: bold; font-size: ".$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.$color."'>".$sla_value.'</span>';
switch ($item['data'][$k_chart]['failover']) {
case 'primary_compare':
$title = '<b>'.__('Primary').' (24x7)</b>';
@ -4712,7 +4712,7 @@ function reporting_html_availability_graph($table, $item, $pdf=0)
case 'result_compare':
$title = '<b>'.__('Result').' (24x7)</b>';
$sla_value_text = "<span style = 'font-weight: bold; font-size: ".$font_size.' !important; color: '.$color."'>".$sla_value.'</span>';
$sla_value_text = "<span style = 'font-weight: bold; font-size: ".$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.$color."'>".$sla_value.'</span>';
$checks_resume_text = '<span style = "font-size: '.$font_mini.';">';
$checks_resume_text .= $checks_resume;
$checks_resume_text .= '</span>';
@ -4723,7 +4723,7 @@ function reporting_html_availability_graph($table, $item, $pdf=0)
$total_values += $sla_value;
$count_total_charts++;
$title = '<b>'.__('Result').'</b>';
$sla_value_text = "<span style = 'font-weight: bold; font-size: ".$font_size.' !important; color: '.$color."'>".$sla_value.'</span>';
$sla_value_text = "<span style = 'font-weight: bold; font-size: ".$font_size.(($pdf === 0) ? ' !important' : '').'; color: '.$color."'>".$sla_value.'</span>';
$checks_resume_text = '<span style = "font-size: '.$font_mini.';">';
$checks_resume_text .= $checks_resume;
$checks_resume_text .= '</span>';
@ -4757,7 +4757,7 @@ function reporting_html_availability_graph($table, $item, $pdf=0)
$table_summary->data = [];
$table_summary->data[0][0] = '<b>'.__('Summary').'</b>';
$table_summary->data[0][1] = '<span style = "font-weight: bold; font-size: '.$font_size.' !important;">';
$table_summary->data[0][1] = '<span style = "font-weight: bold; font-size: '.$font_size.(($pdf === 0) ? ' !important' : '').';">';
$table_summary->data[0][1] .= sla_truncate($total_values / $count_total_charts);
$table_summary->data[0][1] .= ' %';
$table_summary->data[0][1] .= '</span>';

View File

@ -2241,3 +2241,58 @@ var formatterDataVerticalBar = function(value, ctx) {
return percentage;
}
};
// Show about section
$(document).ready(function() {
$("#icon_about").click(function() {
$("#icon_about").addClass("selected");
jQuery.post(
"ajax.php",
{
page: "include/functions_menu",
about: "true"
},
function(data) {
$("div.ui-dialog").remove();
$("#about-div").html("");
if (data) {
$("#about-div").html(data);
openAbout();
}
},
"html"
);
});
function openAbout() {
$("#about-tabs").dialog({
// title: "About",
resizable: false,
draggable: false,
modal: true,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
closeOnEscape: true,
width: 700,
height: 450,
create: function() {
$("#about-tabs").tabs({});
$(".ui-dialog-titlebar").remove();
$("#about-close").click(function() {
$("#about-tabs").dialog("close");
$("div.ui-dialog").remove();
$("#icon_about").removeClass("selected");
});
}
});
}
});

View File

@ -339,6 +339,19 @@ function event_change_status(event_ids, server_id) {
// if (typeof dt_events !== "undefined") {
// dt_events.draw(false);
// }
$.ajax({
type: "POST",
url: "ajax.php",
data: {
page: "include/ajax/events",
get_Acknowledged: 1,
event_id: event_ids
},
success: function(response) {
$("#table4-9-1").html(response);
}
});
$("#table_events")
.DataTable()
.draw(false);

View File

@ -388,12 +388,11 @@ function recalculate_events(calendar, newEvent, from, to, create) {
}
});
var title = "";
if (time_format(from) === "00:00:00" && time_format(to) === "00:00:00") {
title = "All day";
}
if (create === true) {
var title = "";
if (time_format(from) === "00:00:00" && time_format(to) === "00:00:00") {
title = "All day";
}
calendar.addEvent({
title: title,
start: from,
@ -401,6 +400,12 @@ function recalculate_events(calendar, newEvent, from, to, create) {
id: uniqId()
});
} else {
if (!$.isEmptyObject(newEvent)) {
newEvent._def.title = "";
if (time_format(from) === "00:00:00" && time_format(to) === "00:00:00") {
newEvent._def.title = "All day";
}
}
// Update event.
newEvent.setDates(from, to);
}

View File

@ -82,7 +82,8 @@ if ($doLogin === true) {
} else {
db_pandora_audit(
AUDIT_LOG_ACL_VIOLATION,
'Trying to login using invalid credentials'
'Trying to login using invalid credentials with API Rest',
$id_user
);
http_response_code(403);
return;

View File

@ -553,6 +553,4 @@ final class Container extends Model
return $item;
}
}

View File

@ -209,6 +209,7 @@ class Item extends CachedModel
'x' => static::extractX($data),
'y' => static::extractY($data),
'cacheExpiration' => static::extractCacheExpiration($data),
'alertOutline' => static::checkLayoutAlertsRecursive($data),
];
if (static::$useLinkedModule === true) {
@ -2619,4 +2620,108 @@ class Item extends CachedModel
}
/**
* Recursively check for alerts in a Visual Console item and its linked layout.
*
* @param array $item The Visual Console item to check for alerts.
* @param array $visitedLayouts A list of layouts that have already been visited to avoid circular references.
*
* @return boolean True if an alert has been found, false otherwise.
*/
public static function checkLayoutAlertsRecursive(array $item, array $visitedLayouts=[])
{
if (isset($item['type']) === true) {
$excludedItemTypes = [
22,
17,
18,
1,
23,
15,
14,
10,
4,
];
if (in_array($item['type'], $excludedItemTypes) === true) {
return false;
}
}
$agentID = (int) $item['id_agent'];
$agentModuleID = (int) $item['id_agente_modulo'];
$linkedLayoutID = (int) $item['id_layout_linked'];
$metaconsoleID = (int) $item['id_metaconsole'];
$visitedLayouts[] = $item['id_layout'];
if ($agentModuleID !== 0 && $agentID !== 0) {
$alerts_sql = sprintf(
'SELECT talert_template_modules.id
FROM talert_template_modules
INNER JOIN tagente_modulo t2
ON talert_template_modules.id_agent_module = t2.id_agente_modulo
INNER JOIN tagente t3
ON t2.id_agente = t3.id_agente AND t3.id_agente = %d
INNER JOIN talert_templates t4
ON talert_template_modules.id_alert_template = t4.id
WHERE `id_agent_module` = %d AND talert_template_modules.times_fired > 0',
$agentID,
$agentModuleID
);
// Connect to node.
if (\is_metaconsole() === true
&& \metaconsole_connect(null, $metaconsoleID) !== NOERR
) {
throw new \InvalidArgumentException(
'error connecting to the node'
);
}
$firedAlert = db_get_sql($alerts_sql);
// Restore connection.
if (\is_metaconsole() === true) {
\metaconsole_restore_db();
}
// Item has a triggered alert.
if ($firedAlert !== false) {
return true;
}
}
if ($linkedLayoutID === 0 || in_array($linkedLayoutID, $visitedLayouts) === true) {
// Item has no linked layout or it has already been visited (avoid infinite loop caused by circular references).
return false;
}
$filter = ['id_layout' => $linkedLayoutID];
$linkedLayoutItems = \db_get_all_rows_filter(
'tlayout_data',
$filter,
[
'id_layout',
'id_agent',
'id_agente_modulo',
'id_layout_linked',
'id_metaconsole',
]
);
if ($linkedLayoutItems === false) {
// There are no items in the linked visual console. Nothing to check.
return false;
}
foreach ($linkedLayoutItems as $linkedLayoutItem) {
if (self::checkLayoutAlertsRecursive($linkedLayoutItem, $visitedLayouts)) {
return true;
}
}
return false;
}
}

View File

@ -186,6 +186,11 @@ final class EventsHistory extends Item
*/
protected static function buildLink(array $data)
{
$link = parent::buildLink($data);
if ($link !== null) {
return $link;
}
// Get the linked agent and module Ids.
$linkedModule = static::extractLinkedModule($data);
$agentId = static::parseIntOr($linkedModule['agentId'], null);

View File

@ -212,6 +212,9 @@ li.sub_subMenu.selected {
#icon_god-module_library {
background-image: url(../../images/menu/gm_library.menu_gray.png);
}
#icon_about {
background-image: url(../../images/menu/about.menu_gray.png);
}
#menu_container {
z-index: 3;
@ -375,6 +378,9 @@ ul li {
.selected#icon_god-module_library {
background-image: url(../../images/menu/gm_library.menu_white.png);
}
.selected#icon_about {
background-image: url(../../images/menu/about.menu_white.png);
}
#menu_full {
height: 100%;

View File

@ -9169,3 +9169,117 @@ div#err_msg_centralised {
justify-content: start;
padding-left: 10px;
}
/* Table about dialog */
.table-about {
background-color: white !important;
width: 100%;
border-collapse: collapse;
}
.table-about th {
background-color: white !important;
width: 100%;
}
.table-about h1 {
text-transform: none !important;
font-size: 28px !important;
color: #454545;
margin-top: 34px;
margin-left: 9px;
}
.table-about h2 {
text-transform: none !important;
font-size: 15px !important;
margin-bottom: 5px;
margin-left: 9px;
color: #14524f;
}
.table-about h2 span {
color: #14524f;
font-size: large;
font-weight: bolder;
}
.table-about p {
color: #454545;
font-size: 15px;
font-weight: normal;
margin: 7px;
margin-left: 9px;
}
.table-about p span {
color: #454545;
font-size: 15px;
font-weight: bold;
margin: 9px;
margin-left: 0px;
}
.table-about p.about-last-p {
padding-bottom: 17px;
}
.table-about .about-last-tr {
border-bottom: 1px solid #eaeaea;
}
.about-copyright-div {
width: 100%;
height: 100%;
}
p.trademark-copyright {
width: 90%;
color: #8a96a6;
font-size: 13px;
margin-top: 20px;
margin-bottom: 0px;
text-align: center !important;
position: absolute;
bottom: 0;
}
#about-tabs,
#tab-general-view {
padding-bottom: 0px;
margin-bottom: 0px;
}
#about-tabs {
overflow: hidden;
}
#tab-database {
height: 80%;
overflow: auto;
}
form#satellite_conf_edit {
display: flex;
flex-direction: row;
justify-items: baseline;
justify-content: space-between;
flex-wrap: wrap;
}
form#satellite_conf_edit > fieldset {
background-color: #fff;
// border: 1px solid #e2e2e2;
padding: 0.5em;
margin: 0px 1em;
margin-bottom: 20px;
position: relative;
border-radius: 5px;
flex: 1 1 700px;
}
form#satellite_conf_edit > fieldset.full-column {
width: 100%;
flex: none;
margin: 0 0 20px;
}

View File

@ -74,6 +74,10 @@
}
}
.visual-console-item.is-alert-triggered {
border: 3px solid #f36201;
}
.visual-console-spinner {
background-color: transparent;
margin: 0px auto;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -227,6 +227,9 @@ ob_start('ui_process_page_head');
// Enterprise main.
enterprise_include_once('index.php');
// Load event.css to display the about section dialog with correct styles.
echo '<link rel="stylesheet" href="'.ui_get_full_url('/include/styles/events.css', false, false, false).'" type="text/css" />';
echo '<script type="text/javascript">';
echo 'var dispositivo = navigator.userAgent.toLowerCase();';
echo 'if( dispositivo.search(/iphone|ipod|ipad|android/) > -1 ){';
@ -1472,9 +1475,6 @@ if ($config['pure'] == 0) {
echo '</div>';
echo '<div id="both"></div>';
echo '</div>';
echo '<div id="foot">';
include 'general/footer.php';
}
// Clippy function.
@ -1537,29 +1537,6 @@ require 'include/php_to_js_values.php';
}, 500);
}
// Initial load of page.
$(document).ready(adjustFooter);
// Every resize of window.
$(window).resize(adjustFooter);
// Every show/hide call may need footer re-layout.
(function() {
var oShow = jQuery.fn.show;
var oHide = jQuery.fn.hide;
jQuery.fn.show = function () {
var rv = oShow.apply(this, arguments);
adjustFooter();
return rv;
};
jQuery.fn.hide = function() {
var rv = oHide.apply(this, arguments);
adjustFooter();
return rv;
};
})();
function first_time_identification() {
jQuery.post("ajax.php", {
"page": "general/register",
@ -1645,31 +1622,6 @@ require 'include/php_to_js_values.php';
"html"
);
}
//Dynamically assign footer position and width.
function adjustFooter() {
/*
if (document.readyState !== 'complete' || $('#container').position() == undefined) {
return;
}
// minimum top value (upper limit) for div#foot
var ulim = $('#container').position().top + $('#container').outerHeight(true);
// window height. $(window).height() returns wrong value on Opera and Google Chrome.
var wh = document.documentElement.clientHeight;
// save div#foot's height for latter use
var h = $('#foot').height();
// new top value for div#foot
var t = (ulim + $('#foot').outerHeight() > wh) ? ulim : wh - $('#foot').outerHeight();
/*
if ($('#foot').position().top != t) {
$('#foot').css({ position: "absolute", top: t, left: $('#foot').offset().left});
$('#foot').height(h);
}
if ($('#foot').width() != $(window).width()) {
$('#foot').width($(window).width());
}
*/
}
</script>
<?php
if (__PAN_XHPROF__ === 1) {

View File

@ -129,7 +129,7 @@
<div style='height: 10px'>
<?php
$version = '7.0NG.767';
$build = '221228';
$build = '230113';
$banner = "v$version Build $build";
error_reporting(0);

View File

@ -227,245 +227,252 @@ if ($free_search != '') {
$url .= '&free_search='.$free_search;
}
$columns = ['standby'];
$column_names = [
[
'title' => 'Standby',
'text' => 'S.',
],
];
$columns = ['standby'];
if (enterprise_installed() === true) {
array_unshift(
$column_names,
[
'title' => 'Policy',
'text' => 'P.',
]
);
$column_names = [
$columns = array_merge(
['policy'],
$columns
);
}
if (is_metaconsole() === false) {
if (check_acl($config['id_user'], $id_group, 'LW') || check_acl($config['id_user'], $id_group, 'LM')) {
array_unshift(
$column_names,
[
'title' => 'Standby',
'text' => 'S.',
],
];
'title' => 'Validate',
'text' => html_print_checkbox('all_validate', 0, false, true, false),
'class' => 'dt-left',
]
);
if ($isFunctionPolicies !== ENTERPRISE_NOT_HOOK) {
array_unshift(
$column_names,
[
'title' => 'Policy',
'text' => 'P.',
]
);
$columns = array_merge(
['policy'],
$columns
);
}
if (is_metaconsole() === false) {
if (check_acl($config['id_user'], $id_group, 'LW') || check_acl($config['id_user'], $id_group, 'LM')) {
array_unshift(
$column_names,
[
'title' => 'Validate',
'text' => html_print_checkbox('all_validate', 0, false, true, false),
'class' => 'dt-left',
]
);
$columns = array_merge(
['validate'],
$columns
);
}
if (check_acl($config['id_user'], $id_group, 'AW') || check_acl($config['id_user'], $id_group, 'LM')) {
array_push(
$column_names,
[
'title' => 'Force execution',
'text' => 'F.',
]
);
$columns = array_merge(
$columns,
['force']
);
}
}
if ($print_agent === true) {
array_push(
$column_names,
['text' => 'Agent']
);
$columns = array_merge(
$columns,
['agent_name']
);
}
$columns = array_merge(
['validate'],
$columns
);
}
if (check_acl($config['id_user'], $id_group, 'AW') || check_acl($config['id_user'], $id_group, 'LM')) {
array_push(
$column_names,
['text' => 'Module'],
['text' => 'Template'],
['text' => 'Action'],
['text' => 'Last fired'],
['text' => 'Status']
[
'title' => 'Force execution',
'text' => 'F.',
]
);
$columns = array_merge(
$columns,
['agent_module_name'],
['template_name'],
['action'],
['last_fired'],
['status']
['force']
);
}
}
if ($print_agent === true) {
array_push(
$column_names,
['text' => 'Agent']
);
$columns = array_merge(
$columns,
['agent_name']
);
}
array_push(
$column_names,
['text' => 'Module'],
['text' => 'Template'],
['text' => 'Action'],
['text' => 'Last fired'],
['text' => 'Status']
);
$columns = array_merge(
$columns,
['agent_module_name'],
['template_name'],
['action'],
['last_fired'],
['status']
);
if (is_metaconsole() === true) {
$no_sortable_columns = [
0,
1,
5,
];
} else {
$no_sortable_columns = [
0,
1,
2,
3,
7,
];
}
if (is_metaconsole() === true) {
$no_sortable_columns = [
0,
1,
5,
];
} else {
if (enterprise_installed() === true) {
$no_sortable_columns = [
0,
1,
2,
3,
7,
];
} else {
$no_sortable_columns = [
0,
1,
2,
6,
];
}
}
$alert_action = empty(alerts_get_alert_actions_filter()) === false
? alerts_get_alert_actions_filter()
: ['' => __('No actions')];
$alert_action = empty(alerts_get_alert_actions_filter()) === false
? alerts_get_alert_actions_filter()
: ['' => __('No actions')];
ob_start();
ob_start();
if ($agent_view_page === true) {
ui_print_datatable(
[
'id' => 'alerts_status_datatable',
'class' => 'info_table',
'style' => 'width: 100%',
'columns' => $columns,
'column_names' => $column_names,
'no_sortable_columns' => $no_sortable_columns,
'ajax_url' => 'include/ajax/alert_list.ajax',
'ajax_data' => [
'get_agent_alerts_datatable' => 1,
'id_agent' => $idAgent,
'url' => $url,
'agent_view_page' => true,
'all_groups' => $all_groups,
],
'drawCallback' => 'alerts_table_controls()',
'order' => [
'field' => 'agent_module_name',
'direction' => 'asc',
],
'zeroRecords' => __('No alerts found'),
'emptyTable' => __('No alerts found'),
'search_button_class' => 'sub filter float-right',
'form' => [
'inputs' => [
[
'label' => __('Free text for search (*):').ui_print_help_tip(
__('Filter by module name, template name or action name'),
true
),
'type' => 'text',
'name' => 'free_search_alert',
'value' => $free_search,
'size' => 20,
'maxlength' => 100,
],
],
'no_toggle' => true,
],
]
);
} else {
ui_print_datatable(
[
'id' => 'alerts_status_datatable',
'class' => 'info_table',
'style' => 'width: 100%',
'columns' => $columns,
'column_names' => $column_names,
'no_sortable_columns' => $no_sortable_columns,
'ajax_url' => 'include/ajax/alert_list.ajax',
'ajax_data' => [
'get_agent_alerts_datatable' => 1,
'id_agent' => $idAgent,
'url' => $url,
],
'drawCallback' => 'alerts_table_controls()',
'order' => [
'field' => 'agent_module_name',
'direction' => 'asc',
],
'zeroRecords' => __('No alerts found'),
'emptyTable' => __('No alerts found'),
'search_button_class' => 'sub filter float-right',
'form' => [
'html' => printFormFilterAlert(
$id_group,
$filter,
$free_search,
$url,
$filter_standby,
$tag_filter,
true,
true,
$strict_user
if ($agent_view_page === true) {
ui_print_datatable(
[
'id' => 'alerts_status_datatable',
'class' => 'info_table',
'style' => 'width: 100%',
'columns' => $columns,
'column_names' => $column_names,
'no_sortable_columns' => $no_sortable_columns,
'ajax_url' => 'include/ajax/alert_list.ajax',
'ajax_data' => [
'get_agent_alerts_datatable' => 1,
'id_agent' => $idAgent,
'url' => $url,
'agent_view_page' => true,
'all_groups' => $all_groups,
],
'drawCallback' => 'alerts_table_controls()',
'order' => [
'field' => 'agent_module_name',
'direction' => 'asc',
],
'zeroRecords' => __('No alerts found'),
'emptyTable' => __('No alerts found'),
'search_button_class' => 'sub filter float-right',
'form' => [
'inputs' => [
[
'label' => __('Free text for search (*):').ui_print_help_tip(
__('Filter by module name, template name or action name'),
true
),
'type' => 'text',
'name' => 'free_search_alert',
'value' => $free_search,
'size' => 20,
'maxlength' => 100,
],
]
);
}
],
'no_toggle' => true,
],
]
);
} else {
ui_print_datatable(
[
'id' => 'alerts_status_datatable',
'class' => 'info_table',
'style' => 'width: 100%',
'columns' => $columns,
'column_names' => $column_names,
'no_sortable_columns' => $no_sortable_columns,
'ajax_url' => 'include/ajax/alert_list.ajax',
'ajax_data' => [
'get_agent_alerts_datatable' => 1,
'id_agent' => $idAgent,
'url' => $url,
],
'drawCallback' => 'alerts_table_controls()',
'order' => [
'field' => 'agent_module_name',
'direction' => 'asc',
],
'zeroRecords' => __('No alerts found'),
'emptyTable' => __('No alerts found'),
'search_button_class' => 'sub filter float-right',
'form' => [
'html' => printFormFilterAlert(
$id_group,
$filter,
$free_search,
$url,
$filter_standby,
$tag_filter,
true,
true,
$strict_user
),
],
]
);
}
if (!is_metaconsole()) {
if (check_acl($config['id_user'], $id_group, 'AW') || check_acl($config['id_user'], $id_group, 'LM')) {
echo '<div class="action-buttons" style="width: '.$table->width.';">';
html_print_submit_button(__('Validate'), 'alert_validate', false, 'class="sub ok"', false);
echo '</div>';
}
}
$html_content = ob_get_clean();
if ($agent_view_page === true) {
// Create controlled toggle content.
ui_toggle(
$html_content,
__('Full list of alerts'),
'status_monitor_agent',
!$alerts_defined,
false,
'',
'white_table_graph_content no-padding-imp',
'white_table_graph_content'
);
} else {
// Dump entire content.
echo $html_content;
}
// Strict user hidden.
echo '<div id="strict_hidden" class="invisible">';
html_print_input_text('strict_user_hidden', $strict_user);
html_print_input_text('is_meta_hidden', (int) is_metaconsole());
if (!is_metaconsole()) {
if (check_acl($config['id_user'], $id_group, 'AW') || check_acl($config['id_user'], $id_group, 'LM')) {
echo '<div class="action-buttons" style="width: '.$table->width.';">';
html_print_submit_button(__('Validate'), 'alert_validate', false, 'class="sub ok"', false);
echo '</div>';
enterprise_hook('close_meta_frame');
}
}
ui_require_css_file('cluetip', 'include/styles/js/');
ui_require_jquery_file('cluetip');
?>
$html_content = ob_get_clean();
if ($agent_view_page === true) {
// Create controlled toggle content.
ui_toggle(
$html_content,
__('Full list of alerts'),
'status_monitor_agent',
!$alerts_defined,
false,
'',
'white_table_graph_content no-padding-imp',
'white_table_graph_content'
);
} else {
// Dump entire content.
echo $html_content;
}
// Strict user hidden.
echo '<div id="strict_hidden" class="invisible">';
html_print_input_text('strict_user_hidden', $strict_user);
html_print_input_text('is_meta_hidden', (int) is_metaconsole());
echo '</div>';
enterprise_hook('close_meta_frame');
ui_require_css_file('cluetip', 'include/styles/js/');
ui_require_jquery_file('cluetip');
?>
<script type="text/javascript">

View File

@ -537,7 +537,7 @@ function print_form_filter_monitors(
);
$table->data[0][2] = __('Free text for search (*):').ui_print_help_tip(
__('Search by module name, list matches.'),
__('Search by module name or alert name, list matches.'),
true
);

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_console
%define version 7.0NG.767
%define release 221228
%define release 230113
# User and Group under which Apache is running
%define httpd_name httpd

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_console
%define version 7.0NG.767
%define release 221228
%define release 230113
# User and Group under which Apache is running
%define httpd_name httpd

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_console
%define version 7.0NG.767
%define release 221228
%define release 230113
%define httpd_name httpd
# User and Group under which Apache is running
%define httpd_name apache2

View File

@ -16,9 +16,35 @@ if ($issues) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
} elseif (!headers_sent()) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
require_once __DIR__.'/../../include/functions_ui.php';
$url = str_replace('/var/www/html/', '', __DIR__);
$url = str_replace('/vendor/composer', '', $url);
echo '<link rel="stylesheet" type="text/css" href="include/styles/pandora.css">';
?>
<style>
body {
display: block;
}
</style>
<?php
echo '<div style="height:100%;min-height: 100%;display:flex;align-items:center;justify-content:center;background: linear-gradient(74deg, #02020255 36%, transparent 36%), url('.$url.'/../images/backgrounds/background_pandora_console_keys.jpg);">';
echo '<center><div align="middle" class="license_databox w600px pdd_10px" style="background-color: white;">';
echo '<img style="width: 600px" src="images/custom_logo/logo-default-pandorafms.png"><h2> Composer detected issues in your platform:</h2>';
echo '<div class="w90p height_100px" style="text-align:left;font-size: larger">';
echo sprintf(
'PandoraFMS requires PHP 8.0 to work properly and the version %s has been detected. Please update the PHP version of the system. More info %s. The latest version with PHP 7.4 support is PandoraFMS 767 hope LTS.',
PHP_VERSION,
'<a style="font-size: initial;" target="_blank" href="https://pandorafms.com/manual/en/documentation/07_technical_annexes/18_php_8">here</a>'
);
echo '</div></div></center></div>';
}
}
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR

View File

@ -0,0 +1,19 @@
# name for the agent
agent_name=snmp_remote
# configuration (1 for activate modules)
memuse=1
diskuse=1
cpuload=1
process=1
# number of proces to monitoring, each one create a module
numberprocess=3
# name for each process
process1=dhcp
process2=dockerd
process3=docker-proxy
# transfer configuration
mode=tentacle
tentacle_ip=
tentacle_port=41121
#define
as_server_plugin=1

View File

@ -0,0 +1,388 @@
#!/usr/bin/perl
#-----------------------------------------------------------------------
# SNMP remote plugin
# Depending on the configuration returns the result of these modules:
# - % Memory Use
# - % CPU Use
# - % Disk Use
# - Show if a process is running or not
#
# Artica ST
# Copyright (C) 2013 mario.pulido@artica.es
#
# License: GPLv2+
#-----------------------------------------------------------------------
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# GPL License: http://www.gnu.org/licenses/gpl.txt
#-----------------------------------------------------------------------
# Revised by Kevin Rojas 2020 kevin.rojas@pandorafms.com
# - Added check for Module options
# - Optimized SNMP v3 code
# - Improved Help
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# Revised by Kevin Rojas 2023 alejandro.sanchez@pandorafms.com
# - Added plugin tools options like tentacle
# - Added file conf for configuration
# - added option for monitoring more than 1 process in the same execution
#-----------------------------------------------------------------------
use strict;
use Getopt::Std;
my $VERSION = 'v1r3';
#------------------------------
use File::Basename;
my $dirname;
BEGIN { $dirname = dirname(__FILE__);}
use lib $dirname;
use PandoraFMS::PluginTools;
# Variables del conf
my $config;
$config = read_configuration($config);
my $agent_name=$config->{'agent_name'};
my $mode=$config->{'mode'};
my $tentacle_ip=$config->{'tentacle_ip'};
my $tentacle_port=$config->{'tentacle_port'};
my $memuseconf=$config->{'memuse'};
my $diskuseconf=$config->{'diskuse'};
my $cpuloadconf=$config->{'cpuload'};
my $processconf=$config->{'process'};
my $numberprocess=$config->{'numberprocess'};
my @modules;
my $module_group = $config->{'module_group'};
my $valid_conf = 1;
my $as_server_plugin = $config->{'as_server_plugin'};
if ($config->{'mode'} eq "tentacle" && !$config->{'tentacle_ip'}){
print "ERROR: [transfer_mode] set to [tentacle], but no [tentacle_ip] provided.\n";
$valid_conf = 0;
}
#----------------------------------
#-----------------------------------------------------------------------
# HELP
#-----------------------------------------------------------------------
if ($#ARGV == -1 ) {
print "SNMP remote plugin ($VERSION). Retrieves information via SNMP for:\n";
print "\t- Memory Usage (%)\n";
print "\t- CPU Usage (%)\n";
print "\t- Disk Usage (%)\n";
print "\t- Whether a process is running (1) or not (0)\n";
print "\n";
print "Arguments:\n\n";
print "-H, --host=STRING\n";
print "\tHost IP\n";
print "-c, --community=STRING\n";
print "\tSNMP Community\n";
print "-m, --module=STRING\n";
print "\tDefine module (memuse|diskuse|process|cpuload) \n";
print "-d, --disk=STRING\n";
print "\t[Only for diskuse module] Define disk name (C:, D: in Windows) or mount point (Linux). Default: /\n";
print "-p, --process=STRING\n";
print "\t[Only for process module] Process or service name\n\n";
print "SNMP v3 options:\n";
print "\n";
print "-v, --version=STRING\n";
print "\tSNMP version (Default 2c)\n";
print "-u, --user=STRING\n";
print "\tAuth user\n";
print "-l, --level=STRING\n";
print "\tSecurity level\n";
print "-a STRING\n";
print "\tAuth method\n";
print "-A, --auth=STRING\n";
print "\tAuth pass\n";
print "-x STRING\n";
print "\tPrivacy method\n";
print "-X STRING\n";
print "\tPrivacy pass\n";
print "\n";
print "Usage: \n";
print "SNMP v1|2|2c:\n" ;
print "\tperl $0 -H host -c community -m (memuse|diskuse|process|cpuload) [-p process -d disk] \n" ;
print "SNMP v3:\n" ;
print "\tperl $0 -H host -v 3 -u user -l seclevel -a authMethod -A authPass -x privMethod -X privPass -m (memuse|diskuse|process|cpuload) [-p process -d disk] \n" ;
print "\n" ;
exit;
}
my (
$host, # $opts{"H"}
$community, # $opts{"c"}
$disk, # $opts{"d"}
$version, # $opts{"v"}
$user, # $opts{"u"}
$pass, # $opts{"A"}
$security_level, # $opts{"l"}
$auth_method, # $opts{"a"}
$privacy_method, # $opts{"x"}
$privacy_pass # $opts{"X"}
) = &options;
#-----------------------------------------------------------------------
# OPTIONS
#-----------------------------------------------------------------------
sub options {
# Get and check args
my %opts;
getopt( 'HcmdpvuAlaxX', \%opts );
#~ ' -u ' . $snmp3_auth_user .
#~ ' -A ' . $snmp3_auth_pass .
#~ ' -l ' . $snmp3_security_level .
#~ ' -a ' . $snmp3_auth_method .
#~ ' -x ' . $snmp3_privacy_method .
#~ ' -X' $snmp3_privacy_pass;
# host
$opts{"H"} = 0 unless ( exists( $opts{"H"} ) );
# community
$opts{"c"} = 0 unless ( exists( $opts{"c"} ) );
# module
$opts{"m"} = 0 unless ( exists( $opts{"m"} ) );
# disk
$opts{"d"} = "/" unless ( exists( $opts{"d"} ) );
# process
$opts{"p"} = 0 unless ( exists( $opts{"p"} ) );
# version
$opts{"v"} = "2c" unless ( exists( $opts{"v"} ) );
# user
$opts{"u"} = "" unless ( exists( $opts{"u"} ) );
# auth_pass
$opts{"A"} = "" unless ( exists( $opts{"A"} ) );
# security level
$opts{"l"} = "noAuthNoPriv" unless ( exists( $opts{"l"} ) );
# auth method
$opts{"a"} = "" unless ( exists( $opts{"a"} ) );
# privacy method
$opts{"x"} = "" unless ( exists( $opts{"x"} ) );
# privacy pass
$opts{"X"} = "" unless ( exists( $opts{"X"} ) );
return (
$opts{"H"},
$opts{"c"},
$opts{"d"},
$opts{"v"},
$opts{"u"},
$opts{"A"},
$opts{"l"},
$opts{"a"},
$opts{"x"},
$opts{"X"});
}
# unless ( $module ~~ ["memuse","cpuload","process","diskuse"] ){
# print "Error: Invalid or missing argument (-m).\n";
# print "Available options: memuse | diskuse | process | cpuload \n\n";
# exit;
# }
unless ($host){
print "Error: missing host address.\n";
exit;
}
#-----------------------------------------------------------------------
# SNMP Version parameters
#-----------------------------------------------------------------------
my $command_line_parameters;
if ($version == "3") {
if (lc($security_level) eq lc('authNoPriv')) {
$command_line_parameters = "-v $version -u $user -a $auth_method -A '$pass' -l $security_level $host";
}
elsif (lc($security_level) eq lc("AuthPriv")) {
$command_line_parameters = "-v $version -u $user -a $auth_method -A '$pass' -l $security_level -x $privacy_method -X '$privacy_pass' $host";
}
else {
$command_line_parameters = "-v $version -u $user -l $security_level $host";
}
}
else {
$command_line_parameters = "-v $version -c $community $host";
}
#-----------------------------------------------------------------------
# Memory use % module
#-----------------------------------------------------------------------
if($memuseconf==1){
my $memuse = 0;
my $memid = `snmpwalk -On $command_line_parameters .1.3.6.1.2.1.25.2.3.1.3 | grep Physical | head -1 | gawk '{print \$1}' | gawk -F "." '{print \$13}' | tr -d "\r"`;
my @memtot = split(/\s/, `snmpget $command_line_parameters .1.3.6.1.2.1.25.2.3.1.5.$memid `) ;
my @memfree = split(/\s/, `snmpget $command_line_parameters .1.3.6.1.2.1.25.2.3.1.6.$memid `) ;
if ($memid){
$memuse = ($memfree[-1]) * 100 / $memtot[-1];
#printf("%.2f", $memuse);
push @modules, {
'name' => "Total RAM used (%)",
'type' => "generic_data",
'value' => $memuse,
'desc' => "Memory use % module",
'unit' => "%",
'module_group' => $module_group
};
}
else {
print STDOUT "-1";
print STDERR "Error: Memory OID not found";
}
}
#-----------------------------------------------------------------------
# Disk use % module
#-----------------------------------------------------------------------
if($diskuseconf==1){
my $diskuse = 0;
unless ($disk){
print "Error: Invalid or missing argument (-d).\n";
exit;
}
if ($disk =~ /\\ /) {
$disk =~ s/\\/\\\\/g;
}
my $diskid = `snmpwalk -r 2 -On $command_line_parameters .1.3.6.1.2.1.25.2.3.1.3 | grep -F '$disk' | head -1 | gawk '{print \$1}' | gawk -F "." '{print \$13}' | tr -d "\r"`;
my @disktot= split /\s/, `snmpget -r 2 $command_line_parameters .1.3.6.1.2.1.25.2.3.1.5.$diskid` ;
if ($diskid == ""){
print STDOUT "-1";
print STDERR "Error: Disk or partition not found\n";
exit;
}
if ($disktot[-1] == 0) {
$diskuse = 0;
}
else {
my @diskfree = split (/\s/, `snmpget -r 2 $command_line_parameters .1.3.6.1.2.1.25.2.3.1.6.$diskid`) ;
$diskuse = ($disktot[-1] - $diskfree[-1]) * 100 / $disktot[-1];
}
#printf("%.2f", $diskuse);
push @modules, {
'name' => "Storage Physical (%)",
'type' => "generic_data",
'value' => $diskuse,
'desc' => "Disk use % module",
'unit' => "%",
'module_group' => $module_group
};
}
#-----------------------------------------------------------------------
# Process Status module
#-----------------------------------------------------------------------
if($processconf==1){
my $i;
my $count=0;
my $status = 0;
$status = `snmpwalk $command_line_parameters .1.3.6.1.2.1.25.4.2.1.2 2>/dev/null`;
for ($i=0;$i<$numberprocess;$i++){
$count=$count+1;
my $processname =$config->{'process'. $count};
if ($? == 0) {
push @modules, {
'name' => 'Process "'.$processname.'"',
'type' => "generic_proc",
'value' => ($status =~ m/$processname/mi)?1:0,
'desc' => "Process Status module",
'module_group' => $module_group
};
}
#print (($status =~ m/$process/mi)?1:0);
}
}
#-----------------------------------------------------------------------
# CPU Load % module
#-----------------------------------------------------------------------
if($cpuloadconf==1){
my $cputotal = 0;
my $cpuload = `snmpwalk $command_line_parameters .1.3.6.1.2.1.25.3.3.1.2 | gawk '{print \$4}' `;
my @cpuload = split(/\n/, $cpuload);
my $sum;
my $counter = 0;
foreach my $val(@cpuload) {
$sum = $sum + $val;
$counter++;
}
$cputotal = $sum/$counter;
push @modules, {
'name' => "CPU Load (%)",
'type' => "generic_data",
'value' =>$cputotal,
'desc' => "CPU Load % module",
'unit' => "%",
'module_group' => $module_group
};
#print $cputotal;
}
my $xml = print_agent($config, {
'agent_name' => $agent_name
}, \@modules);
if (!transfer_xml($config, $xml)){
if ($as_server_plugin != 1){
print_module ($config, {
name => "snmp_remote",
type => "generic_proc",
desc => "",
value => 0,
});
}
exit 0;
}
#print $xml;

View File

@ -1,5 +1,5 @@
package: pandorafms-server
Version: 7.0NG.767-221228
Version: 7.0NG.767-230113
Architecture: all
Priority: optional
Section: admin

View File

@ -14,7 +14,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
pandora_version="7.0NG.767-221228"
pandora_version="7.0NG.767-230113"
package_cpan=0
package_pandora=1

View File

@ -348,15 +348,6 @@ self_monitoring 1
# Self monitoring interval (in seconds).
self_monitoring_interval 300
# Pandora Sample Agent. If enabled, every 10 minutes, this embedded agent
# will make sample data. Disabled by default.
sample_agent 0
# Pandora Sample Agent interval (in seconds).
sample_agent_interval 600
# Update parent from the agent xml
#update_parent 1

View File

@ -340,15 +340,6 @@ restart_delay 60
self_monitoring 1
# Pandora Sample Agent. If enabled, every 10 minutes, this embedded agent
# will make sample data. Disabled by default.
sample_agent 0
# Pandora Sample Agent interval (in seconds).
sample_agent_interval 600
# Update parent from the agent xml
#update_parent 1

View File

@ -404,30 +404,33 @@ sub pandora_server_tasks ($) {
# Update forced alerts
pandora_exec_forced_alerts ($pa_config, $dbh);
my @agents = get_db_rows ($dbh, 'SELECT id_agente, update_alert_count FROM tagente WHERE update_alert_count=1');
foreach my $agent (@agents) {
if ($agent->{'update_alert_count'} == 1) {
pandora_update_agent_alert_count ($pa_config, $dbh, $agent->{'id_agente'});
}
}
}
# TASKS EXECUTED EVERY 30 SECONDS (Mid latency tasks)
# ---------------------------------------------------
if (($counter % 30) == 0) {
# Update module status and fired alert counts
my @agents = get_db_rows ($dbh, 'SELECT id_agente, nombre, update_module_count, update_alert_count, update_secondary_groups FROM tagente WHERE (update_module_count=1 OR update_alert_count=1 OR update_secondary_groups=1)');
my @agents = get_db_rows ($dbh, 'SELECT id_agente, nombre, update_module_count, update_secondary_groups FROM tagente WHERE (update_module_count=1 OR update_secondary_groups=1)');
foreach my $agent (@agents) {
logger ($pa_config, "Updating module status and fired alert counts for agent " . $agent->{'nombre'}, 10);
if ($agent->{'update_module_count'} == 1) {
pandora_update_agent_module_count ($pa_config, $dbh, $agent->{'id_agente'});
}
if ($agent->{'update_alert_count'} == 1) {
pandora_update_agent_alert_count ($pa_config, $dbh, $agent->{'id_agente'});
}
if ($agent->{'update_secondary_groups'} == 1) {
pandora_update_secondary_groups_cache ($pa_config, $dbh, $agent->{'id_agente'});
}
}
# Keepalive module control.(very DB intensive, not run frecuently
pandora_module_keep_alive_nd ($pa_config, $dbh);
@ -491,16 +494,6 @@ sub pandora_server_tasks ($) {
pandora_self_monitoring ($pa_config, $dbh);
}
# Pandora sample agent
if (defined($pa_config->{'sample_agent'})) {
if ($pa_config->{'sample_agent'} == 1
&& !is_metaconsole($pa_config)
&& $counter % $pa_config->{'sample_agent_interval'} == 0){
pandora_sample_agent ($pa_config);
}
pandora_update_config_token ($dbh, 'sample_agent', $pa_config->{'sample_agent'});
}
# Avoid counter overflow
if ($counter >= ~0){
$counter = 0;

View File

@ -422,15 +422,6 @@ self_monitoring 1
# Self monitoring interval (in seconds).
self_monitoring_interval 300
# Pandora Sample Agent. If enabled, every 10 minutes, this embedded agent
# will make sample data. Disabled by default.
sample_agent 0
# Pandora Sample Agent interval (in seconds).
sample_agent_interval 600
# Update parent from the agent xml
update_parent 1

View File

@ -345,15 +345,6 @@ restart_delay 60
# Self monitoring interval (in seconds).
#self_monitoring_interval 300
# Pandora Sample Agent. If enabled, every 10 minutes, this embedded agent
# will make sample data. Disabled by default.
sample_agent 0
# Pandora Sample Agent interval (in seconds).
sample_agent_interval 600
# Update parent from the agent xml
#update_parent 1

View File

@ -46,7 +46,7 @@ our @EXPORT = qw(
# version: Defines actual version of Pandora Server for this module only
my $pandora_version = "7.0NG.767";
my $pandora_build = "221228";
my $pandora_build = "230113";
our $VERSION = $pandora_version." ".$pandora_build;
# Setup hash
@ -415,12 +415,6 @@ sub pandora_load_config {
# Self monitoring interval
$pa_config->{'self_monitoring_interval'} = 300; # 5.1SP1
# Sample Agent
$pa_config->{'sample_agent'} = 0;
# Sample agent interval
$pa_config->{'sample_agent_interval'} = 600;
# Process XML data files as a stack
$pa_config->{"dataserver_lifo"} = 0; # 5.0
@ -1014,12 +1008,6 @@ sub pandora_load_config {
elsif ($parametro =~ m/^self_monitoring_interval\s+([0-9]*)/i) {
$pa_config->{'self_monitoring_interval'} = clean_blank($1);
}
elsif ($parametro =~ m/^sample_agent\s+([0-1])/i) {
$pa_config->{'sample_agent'} = clean_blank($1);
}
elsif ($parametro =~ m/^sample_agent_interval\s+([0-9]*)/i) {
$pa_config->{'sample_agent_interval'} = clean_blank($1);
}
elsif ($parametro =~ m/^update_parent\s+([0-1])/i) {
$pa_config->{'update_parent'} = clean_blank($1);
}

View File

@ -100,8 +100,6 @@ Exported Functions:
=item * C<pandora_thread_monitoring>
=item * C<pandora_sample_agent>
=back
=head1 METHODS
@ -261,7 +259,6 @@ our @EXPORT = qw(
pandora_server_statistics
pandora_self_monitoring
pandora_thread_monitoring
pandora_sample_agent
pandora_process_policy_queue
pandora_sync_agents_integria
pandora_get_integria_ticket_types
@ -6138,84 +6135,6 @@ sub pandora_thread_monitoring ($$$) {
close (XMLFILE);
}
##########################################################################
=head2 C<< xml_module_template (I<$module_name>, I<$module_type>, I<$module_data>) >>
Module template for sample agent
=cut
##########################################################################
sub xml_module_template ($$$) {
my ($module_name, $module_type, $module_data) = @_;
my $output = "<module>\n";
$module_name = "<![CDATA[".$module_name."]]>" if $module_name =~ /[\s+.]+/;
$module_data = "<![CDATA[".$module_data."]]>" if $module_data =~ /[\s+.]+/;
$output .= "\t<name>".$module_name."</name>\n";
$output .= "\t<type>".$module_type."</type>\n";
$output .= "\t<data>".$module_data."</data>\n";
$output .= "</module>\n";
return $output;
}
##########################################################################
=head2 C<< pandora_sample_agent (I<$pa_config>) >>
Pandora agent for make sample data
=cut
##########################################################################
sub pandora_sample_agent ($) {
my ($pa_config) = @_;
my $utimestamp = time ();
my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime());
# First line
my $xml_output = "<?xml version='1.0' encoding='UTF-8'?>\n";
# Header
$xml_output = "<agent_data agent_name='Sample_Agent' agent_alias='Sample_Agent' description='Agent for sample generation purposes' group='Servers' os_name='$OS' os_version='$OS_VERSION' interval='".$pa_config->{'sample_agent_interval'}."' version='" . $pa_config->{'version'} . "' timestamp='".$timestamp."'>\n";
# Boolean ever return TRUE
$xml_output .= xml_module_template ("Boolean ever true", "generic_proc","1");
# Boolean return TRUE at 80% of times
my $sample_boolean_mostly_true = 1;
$sample_boolean_mostly_true = 0 if rand(9) > 7;
$xml_output .= xml_module_template ("Boolean mostly true", "generic_proc",$sample_boolean_mostly_true);
# Boolean return false at 80% of times
my $sample_boolean_mostly_false = 0;
$sample_boolean_mostly_false = 1 if rand(9) > 7;
$xml_output .= xml_module_template ("Boolean mostly false", "generic_proc", $sample_boolean_mostly_false);
# Boolean ever return FALSE
$xml_output .= xml_module_template ("Boolean ever false", "generic_proc","0");
# Random integer between 0 and 100
$xml_output .= xml_module_template ("Random integer values", "generic_data",int(rand(100)));
# Random values obtained with sinusoidal curves between 0 and 100 values
my $b = 1;
my $sample_serie_curve = 1 + cos(deg2rad($b));
$b = $b + rand(20)/10;
$b = 0 if ($b > 180);
$sample_serie_curve = $sample_serie_curve * $b * 10;
$sample_serie_curve =~ s/\,/\./g;
$xml_output .= xml_module_template ("Random serie curve", "generic_data", $sample_serie_curve);
# String with 10 random characters
my $sample_random_text = "";
my @characters = ('a'..'z','A'..'Z');
for (1...10){
$sample_random_text .= $characters[int(rand(@characters))];
}
$xml_output .= xml_module_template ("Random text", "generic_data_string", $sample_random_text);
# End of xml
$xml_output .= "</agent_data>";
# File path definition
my $filename = $pa_config->{"incomingdir"}."/".$pa_config->{'servername'}.".sample.".$utimestamp.".data";
# Opening, Writing and closing of XML
open (my $xmlfile, ">", $filename) or die "[FATAL] Could not open sample XML file for deploying monitorization at '$filename'";
print $xmlfile $xml_output;
close ($xmlfile);
}
##########################################################################
=head2 C<< set_master (I<$pa_config>, I<$dbh>) >>

View File

@ -34,7 +34,7 @@ our @ISA = qw(Exporter);
# version: Defines actual version of Pandora Server for this module only
my $pandora_version = "7.0NG.767";
my $pandora_build = "221228";
my $pandora_build = "230113";
our $VERSION = $pandora_version." ".$pandora_build;
our %EXPORT_TAGS = ( 'all' => [ qw() ] );

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_server
%define version 7.0NG.767
%define release 221228
%define release 230113
Summary: Pandora FMS Server
Name: %{name}

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_server
%define version 7.0NG.767
%define release 221228
%define release 230113
Summary: Pandora FMS Server
Name: %{name}

View File

@ -9,7 +9,7 @@
# **********************************************************************
PI_VERSION="7.0NG.767"
PI_BUILD="221228"
PI_BUILD="230113"
MODE=$1
if [ $# -gt 1 ]; then

View File

@ -1,12 +1,12 @@
#!/bin/bash
echo "Small tool to measure data processing throughput for a Pandora FMS data server"
echo "(c) 2010-2015 Sancho Lerena, slerena@gmail.com"
echo "Small tool to measure data processing throughput for a Pandora FMS Data server"
echo "(c) 2010-2023 Pandora FMS Team"
ANT=0
while [ 1 ]
do
ACT=`find /var/spool/pandora/data_in | wc -l`
ACT=`find /var/spool/pandora/data_in -maxdepth 1 -type f | wc -l`
if [ $ANT != 0 ]
then
RES=`expr $ANT - $ACT`

View File

@ -35,7 +35,7 @@ use PandoraFMS::Config;
use PandoraFMS::DB;
# version: define current version
my $version = "7.0NG.767 Build 221228";
my $version = "7.0NG.767 Build 230113";
# Pandora server configuration
my %conf;

View File

@ -36,7 +36,7 @@ use Encode::Locale;
Encode::Locale::decode_argv;
# version: define current version
my $version = "7.0NG.767 Build 221228";
my $version = "7.0NG.767 Build 230113";
# save program name for logging
my $progname = basename($0);

View File

@ -66,6 +66,7 @@ export interface ItemProps extends Position, Size {
cacheExpiration: number | null;
colorStatus: string;
cellId: number | null;
alertOutline: boolean;
}
export interface ItemClickEvent {
@ -143,6 +144,7 @@ export function itemBasePropsDecoder(data: AnyObject): ItemProps | never {
cacheExpiration: parseIntOr(data.cacheExpiration, null),
colorStatus: notEmptyStringOr(data.colorStatus, "#CCC"),
cellId: parseIntOr(data.cellId, null),
alertOutline: parseBoolean(data.alertOutline),
...sizePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
...positionPropsDecoder(data) // Object spread. It will merge the properties of the two objects.
};
@ -534,6 +536,10 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
box.style.left = `${this.props.x}px`;
box.style.top = `${this.props.y}px`;
if (this.props.alertOutline) {
box.classList.add("is-alert-triggered");
}
// Init the click listeners.
box.addEventListener("dblclick", e => {
if (!this.meta.isBeingMoved && !this.meta.isBeingResized) {
@ -887,8 +893,13 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
) {
if (this.meta.editMode && this.meta.maintenanceMode === false) {
this.elementRef.classList.add("is-editing");
this.elementRef.classList.remove("is-alert-triggered");
} else {
this.elementRef.classList.remove("is-editing");
if (this.props.alertOutline) {
this.elementRef.classList.add("is-alert-triggered");
}
}
}

View File

@ -74,6 +74,10 @@
}
}
.visual-console-item.is-alert-triggered {
border: 3px solid #f36201;
}
.visual-console-spinner {
background-color: transparent;
margin: 0px auto;