implemented alert commands and actions to send report by email

This commit is contained in:
alejandro.campos@artica.es 2022-09-13 12:16:53 +02:00
parent 3524cdac6c
commit d1cc2458b6
6 changed files with 545 additions and 5 deletions

View File

@ -6,4 +6,7 @@ ALTER TABLE `tplanned_downtime` ADD COLUMN `cron_interval_to` VARCHAR(100) DEFAU
SET @id_config := (SELECT id_config FROM tconfig WHERE `token` = 'metaconsole_node_id' AND `value` IS NOT NULL ORDER BY id_config DESC LIMIT 1);
DELETE FROM tconfig WHERE `token` = 'metaconsole_node_id' AND (id_config < @id_config OR `value` IS NULL);
INSERT INTO `talert_commands` (`name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES ('Send&#x20;report&#x20;by&#x20;e-mail','Internal&#x20;type','This&#x20;command&#x20;allows&#x20;you&#x20;to&#x20;send&#x20;a&#x20;report&#x20;by&#x20;email.',1,'[\"Report\",\"e-mail&#x20;address\",\"Subject\",\"Text\",\"Report&#x20;type\",\"\",\"\",\"\",\"\",\"\"]','[\"_reports_\",\"\",\"\",\"_html_editor_\",\"xml,XML;pdf,PDF;json,JSON;csv,CSV\",\"\",\"\",\"\",\"\",\"\"]');
INSERT INTO `talert_commands` (`name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES ('Send&#x20;report&#x20;by&#x20;e-mail&#x20;(from&#x20;template)','Internal&#x20;type','This&#x20;command&#x20;allows&#x20;you&#x20;to&#x20;send&#x20;a&#x20;report&#x20;generated&#x20;from&#x20;a&#x20;template&#x20;by&#x20;email.',1,'[\"Template\",\"Regexp&#x20;agent&#x20;filter\",\"e-mail&#x20;address\",\"Subject\",\"Text\",\"Report&#x20;type\",\"\",\"\",\"\",\"\"]','[\"_report_templates_\",\"\",\"\",\"\",\"_html_editor_\",\"xml,XML;pdf,PDF;json,JSON;csv,CSV\",\"\",\"\",\"\",\"\"]');
COMMIT;

View File

@ -15,6 +15,7 @@
global $config;
require_once $config['homedir'].'/include/functions_alerts.php';
require_once $config['homedir'].'/include/functions_reports.php';
enterprise_include_once('meta/include/functions_alerts_meta.php');
check_login();
@ -284,13 +285,13 @@ if (is_ajax()) {
$ffield .= '<div name="field'.$i.'_value_container">'.html_print_switch(
[
'name' => 'field'.$i.'_value[]',
'value' => '',
'value' => ''
]
).'</div>';
$rfield .= '<div name="field'.$i.'_recovery_value_container">'.html_print_switch(
[
'name' => 'field'.$i.'_recovery_value[]',
'value' => '',
'value' => ''
]
).'</div>';
@ -349,9 +350,94 @@ if (is_ajax()) {
);
} else {
$fields_value_select = [];
$fv = explode(';', $field_value);
$force_print_select = false;
if (count($fv) > 1) {
// Exception for dynamically filled select boxes.
if (preg_match('/^_reports_$/i', $field_value)) {
// Filter normal and metaconsole reports.
if (is_metaconsole() === true) {
$filter['metaconsole'] = 1;
} else {
$filter['metaconsole'] = 0;
}
$own_info = get_user_info($config['id_user']);
if ($own_info['is_admin'] || check_acl($config['id_user'], 0, 'RM') || check_acl($config['id_user'], 0, 'RR')) {
$return_all_group = true;
} else {
$return_all_group = false;
}
if (is_user_admin($config['id_user']) === false) {
$filter[] = sprintf(
'private = 0 OR (private = 1 AND id_user = "%s")',
$config['id_user']
);
}
$reports = reports_get_reports(
$filter,
[
'name',
'id_report'
],
$return_all_group,
'RR'
);
$fv = array_map(
function ($report) {
return $report['id_report'].','.$report['name'];
},
$reports
);
$force_print_select = true;
} else if (preg_match('/^_report_templates_$/i', $field_value)) {
// Filter normal and metaconsole reports.
if (is_metaconsole() === true) {
$filter['metaconsole'] = 1;
} else {
$filter['metaconsole'] = 0;
}
$own_info = get_user_info($config['id_user']);
if ($own_info['is_admin'] || check_acl($config['id_user'], 0, 'RM') || check_acl($config['id_user'], 0, 'RR')) {
$return_all_group = true;
} else {
$return_all_group = false;
}
if (is_user_admin($config['id_user']) === false) {
$filter[] = sprintf(
'private = 0 OR (private = 1 AND id_user = "%s")',
$config['id_user']
);
}
$templates = reports_get_report_templates(
$filter,
[
'name',
'id_report'
],
$return_all_group,
'RR'
);
$fv = array_map(
function ($template) {
return $template['id_report'].','.$template['name'];
},
$templates
);
$force_print_select = true;
} else {
$fv = explode(';', $field_value);
}
if (count($fv) > 1 || $force_print_select === true) {
if (!empty($fv)) {
foreach ($fv as $fv_option) {
$fv_option = explode(',', $fv_option);

View File

@ -46,12 +46,18 @@ require_once $config['homedir'].'/include/functions_planned_downtimes.php';
require_once $config['homedir'].'/include/functions_db.php';
require_once $config['homedir'].'/include/functions_event_responses.php';
require_once $config['homedir'].'/include/functions_tactical.php';
require_once $config['homedir'].'/include/functions_reporting.php';
require_once $config['homedir'].'/include/functions_reporting_xml.php';
require_once $config['homedir'].'/include/functions_reports.php';
enterprise_include_once('include/functions_local_components.php');
enterprise_include_once('include/functions_events.php');
enterprise_include_once('include/functions_agents.php');
enterprise_include_once('include/functions_modules.php');
enterprise_include_once('include/functions_clusters.php');
enterprise_include_once('include/functions_alerts.php');
enterprise_include_once('include/functions_reporting_pdf.php');
enterprise_include_once('include/functions_reporting_csv.php');
enterprise_include_once('include/functions_cron.php');
// Clases.
use PandoraFMS\Agent;
@ -17542,3 +17548,303 @@ function api_set_enable_disable_discovery_task($id_task, $thrash2, $other)
}
}
}
/**
* Make report (PDF, CSV or XML) and send it via e-mail (this method is intended to be used by server's execution
* of alert actions that involve sending reports by e-mail).
* @param [string] $server_id id server (Node)
* @param [string] $console_event_id console Id node event in tevent
* @param [string] $trash2 don't use
* @param [string] $returnType
*
* Example
* api.php?op=get&op2=event_mcid&return_type=json&id=0&id2=0&apipass=1234&user=admin&pass=pandora
*
* @return void
*/
function api_set_send_report($thrash1, $thrash2, $other, $returnType)
{
global $config;
$id_item = (int) $other['data'][0];
$report_type = $other['data'][1];
$email = $other['data'][2];
$subject_email = $other['data'][3];
$body_email = $other['data'][4];
$make_report_from_template = (bool) $other['data'][5];
$template_regex_agents = $other['data'][6];
// Filter normal and metaconsole reports.
if (is_metaconsole() === true) {
$filter['metaconsole'] = 1;
} else {
$filter['metaconsole'] = 0;
}
$own_info = get_user_info($config['id_user']);
if ($own_info['is_admin'] || check_acl($config['id_user'], 0, 'RM') || check_acl($config['id_user'], 0, 'RR')) {
$return_all_group = true;
} else {
$return_all_group = false;
}
if (is_user_admin($config['id_user']) === false) {
$filter[] = sprintf(
'private = 0 OR (private = 1 AND id_user = "%s")',
$config['id_user']
);
}
$date_today = date($config['date_format']);
$date_today = preg_split('/[\s,]+/', io_safe_output($date_today));
$date_today = __($date_today[0]).' '.$date_today[1].' '.$date_today[2].' '.$date_today[3].' '.$date_today[4];
if ($make_report_from_template === true) {
$filter['id_report'] = $id_item;
$template = reports_get_report_templates(
$filter,
[
'description'
],
$return_all_group,
'RR'
)[0];
$description = $template['description'];
// Report macros post-process.
$body_email = str_replace([
'_report_description_',
'_report_generated_date_',
'_report_date_'
],
[
$description,
$date_today,
$date_today
],
$body_email
);
$report_type = strtoupper($report_type);
$body_email = io_safe_output(io_safe_output($body_email));
cron_task_generate_report_by_template(
$id_item,
'',
$template_regex_agents,
false,
'',
$email,
$subject_email,
$body_email,
$report_type,
''
);
} else {
$report = reports_get_report($id_item);
if ($report === false) {
// User has no grant to access this report.
return;
}
// Report macros post-process.
$body_email = str_replace([
'_report_description_',
'_report_generated_date_',
'_report_date_'
],
[
$report['description'],
$date_today,
$date_today
],
$body_email
);
$body_email = io_safe_output(io_safe_output($body_email));
// Set the languaje of user.
global $l10n;
if (isset($l10n) === false) {
$l10n = null;
$user_language = get_user_language($config['id_user']);
if (file_exists(
$config['homedir'].'/include/languages/'.$user_language.'.mo'
) === true
) {
$obj = new CachedFileReader(
$config['homedir'].'/include/languages/'.$user_language.'.mo'
);
$l10n = new gettext_reader($obj);
$l10n->load_tables();
}
}
// Attachments.
$attachments = [];
// Set the datetime for the report.
$report['datetime'] = time();
$date = date('Y-m-j');
$time = date('h:iA');
$tmpfile = false;
switch ($report_type) {
case 'pdf':
$tmpfile = $config['homedir'].'/attachment/'.date('Ymd-His').'.pdf';
$report = reporting_make_reporting_data(
null,
$id_item,
$date,
$time,
null,
'static',
null,
null,
true
);
pdf_get_report($report, $tmpfile);
$attachments[0] = [
'file' => $tmpfile,
'content_type' => 'application/pdf',
];
break;
case 'csv':
$report = reporting_make_reporting_data(
null,
$id_item,
$date,
$time,
null,
'data'
);
$name = explode(' - ', $report['name']);
$tmpfile = $config['homedir'].'/attachment/'.$name[0].'.csv';
// ------- Removed the unused fields -----------------------------.
unset($report['header']);
unset($report['first_page']);
unset($report['footer']);
unset($report['custom_font']);
unset($report['id_template']);
unset($report['id_group_edit']);
unset($report['metaconsole']);
unset($report['private']);
unset($report['custom_logo']);
ob_start();
csv_get_report($report, true);
$output = ob_get_clean();
file_put_contents($tmpfile, $output);
ob_end_clean();
$attachments[0] = [
'file' => $tmpfile,
'content_type' => 'text/csv',
];
break;
case 'json':
$report = reporting_make_reporting_data(
null,
$id_item,
$date,
$time,
null,
'data'
);
// ------- Removed the unused fields -----------------------------
unset($report['header']);
unset($report['first_page']);
unset($report['footer']);
unset($report['custom_font']);
unset($report['id_template']);
unset($report['id_group_edit']);
unset($report['metaconsole']);
unset($report['private']);
unset($report['custom_logo']);
$name = explode(' - ', $report['name']);
$tmpfile = $config['homedir'].'/attachment/'.$name[0].'.json';
file_put_contents($tmpfile, json_encode($report, JSON_PRETTY_PRINT));
$attachments[0] = [
'file' => $tmpfile,
'content_type' => 'text/json',
];
break;
case 'xml':
$report = reporting_make_reporting_data(
null,
$id_item,
$date,
$time,
null,
'data'
);
$name = explode(' - ', $report['name']);
$tmpfile = $config['homedir'].'/attachment/'.$name[0].'.xml';
// ------- Removed the unused fields -----------------------------
unset($report['header']);
unset($report['first_page']);
unset($report['footer']);
unset($report['custom_font']);
unset($report['id_template']);
unset($report['id_group_edit']);
unset($report['metaconsole']);
unset($report['private']);
unset($report['custom_logo']);
ob_start();
reporting_xml_get_report($report, true);
$output = ob_get_clean();
file_put_contents($tmpfile, $output);
ob_end_clean();
$attachments[0] = [
'file' => $tmpfile,
'content_type' => 'text/xml',
];
break;
default:
break;
}
reporting_email_template(
$subject_email,
$body_email,
'',
$report['name'],
$email,
$attachments
);
unlink($other['data'][0]);
$data = [
'type' => 'string',
'data' => '1',
];
returnData($returnType, $data, ';');
}
}

View File

@ -1408,3 +1408,77 @@ function custom_fields_macros_report($macro, $key_macro)
return $result;
}
/**
* Get a list of the reports the user can view.
*
* A user can view a report by two ways:
* - The user created the report (id_user field in treport)
* - The report is not private and the user has reading privileges on
* the group associated to the report
*
* @param array Extra filter to retrieve reports. All reports are returned by
* default
* @param array Fields to be fetched on every report.
*
* @return array An array with all the reports the user can view.
*/
function reports_get_report_templates(
$filter=false,
$fields=false,
$returnAllGroup=true,
$privileges='RR',
$group=false,
$strict_user=false
) {
global $config;
if (is_array($filter) === false) {
$filter = [];
}
if (is_array($fields) === false) {
$fields[] = 'id_group';
$fields[] = 'id_user';
}
$templates = [];
$all_templates = @db_get_all_rows_filter('treport_template', $filter, $fields);
if (empty($all_templates) === true) {
$all_templates = [];
}
if ($group) {
$groups = $group;
} else {
$groups = users_get_groups($config['id_user'], $privileges, $returnAllGroup);
if ($strict_user) {
$groups = users_get_strict_mode_groups($config['id_user'], $returnAllGroup);
}
}
foreach ($all_templates as $template) {
// If the template is not in all group.
if ($template['id_group'] != 0) {
if (!in_array($template['id_group'], array_keys($groups))) {
continue;
}
if ($config['id_user'] != $template['id_user']
&& !check_acl($config['id_user'], $template['id_group'], $privileges)
) {
continue;
}
} else {
if ($returnAllGroup === false) {
continue;
}
}
array_push($templates, $template);
}
return $templates;
}

File diff suppressed because one or more lines are too long

View File

@ -1647,6 +1647,70 @@ sub pandora_execute_action ($$$$$$$$$;$$) {
pandora_sendmail ($pa_config, $field1, $field2, $field3, $content_type);
}
# Email report
} elsif ($clean_name eq "Send report by e-mail") {
# Text
$field4 = subst_alert_macros ($field4, \%macros, $pa_config, $dbh, $agent, $module, $alert);
# API connection
my $ua = new LWP::UserAgent;
eval {
$ua->ssl_opts( 'verify_hostname' => 0 );
$ua->ssl_opts( 'SSL_verify_mode' => 0x00 );
};
if ( $@ ) {
logger($pa_config, "Failed to limit ssl security on console link: " . $@, 10);
}
my $url ||= $pa_config->{"console_api_url"};
my $params = {};
$params->{"apipass"} = $pa_config->{"console_api_pass"};
$params->{"user"} ||= $pa_config->{"console_user"};
$params->{"pass"} ||= $pa_config->{"console_pass"};
$params->{"op"} = "set";
$params->{"op2"} = "send_report";
$params->{"other_mode"} = "url_encode_separator_|;|";
$field4 = safe_input($field4);
$field4 =~ s/&amp;/&/g;
$params->{"other"} = $field1.'|;|'.$field5.'|;|'.$field2.'|;|'.$field3.'|;|'.$field4.'|;|0';
$ua->post($url, $params);
# Email report (from template)
} elsif ($clean_name eq "Send report by e-mail (from template)") {
# Text
$field5 = subst_alert_macros ($field5, \%macros, $pa_config, $dbh, $agent, $module, $alert);
# API connection
my $ua = new LWP::UserAgent;
eval {
$ua->ssl_opts( 'verify_hostname' => 0 );
$ua->ssl_opts( 'SSL_verify_mode' => 0x00 );
};
if ( $@ ) {
logger($pa_config, "Failed to limit ssl security on console link: " . $@, 10);
}
my $url ||= $pa_config->{"console_api_url"};
my $params = {};
$params->{"apipass"} = $pa_config->{"console_api_pass"};
$params->{"user"} ||= $pa_config->{"console_user"};
$params->{"pass"} ||= $pa_config->{"console_pass"};
$params->{"op"} = "set";
$params->{"op2"} = "send_report";
$params->{"other_mode"} = "url_encode_separator_|;|";
$field5 = safe_input($field5);
$field5 =~ s/&amp;/&/g;
$params->{"other"} = $field1.'|;|'.$field6.'|;|'.$field3.'|;|'.$field4.'|;|'.$field5.'|;|1|;|'.$field2;
$ua->post($url, $params);
# Pandora FMS Event
} elsif ($clean_name eq "Monitoring Event") {
$field1 = subst_alert_macros ($field1, \%macros, $pa_config, $dbh, $agent, $module, $alert);
@ -6831,7 +6895,7 @@ sub pandora_create_integria_ticket ($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$) {
'params=' . $data_ticket .'&' .
'token=|;|';
my $content = get($call_api);
my $content = get($call_api);
if (is_numeric($content) && $content ne "-1") {
return $content;