diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 780ba07f0a..483710b13a 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.773.3-230921 +Version: 7.0NG.773.3-230928 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 51e0b3cf50..d28b3ee47f 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.773.3-230921" +pandora_version="7.0NG.773.3-230928" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index ab9fb2f0e1..8179796429 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -1031,7 +1031,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.773.3'; -use constant AGENT_BUILD => '230921'; +use constant AGENT_BUILD => '230928'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index e80d8f76fb..775c7b6de2 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.773.3 -%define release 230921 +%define release 230928 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.redhat_bin.spec b/pandora_agents/unix/pandora_agent.redhat_bin.spec index c61d0c9b8a..e79f77124f 100644 --- a/pandora_agents/unix/pandora_agent.redhat_bin.spec +++ b/pandora_agents/unix/pandora_agent.redhat_bin.spec @@ -5,7 +5,7 @@ %define name pandorafms_agent_linux_bin %define source_name pandorafms_agent_linux %define version 7.0NG.773.3 -%define release 230921 +%define release 230928 Summary: Pandora FMS Linux agent, binary version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 651f12f16c..027ac1e8fa 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_agent_linux %define version 7.0NG.773.3 -%define release 230921 +%define release 230928 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index 268afacd7a..094d35b842 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.773.3" -PI_BUILD="230921" +PI_BUILD="230928" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index f8155e2f83..0048e27d18 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{230921} +{230928} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 8df7c167e9..b28df08cd0 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.773.3 Build 230921") +#define PANDORA_VERSION ("7.0NG.773.3 Build 230928") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 4b3c790c96..88007e38d9 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Pandora FMS" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.773.3(Build 230921))" + VALUE "ProductVersion", "(7.0NG.773.3(Build 230928))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index 7ba6c9d828..c628b00d4b 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.773.3-230921 +Version: 7.0NG.773.3-230928 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index e9aa2f3a84..01f25b1bd7 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.773.3-230921" +pandora_version="7.0NG.773.3-230928" package_pear=0 package_pandora=1 diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt index 26eaa93392..513b626262 100644 --- a/pandora_console/extras/delete_files/delete_files.txt +++ b/pandora_console/extras/delete_files/delete_files.txt @@ -1707,4 +1707,12 @@ enterprise/godmode/wizards/Applications.class.php enterprise/godmode/wizards/Cloud.class.php enterprise/images/wizard/applications.png enterprise/images/wizard/cloud.png -enterprise/images/wizard/consoletasks.png \ No newline at end of file +enterprise/images/wizard/consoletasks.png +operation/incidents/configure_integriaims_incident.php +operation/incidents/dashboard_detail_integriaims_incident.php +operation/incidents/incident_statistics.php +operation/incidents/integriaims_export_csv.php +operation/incidents/list_integriaims_incidents.php +include/functions_incidents.php +include/functions_integriaims.php +include/ajax/integria_incidents.ajax.php diff --git a/pandora_console/extras/mr/66.sql b/pandora_console/extras/mr/66.sql index 526602e24c..261d0fb9d2 100644 --- a/pandora_console/extras/mr/66.sql +++ b/pandora_console/extras/mr/66.sql @@ -14,6 +14,43 @@ CREATE TABLE IF NOT EXISTS `tgraph_analytics_filter` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; +ALTER TABLE `tusuario` MODIFY COLUMN `integria_user_level_pass` TEXT; + +DROP TABLE `tincidencia`; +DROP TABLE `tnota`; +DROP TABLE `tattachment`; + +ALTER TABLE `talert_commands` ADD CONSTRAINT UNIQUE (`name`); + +ALTER TABLE `talert_actions` MODIFY COLUMN `name` VARCHAR(500); +ALTER TABLE `talert_actions` ADD CONSTRAINT UNIQUE (`name`); + +SET @command_name = 'Pandora ITSM Ticket'; +SET @command_description = 'Create a ticket in Pandora ITSM'; +SET @action_name = 'Create Pandora ITSM ticket'; + +UPDATE `talert_commands` SET `name` = @command_name, `description` = @command_description WHERE `name` = 'Integria IMS Ticket' AND `internal` = 1; +INSERT IGNORE INTO `talert_commands` (`name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (@command_name,'Internal type',@command_description,1,'["Ticket title","Ticket group ID","Ticket priority","Ticket owner","Ticket type","Ticket status","Ticket description","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_"]','["", "_ITSM_groups_", "_ITSM_priorities_","_ITSM_users_","_ITSM_types_","_ITSM_status_","_html_editor_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_"]'); + +SELECT @id_alert_command := `id` FROM `talert_commands` WHERE `name` = @command_name; +UPDATE `talert_actions` SET `name` = @action_name WHERE `name` = 'Create Integria IMS ticket' AND `id_alert_command` = @id_alert_command; +INSERT IGNORE INTO `talert_actions` (`name`, `id_alert_command`) VALUES (@action_name,@id_alert_command); + +SET @event_response_name = 'Create ticket in Pandora ITSM from event'; +SET @event_response_description = 'Create a ticket in Pandora ITSM from an event'; +SET @event_response_target = 'index.php?sec=manageTickets&sec2=operation/ITSM/itsm&operation=edit&from_event=_event_id_'; +SET @event_response_type = 'url'; +SET @event_response_id_group = 0; +SET @event_response_modal_width = 0; +SET @event_response_modal_height = 0; +SET @event_response_new_window = 1; +SET @event_response_params = ''; +SET @event_response_server_to_exec = 0; +SET @event_response_command_timeout = 90; +SET @event_response_display_command = 1; +UPDATE `tevent_response` SET `name` = @event_response_name, `description` = @event_response_description, `target` = @event_response_target, `display_command` = @event_response_display_command WHERE `name` = 'Create ticket in IntegriaIMS from event'; +INSERT IGNORE INTO `tevent_response` (`name`, `description`, `target`,`type`,`id_group`,`modal_width`,`modal_height`,`new_window`,`params`,`server_to_exec`,`command_timeout`,`display_command`) VALUES (@event_response_name, @event_response_description, @event_response_target, @event_response_type, @event_response_id_group, @event_response_modal_width, @event_response_modal_height, @event_response_new_window, @event_response_params, @event_response_server_to_exec, @event_response_command_timeout, @event_response_display_command); + UPDATE `twelcome_tip` SET title = 'Scheduled downtimes', url = 'https://pandorafms.com/manual/en/documentation/04_using/11_managing_and_administration#scheduled_downtimes' @@ -72,5 +109,6 @@ ALTER TABLE `treport_content` ADD COLUMN `cat_security_hardening` INT NOT NULL ALTER TABLE `treport_content` ADD COLUMN `ignore_skipped` INT NOT NULL DEFAULT 0; ALTER TABLE `treport_content` ADD COLUMN `status_of_check` TINYTEXT; - +ALTER TABLE `tservice` ADD COLUMN `enable_horizontal_tree` TINYINT NOT NULL DEFAULT 0; + COMMIT; diff --git a/pandora_console/godmode/agentes/agent_incidents.php b/pandora_console/godmode/agentes/agent_incidents.php index ba43f1799c..6b6efee2ae 100644 --- a/pandora_console/godmode/agentes/agent_incidents.php +++ b/pandora_console/godmode/agentes/agent_incidents.php @@ -1,31 +1,43 @@ '.__('No incidents associated to this agent').'
'; - return; -} else { - $count = count($result); - $result = array_slice($result, $offset, $config['block_size']); +try { + $ITSM = new ITSM(); + echo $ITSM->getTableIncidencesForAgent($id_agente); +} catch (Exception $e) { + echo $e->getMessage(); } -// Show pagination. -ui_pagination($count, $url, $offset, 0, false, 'offset'); -// ($count + $offset) it's real count of incidents because it's use LIMIT $offset in query. -echo '
'; - -// Show headers. -$table->width = '100%'; -$table->class = 'databox'; -$table->cellpadding = 4; -$table->cellspacing = 4; -$table->head = []; -$table->data = []; -$table->size = []; -$table->align = []; - -$table->head[0] = __('ID'); -$table->head[1] = __('Status'); -$table->head[2] = __('Incident'); -$table->head[3] = __('Priority'); -$table->head[4] = __('Group'); -$table->head[5] = __('Updated'); - -$table->size[0] = 43; -$table->size[7] = 50; - -$table->align[1] = 'center'; -$table->align[3] = 'center'; -$table->align[4] = 'center'; - -$rowPair = true; -$iterator = 0; -foreach ($result as $row) { - if ($rowPair) { - $table->rowclass[$iterator] = 'rowPair'; - } else { - $table->rowclass[$iterator] = 'rowOdd'; - } - - $rowPair = !$rowPair; - $iterator++; - - $data = []; - - $data[0] = ''.$row['id_incidencia'].''; - $attach = incidents_get_attach($row['id_incidencia']); - - if (!empty($attach)) { - $data[0] .= '  '.html_print_image('images/attachment.png', true, ['style' => 'align:middle;']); - } - - $data[1] = incidents_print_status_img($row['estado'], true); - $data[2] = ''.substr(io_safe_output($row['titulo']), 0, 45).''; - $data[3] = incidents_print_priority_img($row['prioridad'], true); - $data[4] = $row['id_grupo']; - $data[5] = ui_print_timestamp($row['actualizacion'], true); - - array_push($table->data, $data); -} - -html_print_table($table); - -echo ''; -unset($table); -echo '

'; - -echo '
 
'; +html_print_action_buttons(''); diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index de42b8b6c3..91d911ae24 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -39,6 +39,7 @@ ui_require_javascript_file('encode_decode_base64'); ui_require_css_file('agent_manager'); use PandoraFMS\Event; +use PandoraFMS\ITSM\ITSM; check_login(); @@ -607,23 +608,6 @@ if ($id_agente) { $agent_wizard['active'] = false; } - - $total_incidents = agents_get_count_incidents($id_agente); - - // Incident tab. - if ($total_incidents > 0) { - $incidenttab['text'] = html_print_menu_button( - [ - 'href' => 'index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=incident&id_agente='.$id_agente, - 'image' => 'images/logs@svg.svg', - 'title' => __('Incidents'), - ], - true - ); - - $incidenttab['active'] = ($tab === 'incident'); - } - if (check_acl_one_of_groups($config['id_user'], $all_groups, 'AW') === true) { if ($has_remote_conf !== false) { $agent_name = agents_get_name($id_agente); @@ -2092,7 +2076,6 @@ if ($create_module) { if ($disable_module) { - hd($disable_module, true); $result = modules_change_disabled($disable_module, 1); $module_name = modules_get_agentmodule_name($disable_module); @@ -2116,13 +2099,11 @@ if ($create_module) { if ($result === NOERR) { - hd($disable_module, true); db_pandora_audit( AUDIT_LOG_MODULE_MANAGEMENT, 'Disable #'.$disable_module.' | '.$module_name.' | '.io_safe_output($agent['alias']) ); } else { - hd($disable_module, true); db_pandora_audit( AUDIT_LOG_MODULE_MANAGEMENT, 'Fail to disable #'.$disable_module.' | '.$module_name.' | '.io_safe_output($agent['alias']) diff --git a/pandora_console/godmode/agentes/modificar_agente.php b/pandora_console/godmode/agentes/modificar_agente.php index a14bff4b92..487fe54e07 100644 --- a/pandora_console/godmode/agentes/modificar_agente.php +++ b/pandora_console/godmode/agentes/modificar_agente.php @@ -751,6 +751,10 @@ if ($agents !== false) { 'index.php?sec=reporting&sec2=operation/cluster/cluster&op=view&id=%s', $cluster->id() ); + $agentAlertUrl = sprintf( + 'index.php?sec=estado&sec2=operation/cluster/cluster&op=update&id=%s&page=6', + $cluster->id() + ); } else { $main_tab = ($check_aw === true) ? 'main' : 'module'; $agentNameUrl = sprintf( @@ -762,6 +766,10 @@ if ($agents !== false) { 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente=%s', $agent['id_agente'] ); + $agentAlertUrl = sprintf( + 'index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=alert&id_agente=%s', + $agent['id_agente'] + ); } if (empty($agent['alias']) === true) { @@ -825,7 +833,7 @@ if ($agents !== false) { ); } - if ((int) $agent['id_os'] !== 100) { + if ((int) $agent['id_os'] != CLUSTER_OS_ID) { $additionalOptionsAgentName[] = html_print_anchor( [ 'href' => ui_get_full_url('index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=module&id_agente='.$agent['id_agente']), @@ -837,7 +845,7 @@ if ($agents !== false) { $additionalOptionsAgentName[] = html_print_anchor( [ - 'href' => ui_get_full_url('index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=alert&id_agente='.$agent['id_agente']), + 'href' => ui_get_full_url($agentAlertUrl), 'content' => __('Alerts'), ], true @@ -942,7 +950,7 @@ if ($agents !== false) { $os ) ), - 'onClick' => ($agent['id_os'] === CLUSTER_OS_ID) ? sprintf('if (!confirm(\'%s\')) return false', $agentDisableEnableCaption) : 'return true;', + 'onClick' => ($agent['id_os'] == CLUSTER_OS_ID) ? sprintf('if (!confirm(\'%s\')) return false', $agentDisableEnableCaption) : 'return true;', 'image' => sprintf('images/%s', $agentDisableEnableIcon), 'title' => $agentDisableEnableTitle, ], @@ -950,7 +958,7 @@ if ($agents !== false) { ); if ($check_aw === true && is_management_allowed() === true) { - if ($agent['id_os'] !== CLUSTER_OS_ID) { + if ($agent['id_os'] != CLUSTER_OS_ID) { $onClickActionDeleteAgent = 'if (!confirm(\' '.__('Are you sure?').'\')) return false;'; } else { $onClickActionDeleteAgent = 'if (!confirm(\' '.__('WARNING! - You are going to delete a cluster agent. Are you sure?').'\')) return false;'; diff --git a/pandora_console/godmode/alerts/alert_actions.php b/pandora_console/godmode/alerts/alert_actions.php index 97a492809e..e8915b05eb 100644 --- a/pandora_console/godmode/alerts/alert_actions.php +++ b/pandora_console/godmode/alerts/alert_actions.php @@ -405,6 +405,12 @@ $actions = array_slice($actions, $offset, $limit); $rowPair = true; $iterator = 0; foreach ($actions as $action) { + if ((isset($config['ITSM_enabled']) === false || (bool) $config['ITSM_enabled'] === false) + && $action['name'] === 'Create Pandora ITSM ticket' + ) { + continue; + } + if ($rowPair) { $table->rowclass[$iterator] = 'rowPair'; } else { diff --git a/pandora_console/godmode/alerts/alert_commands.php b/pandora_console/godmode/alerts/alert_commands.php index b6231544d1..a59de7f5e2 100644 --- a/pandora_console/godmode/alerts/alert_commands.php +++ b/pandora_console/godmode/alerts/alert_commands.php @@ -1,16 +1,33 @@ '; @@ -187,7 +215,7 @@ if (is_ajax()) { 0, '', false, - $is_management_allowed, + $management_is_not_allowed, "UndefineTinyMCE('#textarea_field".$i."_recovery_value')", '', true @@ -199,7 +227,7 @@ if (is_ajax()) { 0, '', true, - $is_management_allowed, + $management_is_not_allowed, "defineTinyMCE('#textarea_field".$i."_recovery_value')", '', true @@ -214,7 +242,7 @@ if (is_ajax()) { 'class="fields_recovery"', true, '', - $is_management_allowed + $management_is_not_allowed || $recovery_disabled ); } else if (preg_match('/^_content_type_$/i', $field_value)) { $editor_type_chkbx = '
'; @@ -228,7 +256,7 @@ if (is_ajax()) { 'text/plain', '', '', - $is_management_allowed, + $management_is_not_allowed, '', '', true @@ -240,7 +268,7 @@ if (is_ajax()) { 'text/html', '', 'text/html', - $is_management_allowed, + $management_is_not_allowed, '', '', true @@ -259,7 +287,7 @@ if (is_ajax()) { 'text/plain', '', '', - $is_management_allowed, + $management_is_not_allowed, '', '', true @@ -271,7 +299,7 @@ if (is_ajax()) { 'text/html', '', 'text/html', - $is_management_allowed, + $management_is_not_allowed, '', '', true @@ -279,78 +307,304 @@ if (is_ajax()) { $editor_type_chkbx .= '
'; $rfield = $editor_type_chkbx; // Select type. - } else if (preg_match('/^_integria_type_custom_field_$/i', $field_value)) { - $ffield = ''; - $rfield = ''; + } else if (preg_match('/^_custom_field_ITSM_$/i', $field_value)) { + $ffield = ''; + $rfield = ''; - $ffield .= '
'.html_print_switch( - [ - 'name' => 'field'.$i.'_value[]', - 'value' => '', - ] - ).'
'; - $rfield .= '
'.html_print_switch( - [ - 'name' => 'field'.$i.'_recovery_value[]', - 'value' => '', - ] - ).'
'; + $ffield .= '
'.html_print_switch( + [ + 'name' => 'field'.$i.'_value[]', + 'value' => '', + ] + ).'
'; + $rfield .= '
'.html_print_switch( + [ + 'name' => 'field'.$i.'_recovery_value[]', + 'value' => '', + 'disabled' => $management_is_not_allowed || $recovery_disabled, + ] + ).'
'; - $ffield .= html_print_select( - '', - 'field'.$i.'_value[]', + $ffield .= html_print_select( + '', + 'field'.$i.'_value[]', + '', + '', + __('None'), + '', + true, + false, + false, + 'fields', + $management_is_not_allowed, + 'width: 100%;', + false, + false, + false, + '', + false, + false, + false, + false, + false + ); + + $rfield .= html_print_select( + '', + 'field'.$i.'_recovery_value[]', + '', + '', + __('None'), + '', + true, + false, + false, + 'fields', + $management_is_not_allowed || $recovery_disabled, + 'width: 100%;', + false, + false, + false, + '', + false, + false, + false, + false, + false + ); + + $ffield .= html_print_input_text( + 'field'.$i.'_value[]', + '', + '', + 50, + 50, + true, + false, + false, + '', + 'datepicker', + '', + 'off', + false, + '', + '', + '', + $management_is_not_allowed + ); + $rfield .= html_print_input_text( + 'field'.$i.'_recovery_value[]', + '', + '', + 50, + 50, + true, + false, + false, + '', + 'datepicker', + '', + 'off', + false, + '', + '', + '', + $management_is_not_allowed || $recovery_disabled + ); + + $ffield .= html_print_textarea( + 'field'.$i.'_value[]', + 5, + 1, + '', + 'style="min-height:40px; '.$style.'" class="fields"', + true, + '', + $management_is_not_allowed + ); + + $rfield .= html_print_textarea( + 'field'.$i.'_recovery_value[]', + 5, + 1, + '', + 'style="min-height:40px; '.$style.'" class="fields_recovery', + true, + '', + $management_is_not_allowed || $recovery_disabled + ); + + $values_input_number = [ + 'name' => 'field'.$i.'_value[]', + 'value' => 0, + 'id' => 'field'.$i.'_value', + 'return' => true, + ]; + + if ($management_is_not_allowed === true) { + $values_input_number['disabled'] = true; + } + + $ffield .= html_print_input_number($values_input_number); + + $values_input_number_recovery = [ + 'name' => 'field'.$i.'_recovery_value[]', + 'value' => 0, + 'id' => 'field'.$i.'_recovery_value', + 'return' => true, + ]; + + if ($management_is_not_allowed || $recovery_disabled) { + $values_input_number_recovery['disabled'] = true; + } + + $rfield .= html_print_input_number($values_input_number_recovery); + + $ffield .= html_print_input_text( + 'field'.$i.'_value[]', + '', + '', + 50, + 255, + true, + false, + false, + '', + 'normal w98p', + '', + 'off', + false, + false, + '', + '', + $management_is_not_allowed + ); + $rfield .= html_print_input_text( + 'field'.$i.'_recovery_value[]', + '', + '', + 50, + 255, + true, + false, + false, + '', + 'normal w98p', + '', + 'off', + false, + false, + '', + '', + $management_is_not_allowed || $recovery_disabled + ); + } else if (str_starts_with($field_value, '_ITSM_')) { + $nothing = ''; + $nothing_value = 0; + $mode = 'select'; + switch ($field_value) { + case '_ITSM_groups_': + $fields_array = []; + try { + $ITSM = new ITSM(); + $fields_array = $ITSM->getGroups(); + } catch (\Throwable $th) { + $error = $th->getMessage(); + $fields_array = []; + } + break; + + case '_ITSM_priorities_': + $fields_array = []; + try { + $ITSM = new ITSM(); + $fields_array = $ITSM->getPriorities(); + } catch (\Throwable $th) { + $error = $th->getMessage(); + $fields_array = []; + } + break; + + case '_ITSM_types_': + $fields_array = []; + try { + $ITSM = new ITSM(); + $fields_array = $ITSM->getObjectypes(); + } catch (\Throwable $th) { + $error = $th->getMessage(); + $fields_array = []; + } + + $nothing = __('None'); + $nothing_value = 0; + break; + + case '_ITSM_status_': + $fields_array = []; + try { + $ITSM = new ITSM(); + $fields_array = $ITSM->getStatus(); + } catch (\Throwable $th) { + $error = $th->getMessage(); + $fields_array = []; + } + break; + + default: + // Nothing. + $mode = ''; + break; + } + + if ($mode === 'select') { + $ffield = html_print_select( + $fields_array, + 'field'.$i.'_value', '', '', - __('None'), - '', + $nothing, + $nothing_value, true, false, false, 'fields', - $is_management_allowed, - 'width: 100%;' + $management_is_not_allowed ); - $rfield .= html_print_select( - '', - 'field'.$i.'_recovery_value[]', + $rfield = html_print_select( + $fields_array, + 'field'.$i.'_recovery_value', '', '', - __('None'), - '', + $nothing, + $nothing_value, true, false, false, - 'fields', - $is_management_allowed, - 'width: 100%;' + 'fields_recovery', + $management_is_not_allowed || $recovery_disabled ); - - $ffield .= html_print_input_text('field'.$i.'_value[]', '', '', 10, 10, true, false, false, '', 'datepicker'); - $rfield .= html_print_input_text('field'.$i.'_recovery_value[]', '', '', 10, 10, true, false, false, '', 'datepicker'); - - $ffield .= html_print_textarea( - 'field'.$i.'_value[]', - 5, - 1, + } else { + $ffield = html_print_autocomplete_users_from_pandora_itsm( + 'field'.$i.'_value', '', - 'style="min-height:40px; '.$style.'" class="fields"', true, - '', - $is_management_allowed + 0, + $management_is_not_allowed, + false, + 'ITSM_users' ); - - $rfield .= html_print_textarea( - 'field'.$i.'_recovery_value[]', - 5, - 1, + $rfield = html_print_autocomplete_users_from_pandora_itsm( + 'field'.$i.'_recovery_value', '', - 'style="min-height:40px; '.$style.'" class="fields_recovery', true, - '', - $is_management_allowed + 0, + $management_is_not_allowed || $recovery_disabled, + false, + 'ITSM_users' ); + } } else { $fields_value_select = []; $force_print_select = false; @@ -468,7 +722,7 @@ if (is_ajax()) { false, false, 'fields', - $is_management_allowed + $management_is_not_allowed ); $rfield = html_print_select( $fields_value_select, @@ -481,7 +735,7 @@ if (is_ajax()) { false, false, 'fields_recovery', - $is_management_allowed + $management_is_not_allowed || $recovery_disabled ); } else { $ffield = html_print_textarea( @@ -492,7 +746,7 @@ if (is_ajax()) { 'style="'.$style.'" class="fields min-height-40px w100p"', true, '', - $is_management_allowed + $management_is_not_allowed ); $rfield = html_print_textarea( 'field'.$i.'_recovery_value', @@ -502,7 +756,7 @@ if (is_ajax()) { 'style="'.$style.'" class="fields_recovery min-height-40px w100p', true, '', - $is_management_allowed + $management_is_not_allowed || $recovery_disabled ); } } @@ -515,7 +769,7 @@ if (is_ajax()) { 'style="'.$style.'" class="fields min-height-40px w100p"', true, '', - $is_management_allowed + $management_is_not_allowed ); $rfield = html_print_textarea( 'field'.$i.'_recovery_value', @@ -525,7 +779,7 @@ if (is_ajax()) { 'style="'.$style.'" class="fields_recovery min-height-40px w100p"', true, '', - $is_management_allowed + $management_is_not_allowed || $recovery_disabled ); } @@ -684,9 +938,7 @@ if ($delete_command) { $result = alerts_delete_alert_command($id); - $auditMessage = ((bool) $result === true) - ? sprintf('Delete alert command #%s', $id) - : sprintf('Fail try to delete alert command #%s', $id); + $auditMessage = ((bool) $result === true) ? sprintf('Delete alert command #%s', $id) : sprintf('Fail try to delete alert command #%s', $id); db_pandora_audit( AUDIT_LOG_ALERT_MANAGEMENT, @@ -775,6 +1027,12 @@ $commands = array_slice($commands, $offset, $limit); foreach ($commands as $command) { $data = []; + if ((isset($config['ITSM_enabled']) === false || (bool) $config['ITSM_enabled'] === false) + && $command['name'] === 'Pandora ITSM Ticket' + ) { + continue; + } + $data['name'] = ''; // (IMPORTANT, DO NOT CHANGE!) only users with permissions over "All" group have access to edition of commands belonging to "All" group. diff --git a/pandora_console/godmode/alerts/alert_list.builder.php b/pandora_console/godmode/alerts/alert_list.builder.php index de07bce961..13151b4de9 100644 --- a/pandora_console/godmode/alerts/alert_list.builder.php +++ b/pandora_console/godmode/alerts/alert_list.builder.php @@ -105,8 +105,8 @@ $groups_user = users_get_groups($config['id_user']); if (!empty($groups_user)) { $groups = implode(',', array_keys($groups_user)); - if ($config['integria_enabled'] == 0) { - $integria_command = 'Integria IMS Ticket'; + if ($config['ITSM_enabled'] == 0) { + $integria_command = 'Pandora ITSM Ticket'; $sql = sprintf('SELECT taa.id, taa.name FROM talert_actions taa INNER JOIN talert_commands tac ON taa.id_alert_command = tac.id WHERE tac.name <> "%s" AND taa.id_group IN (%s)', $integria_command, $groups); } else { $sql = "SELECT id, name FROM talert_actions WHERE id_group IN ($groups)"; @@ -206,9 +206,10 @@ $table->data[2][0] = html_print_label_input_block( if (isset($step) === false) { echo '
'; - html_print_table($table); } +html_print_table($table); + if (isset($step) === false) { $output = ''; diff --git a/pandora_console/godmode/alerts/alert_list.list.php b/pandora_console/godmode/alerts/alert_list.list.php index fa848c845d..5d71895ecd 100644 --- a/pandora_console/godmode/alerts/alert_list.list.php +++ b/pandora_console/godmode/alerts/alert_list.list.php @@ -620,7 +620,21 @@ foreach ($simple_alerts as $alert) { $main_tab = 'module'; } - $data[0] = ''; + if ((int) agents_get_os($id_agent) === CLUSTER_OS_ID) { + $cluster = PandoraFMS\Cluster::loadFromAgentId($id_agent); + $agentAlertUrl = sprintf( + 'index.php?sec=estado&sec2=operation/cluster/cluster&op=update&id=%s&page=6', + $cluster->id() + ); + } else { + $agentAlertUrl = sprintf( + 'index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=%s&id_agente=%s', + $main_tab, + $id_agent + ); + } + + $data[0] = ''; if ($alert['disabled']) { $data[0] .= ''; diff --git a/pandora_console/godmode/alerts/alert_list.php b/pandora_console/godmode/alerts/alert_list.php index 17669ab248..1dc32ba086 100644 --- a/pandora_console/godmode/alerts/alert_list.php +++ b/pandora_console/godmode/alerts/alert_list.php @@ -650,6 +650,11 @@ if ($id_agente) { echo $messageAction; include_once 'godmode/alerts/alert_list.list.php'; + + if (isset($step) === true && $step === true) { + return; + } + $all_groups = agents_get_all_groups_agent($id_agente, $agent['id_grupo']); if (check_acl_one_of_groups($config['id_user'], $all_groups, 'LW') || check_acl_one_of_groups($config['id_user'], $all_groups, 'LM')) { include_once 'godmode/alerts/alert_list.builder.php'; diff --git a/pandora_console/godmode/alerts/configure_alert_action.php b/pandora_console/godmode/alerts/configure_alert_action.php index 033171953b..4883467c10 100644 --- a/pandora_console/godmode/alerts/configure_alert_action.php +++ b/pandora_console/godmode/alerts/configure_alert_action.php @@ -11,12 +11,12 @@ // 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. -// Load global vars +use PandoraFMS\ITSM\ITSM; +// Load global vars. global $config; require_once $config['homedir'].'/include/functions_alerts.php'; require_once $config['homedir'].'/include/functions_users.php'; -require_once $config['homedir'].'/include/functions_integriaims.php'; enterprise_include_once('meta/include/functions_alerts_meta.php'); check_login(); @@ -39,11 +39,19 @@ if (is_ajax()) { $get_integria_ticket_custom_types = (bool) get_parameter('get_integria_ticket_custom_types'); if ($get_integria_ticket_custom_types) { - $ticket_type_id = get_parameter('ticket_type_id'); + $ticket_type_id = (int) get_parameter('ticket_type_id', 0); + if (empty($ticket_type_id) === false) { + $error = ''; + try { + $ITSM = new ITSM(); + $fields = $ITSM->getObjecTypesFields($ticket_type_id); + } catch (\Throwable $th) { + $error = $th->getMessage(); + } - $api_call = integria_api_call(null, null, null, null, 'get_incident_fields', $ticket_type_id, false, 'json'); + echo json_encode($fields); + } - echo $api_call; return; } } @@ -150,6 +158,22 @@ if ($id) { $action = alerts_get_alert_action($id); $name = $action['name']; $id_command = $action['id_alert_command']; + $command = alerts_get_alert_command($id_command); + if (empty($command) === false && $command['name'] === io_safe_input('Pandora ITSM Ticket')) { + $action['field1'] = io_safe_output(($action['field1'] ?? $config['incident_title'])); + $action['field2'] = io_safe_output(($action['field2'] ?? $config['default_group'])); + $action['field3'] = io_safe_output(($action['field3'] ?? $config['default_criticity'])); + $action['field4'] = io_safe_output(($action['field4'] ?? $config['default_owner'])); + $action['field5'] = io_safe_output(($action['field5'] ?? $config['incident_type'])); + $action['field6'] = io_safe_output(($action['field6'] ?? $config['incident_status'])); + $action['field7'] = io_safe_output(($action['field7'] ?? $config['incident_content'])); + $action['field2_recovery'] = io_safe_output(($action['field2'] ?? $config['default_group'])); + $action['field3_recovery'] = io_safe_output(($action['field3'] ?? $config['default_criticity'])); + $action['field4_recovery'] = io_safe_output(($action['field4'] ?? $config['default_owner'])); + $action['field5_recovery'] = io_safe_output(($action['field5'] ?? $config['incident_type'])); + $action['field6_recovery'] = io_safe_output(($action['field6_recovery'] ?? $config['incident_status'])); + $action['field7_recovery'] = io_safe_output(($action['field7_recovery'] ?? $config['incident_content'])); + } $group = $action['id_group']; $action_threshold = $action['action_threshold']; @@ -235,11 +259,11 @@ $table->data[0][1] = html_print_label_input_block( ) ); -$create_ticket_command_id = db_get_value('id', 'talert_commands', 'name', io_safe_input('Integria IMS Ticket')); +$create_ticket_command_id = db_get_value('id', 'talert_commands', 'name', io_safe_input('Pandora ITSM Ticket')); $sql_exclude_command_id = ''; -if (!is_metaconsole() && $config['integria_enabled'] == 0 && $create_ticket_command_id !== false) { +if (!is_metaconsole() && $config['ITSM_enabled'] == 0 && $create_ticket_command_id !== false) { $sql_exclude_command_id = ' AND id <> '.$create_ticket_command_id; } @@ -355,24 +379,26 @@ $table_macros->data[1][2] = html_print_label_input_block( ) ); -// Selector will work only with Integria activated. -$integriaIdName = 'integria_wu'; -$table_macros->colspan[$integriaIdName][0] = 3; -$table_macros->data[$integriaIdName][0] = html_print_label_input_block( - __('Create workunit on recovery').ui_print_help_tip( - __('If closed status is set on recovery, a workunit will be added to the ticket in Integria IMS rather that closing the ticket.'), - true - ), - html_print_checkbox_switch_extended( - 'create_wu_integria', - 1, - $create_wu_integria, - false, - '', - $disabled_attr, - true - ) -); +if (empty($command) === false && $command['name'] === io_safe_input('Pandora ITSM Ticket')) { + // Selector will work only with Integria activated. + $integriaIdName = 'integria_wu'; + $table_macros->colspan[$integriaIdName][0] = 3; + $table_macros->data[$integriaIdName][0] = html_print_label_input_block( + __('Create workunit on recovery').ui_print_help_tip( + __('If closed status is set on recovery, a workunit will be added to the ticket in Pandora ITSM rather that closing the ticket.'), + true + ), + html_print_checkbox_switch_extended( + 'create_wu_integria', + 1, + $create_wu_integria, + false, + '', + $disabled_attr, + true + ) + ); +} for ($i = 1; $i <= $config['max_macro_fields']; $i++) { $table_macros->data['field'.$i][0] = html_print_image( @@ -504,7 +530,6 @@ $(document).ready (function () { }, function(data) { var max_macro_fields = ; - data.forEach(function(custom_field, key) { var custom_field_key = key+8; // Custom fields start from field 8. @@ -523,9 +548,9 @@ $(document).ready (function () { custom_field_row.html(new_html_content); switch (custom_field.type) { - case 'checkbox': - var checkbox_selector = $('input:not(.datepicker)[name=field'+custom_field_key+'_value\\[\\]]'); - var checkbox_recovery_selector = $('input:not(.datepicker)[name=field'+custom_field_key+'_recovery_value\\[\\]]'); + case 'CHECKBOX': + var checkbox_selector = $('input[type="checkbox"][name=field'+custom_field_key+'_value\\[\\]]'); + var checkbox_recovery_selector = $('input[type="checkbox"][name=field'+custom_field_key+'_recovery_value\\[\\]]'); checkbox_selector.on('change', function() { if (checkbox_selector.prop('checked')) { @@ -565,17 +590,17 @@ $(document).ready (function () { $('[name=field'+custom_field_key+'_value_container]').show(); $('[name=field'+custom_field_key+'_recovery_value_container]').show(); - $('input:not(.datepicker)[name=field'+custom_field_key+'_value\\[\\]]').show(); - $('input:not(.datepicker)[name=field'+custom_field_key+'_recovery_value\\[\\]]').show(); + $('input[type="checkbox"][name=field'+custom_field_key+'_value\\[\\]]').show(); + $('input[type="checkbox"][name=field'+custom_field_key+'_recovery_value\\[\\]]').show(); break; - case 'combo': + case 'COMBO': var combo_input = $('select[name=field'+custom_field_key+'_value\\[\\]]'); var combo_input_recovery = $('select[name=field'+custom_field_key+'_recovery_value\\[\\]]'); combo_input.find('option').remove(); combo_input_recovery.find('option').remove(); - var combo_values_array = custom_field.combo_value.split(','); + var combo_values_array = custom_field.comboValue.split(','); combo_values_array.forEach(function(value) { combo_input.append($(''.$response['name'].''; $data[1] = $response['description']; diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index 7cd504c8ac..e949eeaa83 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -477,8 +477,8 @@ if ($access_console_node === true) { $sub2['godmode/setup/setup§ion=ehorus']['text'] = __('eHorus'); $sub2['godmode/setup/setup§ion=ehorus']['refr'] = 0; - $sub2['godmode/setup/setup§ion=integria']['text'] = __('Integria IMS'); - $sub2['godmode/setup/setup§ion=integria']['refr'] = 0; + $sub2['godmode/setup/setup§ion=ITSM']['text'] = __('ITSM'); + $sub2['godmode/setup/setup§ion=ITSM']['refr'] = 0; enterprise_hook('module_library_submenu'); diff --git a/pandora_console/godmode/setup/setup.php b/pandora_console/godmode/setup/setup.php index 7e17f9fe4c..d7f496c2d6 100644 --- a/pandora_console/godmode/setup/setup.php +++ b/pandora_console/godmode/setup/setup.php @@ -170,13 +170,13 @@ if (check_acl($config['id_user'], 0, 'AW')) { } } -$buttons['integria'] = [ +$buttons['ITSM'] = [ 'active' => false, - 'text' => ''.html_print_image( - 'images/integria.png', + 'text' => ''.html_print_image( + 'images/itsm.png', true, [ - 'title' => __('Integria IMS'), + 'title' => __('ITSM'), 'class' => 'invert_filter', ] ).'', @@ -185,7 +185,7 @@ $buttons['integria'] = [ $buttons['ehorus'] = [ 'active' => false, 'text' => ''.html_print_image( - 'images/ehorus/ehorus.png', + 'images/RC.png', true, [ 'title' => __('eHorus'), @@ -303,10 +303,10 @@ switch ($section) { $help_header = 'setup_ehorus_tab'; break; - case 'integria': - $buttons['integria']['active'] = true; - $subpage = __('Integria IMS'); - $help_header = 'setup_integria_tab'; + case 'ITSM': + $buttons['ITSM']['active'] = true; + $subpage = __('Pandora ITSM'); + $help_header = 'setup_ITSM_tab'; break; case 'module_library': @@ -442,8 +442,8 @@ switch ($section) { include_once $config['homedir'].'/godmode/setup/setup_ehorus.php'; break; - case 'integria': - include_once $config['homedir'].'/godmode/setup/setup_integria.php'; + case 'ITSM': + include_once $config['homedir'].'/godmode/setup/setup_ITSM.php'; break; case 'gis': diff --git a/pandora_console/godmode/setup/setup_ITSM.php b/pandora_console/godmode/setup/setup_ITSM.php new file mode 100644 index 0000000000..3196ef677c --- /dev/null +++ b/pandora_console/godmode/setup/setup_ITSM.php @@ -0,0 +1,716 @@ +ping(); + $group_values = $ITSM->getGroups(); + $priority_values = $ITSM->getPriorities(); + $status_values = $ITSM->getStatus(); + $object_types_values = $ITSM->getObjectypes(); + if ((bool) get_parameter('update_config', 0) === true) { + $set_config_inventories = $ITSM->createNode( + [ + 'serverAuth' => $config['server_unique_identifier'], + 'apiPass' => $config['api_password'], + 'agentsForExecution' => $config['ITSM_agents_sync'], + 'path' => $config['ITSM_public_url'], + 'label' => array_keys(servers_get_names())[0], + 'nodeId' => $config['metaconsole_node_id'], + ] + ); + } + + try { + $node = $ITSM->getNode($config['server_unique_identifier']); + } catch (\Throwable $th) { + $node = []; + } +} catch (\Throwable $th) { + $error = $th->getMessage(); + $has_connection = false; +} + +if ($has_connection === false && $config['ITSM_enabled']) { + ui_print_error_message(__('ITSM API is not reachable, %s', $error)); +} + +$table_enable = new StdClass(); +$table_enable->data = []; +$table_enable->width = '100%'; +$table_enable->id = 'itsm-enable-setup'; +$table_enable->class = 'databox filters'; +$table_enable->size['name'] = '30%'; +$table_enable->style['name'] = 'font-weight: bold'; + +// Enable Pandora ITSM. +$row = []; +$row['name'] = __('Enable Pandora ITSM'); +$row['control'] = html_print_checkbox_switch('ITSM_enabled', 1, $config['ITSM_enabled'], true); +$table_enable->data['ITSM_enabled'] = $row; + +// Remote config table. +$table_remote = new StdClass(); +$table_remote->data = []; +$table_remote->width = '100%'; +$table_remote->styleTable = 'margin-bottom: 10px;'; +$table_remote->id = 'ITSM-remote-setup'; +$table_remote->class = 'databox filters filter-table-adv'; +$table_remote->size['hostname'] = '50%'; +$table_remote->size['api_pass'] = '50%'; + +// Enable ITSM user configuration. +$row = []; +$row['user_level'] = html_print_label_input_block( + __('Pandora ITSM configuration at user level'), + html_print_checkbox_switch( + 'ITSM_user_level_conf', + 1, + $config['ITSM_user_level_conf'], + true + ) +); +$table_remote->data['ITSM_user_level_conf'] = $row; + +// ITSM hostname. +$row = []; +$row['hostname'] = html_print_label_input_block( + __('URL to Pandora ITSM setup').ui_print_help_tip( + __('Full URL to your Pandora ITSM setup (e.g., http://192.168.1.20/integria/api/v1).'), + true + ), + html_print_input_text( + 'ITSM_hostname', + $config['ITSM_hostname'], + '', + 30, + 100, + true + ), + ['div_class' => 'ITSM-remote-setup-ITSM_hostname'] +); + +// ITSM token. +$row['password'] = html_print_label_input_block( + __('Token'), + html_print_input_password( + 'ITSM_token', + io_output_password($config['ITSM_token']), + '', + 30, + 100, + true + ), + ['div_class' => 'ITSM-remote-setup-ITSM_token'] +); +$table_remote->data['ITSM_token'] = $row; + +// Test. +$row = []; +$button_test = html_print_button( + __('Test'), + 'ITSM', + false, + '', + [ + 'icon' => 'cog', + 'mode' => 'secondary mini', + ], + true +); +$button_test .= ''; +$button_test .= ''; +$button_test .= ''; +$button_test .= ' '; + +$row['control'] = html_print_label_input_block( + __('Test connection pandora to ITSM'), + $button_test +); +$table_remote->data['ITSM_test'] = $row; + +$row = []; +$itsm_public_url = $config['ITSM_public_url']; +if (empty($itsm_public_url) === true) { + $itsm_public_url = $config['homeurl']; + if (isset($config['public_url']) === true && empty($config['public_url']) === false) { + $itsm_public_url = $config['public_url']; + } +} + +$row['publicUrl'] = html_print_label_input_block( + __('URL conect to API %s', get_product_name()).ui_print_help_tip( + __('Full URL to your Pandora (e.g., http://192.168.1.20).'), + true + ), + html_print_input_text( + 'ITSM_public_url', + $itsm_public_url, + '', + 30, + 100, + true + ) +); + +$row['agentsSync'] = html_print_label_input_block( + __('Number Agents to synchronize').ui_print_help_tip( + __('Number of agents that will synchronize at the same time, minimum 10 max 1000'), + true + ), + html_print_input_number( + [ + 'name' => 'ITSM_agents_sync', + 'min' => 10, + 'max' => 1000, + 'value' => ($config['ITSM_agents_sync'] ?? 20), + ] + ) +); + +$table_remote->data['ITSM_sync_inventory'] = $row; + +// Test. +$row = []; +$button_test_pandora = html_print_button( + __('Test'), + 'ITSM-pandora', + false, + '', + [ + 'icon' => 'cog', + 'mode' => 'secondary mini', + ], + true +); +$button_test_pandora .= ''; +$button_test_pandora .= ''; +$button_test_pandora .= ''; +$button_test_pandora .= ' '; + +$row['control-test'] = html_print_label_input_block( + __('Test conection ITSM to pandora'), + $button_test_pandora +); + +if (empty($node) === false) { + $progressbar = ''; + + $progress = 0; + if (empty($node['total']) === false) { + if (empty($node['accumulate']) === true) { + $node['accumulate'] = 0; + } + + $progress = round(($node['accumulate'] * 100 / $node['total'])); + } + + if (empty($node['error']) === false) { + $progressbar = $node['error']; + } else if (empty($node['total']) === false) { + $progressbar = '
'; + $progressbar .= ui_progress($progress, '150px', '1.3', '#14524f', true, '', false, 'margin-right:5px; color:#c0ccdc'); + $progressbar .= ' ( '.$node['accumulate'].' / '.$node['total'].' ) '.__('Agents'); + $progressbar .= '
'; + } else { + $progressbar = '--'; + } + + // $progressbar .= (empty($node['dateStart']) === false) ? human_time_comparation($node['dateStart']) : __('Never'); + $row['control-test-pandora'] = html_print_label_input_block( + __('Progress agents to synch'), + $progressbar + ); +} + +$table_remote->data['ITSM_test_pandora'] = $row; + +// Alert settings. +$table_alert_settings = new StdClass(); +$table_alert_settings->data = []; +$table_alert_settings->rowspan = []; +$table_alert_settings->width = '100%'; +$table_alert_settings->styleTable = 'margin-bottom: 10px;'; +$table_alert_settings->id = 'ITSM-settings-setup'; +$table_alert_settings->class = 'databox filters filter-table-adv'; +$table_alert_settings->size[0] = '50%'; +$table_alert_settings->size[1] = '50%'; + +// Alert incident title. +$table_alert_settings->data[0][0] = html_print_label_input_block( + __('Title'), + html_print_input_text( + 'incident_title', + $config['incident_title'], + __('Name'), + 50, + 100, + true, + false, + false + ) +); + +// Alert incident description. +$table_alert_settings->rowspan[0][1] = 3; +$table_alert_settings->data[0][1] = html_print_label_input_block( + __('Ticket body'), + html_print_textarea( + 'incident_content', + 9, + 25, + $config['incident_content'], + '', + true + ) +); + +// Alert default group. +$table_alert_settings->data[1][0] = html_print_label_input_block( + __('Group'), + html_print_select( + $group_values, + 'default_group', + $config['default_group'], + '', + '', + 0, + true, + false, + true, + '', + false + ) +); + +// Alert default owner. +$table_alert_settings->data[2][0] = html_print_label_input_block( + __('Owner'), + html_print_autocomplete_users_from_pandora_itsm( + 'default_owner', + $config['default_owner'], + true, + '30', + false, + false, + 'w100p' + ), + ['div_class' => 'inline'] +); + +// Alert default incident status. +$table_alert_settings->data[3][0] = html_print_label_input_block( + __('Status'), + html_print_select( + $status_values, + 'incident_status', + $config['incident_status'], + '', + __('Select'), + 0, + true, + false, + true, + '', + false + ) +); + +// Alert default criticity. +$table_alert_settings->data[3][1] = html_print_label_input_block( + __('Priority'), + html_print_select( + $priority_values, + 'default_criticity', + $config['default_criticity'], + '', + __('Select'), + 0, + true, + false, + true, + '', + false + ) +); + +// Alert default incident type. +$table_alert_settings->data[4][0] = html_print_label_input_block( + __('Type'), + html_print_select( + $object_types_values, + 'incident_type', + $config['incident_type'], + '', + __('Select'), + 0, + true, + false, + true, + '', + false + ) +); + +// Custom response settings. +$table_cr_settings = new StdClass(); +$table_cr_settings->data = []; +$table_cr_settings->width = '100%'; +$table_cr_settings->styleTable = 'margin-bottom: 10px;'; +$table_cr_settings->id = 'ITSM-cr-settings-setup'; +$table_cr_settings->class = 'databox filters filter-table-adv'; +$table_cr_settings->size[0] = '50%'; +$table_cr_settings->size[1] = '50%'; + +// Custom response incident title. +$table_cr_settings->data[0][0] = html_print_label_input_block( + __('Title'), + html_print_input_text( + 'cr_incident_title', + $config['cr_incident_title'], + __('Name'), + 50, + 100, + true, + false, + false + ) +); + +// Custom response incident description. +$table_cr_settings->rowspan[0][1] = 3; +$table_cr_settings->data[0][1] = html_print_label_input_block( + __('Ticket body'), + html_print_textarea( + 'cr_incident_content', + 9, + 25, + $config['cr_incident_content'], + '', + true + ) +); + +// Custom response default group. +$table_cr_settings->data[1][0] = html_print_label_input_block( + __('Group'), + html_print_select( + $group_values, + 'cr_default_group', + $config['cr_default_group'], + '', + __('Select'), + 0, + true, + false, + true, + '', + false + ) +); + +// Custom response default owner. +$table_cr_settings->data[2][0] = html_print_label_input_block( + __('Owner'), + html_print_autocomplete_users_from_pandora_itsm( + 'cr_default_owner', + $config['cr_default_owner'], + true, + '30', + false, + false, + 'w100p' + ), + ['div_class' => 'inline'] +); + +// Custom response default incident status. +$row = []; +$table_cr_settings->data[3][0] = html_print_label_input_block( + __('Status'), + html_print_select( + $status_values, + 'cr_incident_status', + $config['cr_incident_status'], + '', + __('Select'), + 0, + true, + false, + true, + '', + false + ) +); + +// Custom response default criticity. +$table_cr_settings->data[3][1] = html_print_label_input_block( + __('Priority'), + html_print_select( + $priority_values, + 'cr_default_criticity', + $config['cr_default_criticity'], + '', + __('Select'), + 0, + true, + false, + true, + '', + false + ) +); + +// Custom response default incident type. +$table_cr_settings->data[4][0] = html_print_label_input_block( + __('Type'), + html_print_select( + $object_types_values, + 'cr_incident_type', + $config['cr_incident_type'], + '', + __('Select'), + 0, + true, + false, + true, + '', + false + ) +); + +// Print. +echo '
'; + +echo ""; +html_print_input_hidden('update_config', 1); + +// Form enable. +echo '
'; +html_print_table($table_enable); +echo '
'; + +// Form remote. +echo '
'; +echo '
'; +echo ''.__('Pandora ITSM API settings').''; + +html_print_table($table_remote); + +echo '
'; +echo '
'; + +if ($has_connection !== false) { + // Form alert default settings. + echo '
'; + echo '
'; + echo ''.__('Alert default values').' '.ui_print_help_icon('alert_macros', true).''; + + html_print_table($table_alert_settings); + + echo '
'; + echo '
'; + + // Form custom response default settings. + echo '
'; + echo '
'; + echo ''.__('Event custom response default values').' '.ui_print_help_icon('alert_macros', true).''; + + html_print_table($table_cr_settings); + + echo '
'; + echo '
'; + + $update_button = html_print_submit_button( + __('Update'), + 'update_button', + false, + ['icon' => 'update'], + true + ); +} else { + $update_button = html_print_submit_button( + __('Update and continue'), + 'update_button', + false, + ['icon' => 'update'], + true + ); +} + +html_print_action_buttons($update_button); + +echo '
'; + +ui_require_javascript_file('ITSM'); + +?> + + diff --git a/pandora_console/godmode/setup/setup_auth.php b/pandora_console/godmode/setup/setup_auth.php index 6616cd765c..40a816a6fa 100644 --- a/pandora_console/godmode/setup/setup_auth.php +++ b/pandora_console/godmode/setup/setup_auth.php @@ -371,7 +371,7 @@ if (is_ajax() === true) { case 'pandora': case 'ad': case 'saml': - case 'integria': + case 'ITSM': // Add enterprise authentication options. if (enterprise_installed() === true) { add_enterprise_auth_options($table, $type_auth); diff --git a/pandora_console/godmode/setup/setup_integria.php b/pandora_console/godmode/setup/setup_integria.php deleted file mode 100644 index a01927c017..0000000000 --- a/pandora_console/godmode/setup/setup_integria.php +++ /dev/null @@ -1,997 +0,0 @@ - ($login_result !== false) ? 1 : 0]); - - return; -} - -$has_connection = integria_api_call(null, null, null, null, 'get_login', []); - -if ($has_connection === false && $config['integria_enabled']) { - ui_print_error_message(__('Integria IMS API is not reachable')); -} - -if (get_parameter('update_config', 0) == 1) { - // Try to retrieve event response 'Create incident in IntegriaIMS from event' to check if it exists. - $event_response_exists = db_get_row_filter('tevent_response', ['name' => io_safe_input('Create ticket in IntegriaIMS from event')]); - - // Try to retrieve command 'Integia IMS Ticket' to check if it exists. - $command_exists = db_get_row_filter('talert_commands', ['name' => io_safe_input('Integria IMS Ticket')]); - - if ($config['integria_enabled'] == 1) { - if ($event_response_exists === false) { - // Create 'Create incident in IntegriaIMS from event' event response only when user enables IntegriaIMS integration and it does not exist in database. - db_process_sql_insert( - 'tevent_response', - [ - 'name' => io_safe_input('Create ticket in IntegriaIMS from event'), - 'description' => io_safe_input('Create a ticket in Integria IMS from an event'), - 'target' => io_safe_input('index.php?sec=incident&sec2=operation/incidents/configure_integriaims_incident&from_event=_event_id_'), - 'type' => 'url', - 'id_group' => '0', - 'modal_width' => '0', - 'modal_height' => '0', - 'new_window' => '1', - 'params' => '', - 'server_to_exec' => '0', - ] - ); - } - - $ticket_types = integria_api_call(null, null, null, null, 'get_types', '', false, 'json'); - - $types_string = ''; - - if ($ticket_types !== '') { - foreach (json_decode($ticket_types, true) as $key => $value) { - $types_string .= $value['id'].','.$value['name'].';'; - } - } - - if ($command_exists === false) { - // Create 'Integria IMS Ticket' command only when user enables IntegriaIMS integration and it does not exist in database. - $id_command_inserted = db_process_sql_insert( - 'talert_commands', - [ - 'name' => io_safe_input('Integria IMS Ticket'), - 'command' => io_safe_input('Internal type'), - 'internal' => 1, - 'description' => io_safe_input('Create a ticket in Integria IMS'), - 'fields_descriptions' => '["'.io_safe_input('Ticket title').'","'.io_safe_input('Ticket group ID').'","'.io_safe_input('Ticket priority').'","'.io_safe_input('Ticket owner').'","'.io_safe_input('Ticket type').'","'.io_safe_input('Ticket status').'","'.io_safe_input('Ticket description').'","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_"]', - 'fields_values' => '["", "", "","","'.$types_string.'","","","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_"]', - ] - ); - - // Create 'Create Integria IMS Ticket' action only when user enables IntegriaIMS integration and command exists in database. - $action_values = [ - 'field1' => io_safe_input($config['incident_title']), - 'field1_recovery' => io_safe_input($config['incident_title']), - 'field2' => io_safe_input($config['default_group']), - 'field2_recovery' => io_safe_input($config['default_group']), - 'field3' => io_safe_input($config['default_criticity']), - 'field3_recovery' => io_safe_input($config['default_criticity']), - 'field4' => io_safe_input($config['default_owner']), - 'field4_recovery' => io_safe_input($config['default_owner']), - 'field5' => io_safe_input($config['incident_type']), - 'field5_recovery' => io_safe_input($config['incident_type']), - 'field6' => io_safe_input($config['incident_status']), - 'field6_recovery' => io_safe_input($config['incident_status']), - 'field7' => io_safe_input($config['incident_content']), - 'field7_recovery' => io_safe_input($config['incident_content']), - 'id_group' => 0, - 'action_threshold' => 0, - ]; - - alerts_create_alert_action(io_safe_input('Create Integria IMS ticket'), $id_command_inserted, $action_values); - } else { - // Update 'Integria IMS Ticket' command with ticket types retrieved from Integria IMS. - $sql_update_command_values = sprintf( - ' - UPDATE talert_commands - SET fields_values = \'["","","","","%s","","","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_","_integria_type_custom_field_"]\' - WHERE name="%s"', - $types_string, - io_safe_input('Integria IMS Ticket') - ); - - db_process_sql($sql_update_command_values); - - // Update those actions that make use of 'Integria IMS Ticket' command when setup default fields are updated. Empty fields in actions will be filled in with default values. - $update_action_values = [ - $config['incident_title'], - $config['default_group'], - $config['default_criticity'], - $config['default_owner'], - $config['incident_type'], - $config['incident_status'], - $config['incident_content'], - ]; - - foreach ($update_action_values as $key => $value) { - $field_key = ($key + 1); - - $sql_update_action_field = sprintf( - ' - UPDATE talert_actions taa - INNER JOIN talert_commands tac - ON taa.id_alert_command=tac.id - SET field%s= "%s" - WHERE tac.name="Integria IMS Ticket" - AND ( - taa.field%s IS NULL OR taa.field%s="" - )', - $field_key, - $value, - $field_key, - $field_key, - $field_key - ); - - db_process_sql($sql_update_action_field); - } - - foreach ($update_action_values as $key => $value) { - $field_key = ($key + 1); - - $sql_update_action_recovery_field = sprintf( - ' - UPDATE talert_actions taa - INNER JOIN talert_commands tac - ON taa.id_alert_command=tac.id - SET field%s_recovery = "%s" - WHERE tac.name="Integria IMS Ticket" - AND ( - taa.field%s_recovery IS NULL OR taa.field%s_recovery="" - )', - $field_key, - $value, - $field_key, - $field_key, - $field_key - ); - - db_process_sql($sql_update_action_recovery_field); - } - } - } else { - if ($event_response_exists !== false) { - // Delete 'Create incident in IntegriaIMS from event' event response if it does exist and IntegriaIMS integration is disabled. - db_process_sql_delete('tevent_response', ['name' => io_safe_input('Create ticket in IntegriaIMS from event')]); - } - } -} - -// Get parameters from Integria IMS API. -$integria_group_values = []; -$integria_criticity_values = []; -$integria_users_values = []; -$integria_types_values = []; -$integria_status_values = []; - -$integria_groups_csv = integria_api_call(null, null, null, null, 'get_groups', []); - -get_array_from_csv_data_pair($integria_groups_csv, $integria_group_values); - -$integria_status_csv = integria_api_call(null, null, null, null, 'get_incidents_status', []); - -get_array_from_csv_data_pair($integria_status_csv, $integria_status_values); - -$integria_criticity_levels_csv = integria_api_call(null, null, null, null, 'get_incident_priorities', []); - -get_array_from_csv_data_pair($integria_criticity_levels_csv, $integria_criticity_values); - -$integria_users_csv = integria_api_call(null, null, null, null, 'get_users', []); - -$csv_array = explode("\n", $integria_users_csv); - -foreach ($csv_array as $csv_line) { - if (empty($csv_line) === false) { - $integria_users_values[$csv_line] = $csv_line; - } -} - -$integria_types_csv = integria_api_call(null, null, null, null, 'get_types', []); - -get_array_from_csv_data_pair($integria_types_csv, $integria_types_values); - -// Enable table. -$table_enable = new StdClass(); -$table_enable->data = []; -$table_enable->width = '100%'; -$table_enable->id = 'integria-enable-setup'; -$table_enable->class = 'databox filters'; -$table_enable->size['name'] = '30%'; -$table_enable->style['name'] = 'font-weight: bold'; - -// Enable Integria. -$row = []; -$row['name'] = __('Enable Integria IMS'); -$row['control'] = html_print_checkbox_switch('integria_enabled', 1, $config['integria_enabled'], true); -$table_enable->data['integria_enabled'] = $row; - -// Remote config table. -$table_remote = new StdClass(); -$table_remote->data = []; -$table_remote->width = '100%'; -$table_remote->styleTable = 'margin-bottom: 10px;'; -$table_remote->id = 'integria-remote-setup'; -$table_remote->class = 'databox filters filter-table-adv'; -$table_remote->size['hostname'] = '50%'; -$table_remote->size['api_pass'] = '50%'; - -// Enable Integria user configuration. -$row = []; -$row['user_level'] = html_print_label_input_block( - __('Integria configuration at user level'), - html_print_checkbox_switch( - 'integria_user_level_conf', - 1, - $config['integria_user_level_conf'], - true - ) -); -$table_remote->data['integria_user_level_conf'] = $row; - -// Integria user. -$row = []; -$row['user'] = html_print_label_input_block( - __('User'), - html_print_input_text( - 'integria_user', - $config['integria_user'], - '', - 30, - 100, - true - ), - ['div_class' => 'integria-remote-setup-integria_user'] -); - -// Integria password. -$row['password'] = html_print_label_input_block( - __('Password'), - html_print_input_password( - 'integria_pass', - io_output_password($config['integria_pass']), - '', - 30, - 100, - true - ), - ['div_class' => 'integria-remote-setup-integria_pass'] -); -$table_remote->data['integria_pass'] = $row; - -// Integria hostname. -$row = []; -$row['hostname'] = html_print_label_input_block( - __('URL to Integria IMS setup').ui_print_help_tip(__('Full URL to your Integria IMS setup (e.g., http://192.168.1.20/integria, https://support.mycompany.com).'), true), - html_print_input_text( - 'integria_hostname', - $config['integria_hostname'], - '', - 30, - 100, - true - ), - ['div_class' => 'integria-remote-setup-integria_hostname'] -); - -// API password. -$row['api_pass'] = html_print_label_input_block( - __('API Password'), - html_print_input_password( - 'integria_api_pass', - io_output_password($config['integria_api_pass']), - '', - 30, - 100, - true - ), - ['div_class' => 'integria-remote-setup-integria_api_pass'] -); -$table_remote->data['integria_api_pass'] = $row; - -// Request timeout. -$row = []; -$row['req_timeout'] = html_print_label_input_block( - __('Request timeout'), - html_print_input_text( - 'integria_req_timeout', - $config['integria_req_timeout'], - '', - 3, - 10, - true - ), - ['div_class' => 'integria-remote-setup-integria_req_timeout'] -); -$table_remote->data['integria_req_timeout'] = $row; - -$row = []; -$row['control'] = __('Inventory'); -$row['control'] .= html_print_button( - __('Sync inventory'), - 'sync-inventory', - false, - '', - [ - 'icon' => 'cog', - 'mode' => 'secondary mini', - ], - true -); -$row['control'] .= ''; -$row['control'] .= ''; -$row['control'] .= ''; -$table_remote->data['integria_sync_inventory'] = $row; - -// Alert settings. -$table_alert_settings = new StdClass(); -$table_alert_settings->data = []; -$table_alert_settings->width = '100%'; -$table_alert_settings->styleTable = 'margin-bottom: 10px;'; -$table_alert_settings->id = 'integria-cr-settings-setup'; -$table_alert_settings->class = 'databox filters filter-table-adv'; -$table_alert_settings->size[0] = '50%'; -$table_alert_settings->size[1] = '50%'; - -// Alert incident title. -$row = []; -$row[0] = html_print_label_input_block( - __('Title'), - html_print_input_text( - 'incident_title', - $config['incident_title'], - __('Name'), - 50, - 100, - true, - false, - false - ) -); - -// Alert incident description. -$row[1] = html_print_label_input_block( - __('Ticket body'), - html_print_textarea( - 'incident_content', - 3, - 25, - $config['incident_content'], - '', - true - ) -); -$table_alert_settings->data[0] = $row; - -// Alert default group. -$row = []; -$row[0] = html_print_label_input_block( - __('Group'), - html_print_select( - $integria_group_values, - 'default_group', - $config['default_group'], - '', - __('Select'), - 0, - true, - false, - true, - '', - false - ) -); - -// Alert default criticity. -$row[1] = html_print_label_input_block( - __('Priority'), - html_print_select( - $integria_criticity_values, - 'default_criticity', - $config['default_criticity'], - '', - __('Select'), - 0, - true, - false, - true, - '', - false - ) -); -$table_alert_settings->data[1] = $row; - -// Alert default owner. -$row = []; -$row[0] = html_print_label_input_block( - __('Owner'), - html_print_autocomplete_users_from_integria( - 'default_owner', - $config['default_owner'], - true, - '30', - false, - false, - 'w100p' - ), - ['div_class' => 'inline'] -); - -// Alert default incident type. -$row[1] = html_print_label_input_block( - __('Type'), - html_print_select( - $integria_types_values, - 'incident_type', - $config['incident_type'], - '', - __('Select'), - 0, - true, - false, - true, - '', - false - ) -); -$table_alert_settings->data[2] = $row; - -// Alert default incident status. -$row = []; -$row[0] = html_print_label_input_block( - __('Status'), - html_print_select( - $integria_status_values, - 'incident_status', - $config['incident_status'], - '', - __('Select'), - 0, - true, - false, - true, - '', - false - ) -); -$table_alert_settings->data[3] = $row; - -// Custom response settings. -$table_cr_settings = new StdClass(); -$table_cr_settings->data = []; -$table_cr_settings->width = '100%'; -$table_cr_settings->styleTable = 'margin-bottom: 10px;'; -$table_cr_settings->id = 'integria-cr-settings-setup'; -$table_cr_settings->class = 'databox filters filter-table-adv'; -$table_cr_settings->size[0] = '50%'; -$table_cr_settings->size[1] = '50%'; - -// Custom response incident title. -$row = []; -$row[0] = html_print_label_input_block( - __('Title'), - html_print_input_text( - 'cr_incident_title', - $config['cr_incident_title'], - __('Name'), - 50, - 100, - true, - false, - false - ) -); - -// Custom response incident description. -$row[1] = html_print_label_input_block( - __('Ticket body'), - html_print_textarea( - 'cr_incident_content', - 3, - 25, - $config['cr_incident_content'], - '', - true - ) -); - -$table_cr_settings->data[0] = $row; - -// Custom response default group. -$row = []; -$row[0] = html_print_label_input_block( - __('Group'), - html_print_select( - $integria_group_values, - 'cr_default_group', - $config['cr_default_group'], - '', - __('Select'), - 0, - true, - false, - true, - '', - false - ) -); - -// Custom response default criticity. -$row[1] = html_print_label_input_block( - __('Priority'), - html_print_select( - $integria_criticity_values, - 'cr_default_criticity', - $config['cr_default_criticity'], - '', - __('Select'), - 0, - true, - false, - true, - '', - false - ) -); -$table_cr_settings->data[1] = $row; - -// Custom response default owner. -$row = []; -$row[0] = html_print_label_input_block( - __('Owner'), - html_print_autocomplete_users_from_integria( - 'cr_default_owner', - $config['cr_default_owner'], - true, - '30', - false, - false, - 'w100p' - ), - ['div_class' => 'inline'] -); - -// Custom response default incident type. -$row[1] = html_print_label_input_block( - __('Type'), - html_print_select( - $integria_types_values, - 'cr_incident_type', - $config['cr_incident_type'], - '', - __('Select'), - 0, - true, - false, - true, - '', - false - ) -); -$table_cr_settings->data[2] = $row; - -// Custom response default incident status. -$row = []; -$row[0] = html_print_label_input_block( - __('Status'), - html_print_select( - $integria_status_values, - 'cr_incident_status', - $config['cr_incident_status'], - '', - __('Select'), - 0, - true, - false, - true, - '', - false - ) -); -$table_cr_settings->data[3] = $row; - -// Test. -$row = []; -$row['control'] = __('Test connection'); -$row['control'] .= html_print_button( - __('Test'), - 'test-integria', - false, - '', - [ - 'icon' => 'cog', - 'mode' => 'secondary mini', - ], - true -); -$row['control'] .= ''; -$row['control'] .= ''; -$row['control'] .= ''; -$row['control'] .= ' '; -$table_remote->data['integria_test'] = $row; - -// Print. -echo ''; - -echo "
"; -html_print_input_hidden('update_config', 1); - -// Form enable. -echo '
'; -html_print_table($table_enable); -echo '
'; - -// Form remote. -echo '
'; -echo '
'; -echo ''.__('Integria API settings').''; - -html_print_table($table_remote); - -echo '
'; -echo '
'; - -if ($has_connection != false) { - // Form alert default settings. - echo '
'; - echo '
'; - echo ''.__('Alert default values').' '.ui_print_help_icon('alert_macros', true).''; - - html_print_table($table_alert_settings); - - echo '
'; - echo '
'; - - // Form custom response default settings. - echo '
'; - echo '
'; - echo ''.__('Event custom response default values').' '.ui_print_help_icon('alert_macros', true).''; - - html_print_table($table_cr_settings); - - echo '
'; - echo '
'; - - $update_button = html_print_submit_button( - __('Update'), - 'update_button', - false, - ['icon' => 'update'], - true - ); -} else { - $update_button = html_print_submit_button( - __('Update and continue'), - 'update_button', - false, - ['icon' => 'update'], - true - ); -} - -html_print_action_buttons($update_button); - -echo '
'; - -?> - - diff --git a/pandora_console/godmode/users/configure_user.php b/pandora_console/godmode/users/configure_user.php index df90f49315..08040f839c 100644 --- a/pandora_console/godmode/users/configure_user.php +++ b/pandora_console/godmode/users/configure_user.php @@ -333,6 +333,7 @@ if ($create_user === true) { $values['default_custom_view'] = (int) get_parameter('default_custom_view'); $values['time_autorefresh'] = (int) get_parameter('time_autorefresh', 0); $values['show_tips_startup'] = (int) get_parameter_switch('show_tips_startup'); + $values['integria_user_level_pass'] = (string) get_parameter('integria_user_level_pass'); $dashboard = get_parameter('dashboard', ''); $visual_console = get_parameter('visual_console', ''); @@ -624,6 +625,7 @@ if ($update_user) { $values['ehorus_user_level_enabled'] = (bool) get_parameter('ehorus_user_level_enabled', false); $values['ehorus_user_level_user'] = (string) get_parameter('ehorus_user_level_user'); $values['ehorus_user_level_pass'] = (string) get_parameter('ehorus_user_level_pass'); + $values['integria_user_level_pass'] = (string) get_parameter('integria_user_level_pass'); $values['middlename'] = get_parameter('middlename', 0); diff --git a/pandora_console/godmode/users/user_management.php b/pandora_console/godmode/users/user_management.php index 0675c39be5..9991736583 100644 --- a/pandora_console/godmode/users/user_management.php +++ b/pandora_console/godmode/users/user_management.php @@ -789,6 +789,62 @@ $userManagementTable->data['fields_addSettings'][1] .= html_print_div( true ); + +if ($config['ITSM_enabled'] && $config['ITSM_user_level_conf']) { + // Pandora ITSM user remote login. + $table_ITSM = new StdClass(); + $table_ITSM->data = []; + $table_ITSM->width = '100%'; + $table_ITSM->id = 'ITSM-remote-setup'; + $table_ITSM->class = 'white_box'; + $table_ITSM->size['name'] = '30%'; + $table_ITSM->style['name'] = 'font-weight: bold'; + + // Pandora ITSM user level authentication. + // Title. + $row = []; + $row['control'] = '

'.__('Pandora ITSM user configuration').':

'; + $table_ITSM->data['ITSM_user_level_conf'] = $row; + + // Pandora ITSM pass. + $row = []; + $row['name'] = __('Token'); + $row['control'] = html_print_input_password( + 'integria_user_level_pass', + io_output_password($user_info['integria_user_level_pass']), + '', + 100, + 100, + true + ); + $table_ITSM->data['integria_user_level_pass'] = $row; + + // Test. + $ITSM_host = db_get_value('value', 'tconfig', 'token', 'ITSM_hostname'); + + $row = []; + $row['name'] = __('Test'); + $row['control'] = html_print_button( + __('Start'), + 'ITSM', + false, + '', + [ + 'icon' => 'cog', + 'mode' => 'secondary mini', + ], + true + ); + $row['control'] .= ' '; + $row['control'] .= ' '; + $row['control'] .= ' '; + $row['control'] .= ''; + $table_ITSM->data['ITSM_test'] = $row; + + $userManagementTable->colspan['pandoraitsm'] = 2; + $userManagementTable->data['pandoraitsm'] = html_print_table($table_ITSM, true); +} + if (isset($CodeQRTable) === true || isset($apiTokenContent) === true) { // QR Code and API Token advice. $titleQr = ''.__('Contact details (QR)').''; @@ -814,16 +870,24 @@ $vcard_data['organization'] = io_safe_output(get_product_name()); $vcard_data['url'] = ui_get_full_url('index.php'); $vcard_json = json_encode($vcard_data); + +ui_require_javascript_file('ITSM'); ?> __('Informative')]).html_print_image('images/dot_green.png', true, ['title' => __('Informative')]).html_print_image('images/dot_yellow.png', true, ['title' => __('Informative')]); - break; - - case 1: - $img = html_print_image('images/dot_green.png', true, ['title' => __('Low')]).html_print_image('images/dot_yellow.png', true, ['title' => __('Low')]).html_print_image('images/dot_yellow.png', true, ['title' => __('Low')]); - break; - - case 2: - $img = html_print_image('images/dot_yellow.png', true, ['title' => __('Medium')]).html_print_image('images/dot_yellow.png', true, ['title' => __('Medium')]).html_print_image('images/dot_red.png', true, ['title' => __('Medium')]); - break; - - case 3: - $img = html_print_image('images/dot_yellow.png', true, ['title' => __('Serious')]).html_print_image('images/dot_red.png', true, ['title' => __('Serious')]).html_print_image('images/dot_red.png', true, ['title' => __('Serious')]); - break; - - case 4: - $img = html_print_image('images/dot_red.png', true, ['title' => __('Very serious')]).html_print_image('images/dot_red.png', true, ['title' => __('Very serious')]).html_print_image('images/dot_red.png', true, ['title' => __('Very serious')]); - break; - - case 10: - $img = html_print_image('images/dot_green.png', true, ['title' => __('Maintenance')]).html_print_image('images/dot_green.png', true, ['title' => __('Maintenance')]).html_print_image('images/dot_green.png', true, ['title' => __('Maintenance')]); - break; - } - - if ($return === false) { - echo $img; - } - - return $img; -} - - -/** - * Gets all the possible status for incidents in an array - * - * @return array The several status with their values - */ -function incidents_get_status() -{ - $fields = []; - $fields[0] = __('Active incidents'); - $fields[1] = __('Active incidents, with comments'); - $fields[2] = __('Rejected incidents'); - $fields[3] = __('Expired incidents'); - $fields[13] = __('Closed incidents'); - - return $fields; -} - - -/** - * Prints the image tag for passed status - * - * @param integer $id_status: Which status to return the image to - * - * @return string The string with the image tag - */ -function incidents_print_status_img($id_status, $return=false) -{ - switch ($id_status) { - case 0: - $img = html_print_image('images/dot_red.png', true, ['title' => __('Active incidents')]); - break; - - case 1: - $img = html_print_image('images/dot_yellow.png', true, ['title' => __('Active incidents, with comments')]); - break; - - case 2: - $img = html_print_image('images/dot_blue.png', true, ['title' => __('Rejected incidents')]); - break; - - case 3: - $img = html_print_image('images/dot_green.png', true, ['title' => __('Expired incidents')]); - break; - - case 13: - $img = html_print_image('images/dot_white.png', true, ['title' => __('Closed incidents')]); - break; - } - - if ($return === false) { - echo $img; - } - - return $img; -} - - -/** - * Updates the last user (either by adding an attachment, note or the incident itself) - * Named after the UNIX touch utility - * - * @param integer $id_incident: A single incident or an array of incidents - * - * @return boolean True if it was done, false if it wasn't - */ -function incidents_process_touch($id_incident) -{ - global $config; - - $id_incident = (array) safe_int($id_incident, 1); - // Make sure we have all positive int's - if (empty($id_incident)) { - return false; - } - - if (empty($id_incident)) { - return false; - } - - return db_process_sql_update('tincidencia', ['id_lastupdate' => $config['id_user']], ['id_incidencia' => $id_incident]); -} - - -/** - * Updates the owner (named after the UNIX utility chown) - * - * @param integer $id_incident: A single incident or an array of incidents - * - * @return boolean True if it was done, false if it wasn't - */ -function incidents_process_chown($id_incident, $owner=false) -{ - if ($owner === false) { - global $config; - $owner = $config['id_user']; - } - - $id_incident = (array) safe_int($id_incident, 1); - // Make sure we have all positive int's - if (empty($id_incident)) { - return false; - } - - $id_incident = implode(',', $id_incident); - $sql = sprintf("UPDATE tincidencia SET id_usuario = '%s' WHERE id_incidencia IN (%s)", $owner, $id_incident); - - return db_process_sql($sql); -} - - -/** - * Get the author of an incident. - * - * @param integer $id_incident Incident id. - * - * @return string The author of an incident - */ -function incidents_get_author($id_incident) -{ - if ($id_incident < 1) { - return ''; - } - - return (string) db_get_value('id_creator', 'tincidencia', 'id_incidencia', (int) $id_incident); -} - - -/** - * Get the owner of an incident. - * - * @param integer $id_incident Incident id. - * - * @return string The last updater of an incident - */ -function incidents_get_owner($id_incident) -{ - if ($id_incident < 1) { - return ''; - } - - return (string) db_get_value('id_usuario', 'tincidencia', 'id_incidencia', (int) $id_incident); -} - - -/** - * Get the last updater of an incident. - * - * @param integer $id_incident Incident id. - * - * @return string The last updater of an incident - */ -function incidents_get_lastupdate($id_incident) -{ - if ($id_incident < 1) { - return ''; - } - - return (string) db_get_value('id_lastupdate', 'tincidencia', 'id_incidencia', (int) $id_incident); -} - - -/** - * Get the group id of an incident. - * - * @param integer $id_incident Incident id. - * - * @return integer The group id of an incident - */ -function incidents_get_group($id_incident) -{ - if ($id_incident < 1) { - return 0; - } - - return (int) db_get_value('id_grupo', 'tincidencia', 'id_incidencia', (int) $id_incident); -} - - -/** - * Delete an incident out the database. - * - * @param mixed $id_inc An int or an array of ints to be deleted - * - * @return boolean True if incident was succesfully deleted, false if not - */ -function incidents_delete_incident($id_incident) -{ - global $config; - $ids = (array) safe_int($id_incident, 1); - // Make the input an array - $notes = []; - $attachments = []; - $errors = 0; - - foreach ($ids as $id_inc) { - // Delete incident - $ret = db_process_sql_delete('tincidencia', ['id_incidencia' => $id_inc]); - if ($ret === false) { - $errors++; - } - - // We only need the ID's - $notes = array_merge($notes, array_keys(incidents_get_notes($id_inc))); - $attachments = array_merge($attachments, array_keys(incidents_get_attach($id_inc))); - - db_pandora_audit( - AUDIT_LOG_INCIDENT_MANAGEMENT, - $config['id_user'].' deleted incident #'.$id_inc - ); - } - - // Delete notes - $note_err = incidents_delete_note($notes, false); - $attach_err = incidents_delete_attach($attachments, false); - - if ($note_err === false || $attach_err === false) { - $errors++; - } - - if ($errors > 0) { - return false; - } - - return true; -} - - -/** - * Delete notes out the database. - * - * @param mixed $id_note An int or an array of ints to be deleted - * @param boolean $transact true if a transaction should be started, false if not - * - * @return boolean True if note was succesfully deleted, false if not - */ -function incidents_delete_note($id_note, $transact=true) -{ - $id_note = (array) safe_int($id_note, 1); - // cast as array - $errors = 0; - - // Delete notes - foreach ($id_note as $id) { - $ret = db_process_sql_delete('tnota', ['id_nota' => $id]); - if ($ret === false) { - $errors++; - } - } - - if ($errors > 0) { - return false; - } else { - return true; - } -} - - -/** - * Delete attachments out the database and from the machine. - * - * @param mixed $id_attach An int or an array of ints to be deleted - * @param boolean $transact true if a transaction should be started, false if not - * - * @return boolean True if attachment was succesfully deleted, false if not - */ -function incidents_delete_attach($id_attach, $transact=true) -{ - global $config; - - $id_attach = (array) safe_int($id_attach, 1); - // cast as array - $errors = 0; - - // Delete attachment - foreach ($id_attach as $id) { - $filename = db_get_value('filename', 'tattachment', 'id_attachment', $id); - - $ret = db_process_sql_delete('tattachment', ['id_attachment' => $id]); - if ($ret === false) { - $errors++; - } - - unlink($config['attachment_store'].'/pand'.$id.'_'.$filename); - } - - if ($errors > 0) { - return false; - } else { - return true; - } -} - - -/** - * Get notes based on the incident id. - * - * @param integer $id_incident An int with the incident id - * - * @return array An array of all the notes for that incident - */ -function incidents_get_notes($id_incident) -{ - $return = db_get_all_rows_field_filter('tnota', 'id_incident', (int) $id_incident); - - if ($return === false) { - $return = []; - } - - $notes = []; - foreach ($return as $row) { - $notes[$row['id_nota']] = $row; - } - - return $notes; -} - - -/** - * Get attachments based on the incident id. - * - * @param integer $id_incident An int with the incident id - * - * @return array An array of all the notes for that incident - */ -function incidents_get_attach($id_incident) -{ - $return = db_get_all_rows_field_filter('tattachment', 'id_incidencia', (int) $id_incident); - - if ($return === false) { - $return = []; - } - - $attach = []; - foreach ($return as $row) { - $attach[$row['id_attachment']] = $row; - } - - return $attach; -} - - -/** - * Get user id of a note. - * - * @param integer $id_note Note id. - * - * @return string User id of the given note. - */ -function incidents_get_notes_author($id_note) -{ - return (string) db_get_value('id_usuario', 'tnota', 'id_nota', (int) $id_note); -} - - -/** - * Interface to Integria API functionality. - * - * @param string $url Url to Integria API with user, password and option (function to use). - * @param string $postparameters Additional parameters to pass. - * - * @return variant The function result called in the API. - */ -function incidents_call_api($url, $postparameters=false) -{ - $curlObj = curl_init(); - curl_setopt($curlObj, CURLOPT_URL, $url); - curl_setopt($curlObj, CURLOPT_RETURNTRANSFER, 1); - if ($postparameters !== false) { - curl_setopt($curlObj, CURLOPT_POSTFIELDS, $postparameters); - } - - $result = curl_exec($curlObj); - curl_close($curlObj); - - return $result; -} - - -/** - * Converts Xml format file to an array datatype. - * - * @param string $xml Xml file to convert. - * - * @return array A Json encoded array with xml content. - */ -function incidents_xml_to_array($xml) -{ - $xmlObj = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); - - return json_decode(json_encode($xmlObj), true); -} diff --git a/pandora_console/include/functions_integriaims.php b/pandora_console/include/functions_integriaims.php deleted file mode 100644 index 8fec23e210..0000000000 --- a/pandora_console/include/functions_integriaims.php +++ /dev/null @@ -1,564 +0,0 @@ -'.html_print_image('images/configuration@svg.svg', true, ['title' => __('Configure Integria IMS'), 'class' => 'main_menu_icon invert_filter']).''; - $list_tab['text'] = ''.html_print_image('images/logs@svg.svg', true, ['title' => __('Ticket list'), 'class' => 'main_menu_icon invert_filter']).''; - $create_tab['text'] = ''.html_print_image('images/edit.svg', true, ['title' => __('New ticket'), 'class' => 'main_menu_icon invert_filter']).''; - - switch ($active_tab) { - case 'setup_tab': - $setup_tab['active'] = true; - $list_tab['active'] = false; - $create_tab['active'] = false; - break; - - case 'list_tab': - $setup_tab['active'] = false; - $list_tab['active'] = true; - $create_tab['active'] = false; - break; - - case 'create_tab': - $setup_tab['active'] = false; - $list_tab['active'] = false; - $create_tab['active'] = true; - break; - - default: - $setup_tab['active'] = false; - $list_tab['active'] = false; - $create_tab['active'] = false; - break; - } - - if ($view) { - $create_tab['text'] = ''.html_print_image('images/edit.svg', true, ['title' => __('Edit ticket'), 'class' => 'main_menu_icon invert_filter']).''; - $view_tab['text'] = ''.html_print_image('images/details.svg', true, ['title' => __('View ticket'), 'class' => 'main_menu_icon invert_filter']).''; - // When the current page is the View page. - if (!$active_tab) { - $view_tab['active'] = true; - } - } - - $onheader = []; - $onheader['view'] = $view_tab; - $onheader['configure'] = $setup_tab; - $onheader['list'] = $list_tab; - $onheader['create'] = $create_tab; - - return $onheader; -} - - -/** - * Gets all the details of Integria IMS API - * - * @param string $details Type of API call. - * @param number $detail_index Send index if you want return the text. - * - * @return string or array with result of API call. - */ -function integriaims_get_details($details, $detail_index=false) -{ - global $config; - - switch ($details) { - case 'status': - $operation = 'get_incidents_status'; - break; - - case 'group': - $operation = 'get_groups'; - break; - - case 'priority': - $operation = 'get_incident_priorities'; - break; - - case 'resolution': - $operation = 'get_incidents_resolutions'; - break; - - case 'type': - $operation = 'get_types'; - break; - - default: - // code... - break; - } - - $api_call = integria_api_call(null, null, null, null, $operation); - $result = []; - get_array_from_csv_data_pair($api_call, $result); - - if ($detail_index !== false) { - if ($result[$detail_index] == '' || $result[$detail_index] === null) { - return __('None'); - } else { - return $result[$detail_index]; - } - } else { - return $result; - } -} - - -/** - * Perform an API call to Integria IMS. - * - * @param string|null $api_hostname API host URL. - * @param string|null $user User name. - * @param string|null $user_pass User password. - * @param string|null $api_pass API password. - * @param string|null $operation API Operation. - * @param mixed $params String or array with parameters required by the API function. - * @param mixed $show_credentials_error_msg Show_credentials_error_msg. - * @param mixed $return_type Return_type. - * @param mixed $token Token. - * @param mixed $user_level_conf User_level_conf. - * - * @return boolean True if API request succeeded, false if API request failed. - */ -function integria_api_call( - $api_hostname=null, - $user=null, - $user_pass=null, - $api_pass=null, - $operation=null, - $params='', - $show_credentials_error_msg=false, - $return_type='', - $token='', - $user_level_conf=null -) { - global $config; - - if (is_metaconsole()) { - $servers = metaconsole_get_connection_names(); - foreach ($servers as $key => $server) { - $connection = metaconsole_get_connection($server); - if (metaconsole_connect($connection) != NOERR) { - continue; - } - - $integria_enabled = db_get_sql( - 'SELECT `value` FROM tconfig WHERE `token` = "integria_enabled"' - ); - - if (!$integria_enabled) { - metaconsole_restore_db(); - continue; - } - - // integria_user_level_conf, integria_hostname, integria_api_pass, integria_user, integria_user_level_user, integria_pass, integria_user_level_pass - $config_aux = db_get_all_rows_sql('SELECT `token`, `value` FROM `tconfig` WHERE `token` IN ("integria_user_level_conf", "integria_hostname", "integria_api_pass", "integria_user", "integria_user_level_user", "integria_pass", "integria_user_level_pass")'); - $user_info = users_get_user_by_id($config['id_user']); - foreach ($config_aux as $key => $conf) { - if ($conf['token'] === 'integria_user_level_conf') { - $user_level_conf = $conf['value']; - } - - if ($conf['token'] === 'integria_hostname') { - $api_hostname = $conf['value']; - } - - if ($conf['token'] === 'integria_api_pass') { - $api_pass = $conf['value']; - } - - if ($conf['token'] === 'integria_user') { - $user = $conf['value']; - } - - if ($conf['token'] === 'integria_pass') { - $user_pass = $conf['value']; - } - } - - if ($user_level_conf == true) { - $user = $user_info['integria_user_level_user']; - $user_pass = $user_info['integria_user_level_pass']; - } - - metaconsole_restore_db(); - } - } else { - if ($user_level_conf === null) { - $user_level_conf = (bool) $config['integria_user_level_conf']; - } - - $user_info = users_get_user_by_id($config['id_user']); - - // API access data. - if ($api_hostname === null) { - $api_hostname = $config['integria_hostname']; - } - - if ($api_pass === null) { - $api_pass = $config['integria_api_pass']; - } - - // Integria user and password. - if ($user === null || $user_level_conf === true) { - $user = $config['integria_user']; - - if ($user_level_conf === true) { - $user = $user_info['integria_user_level_user']; - } - } - - if ($user_pass === null || $user_level_conf === true) { - $user_pass = $config['integria_pass']; - - if ($user_level_conf === true) { - $user_pass = $user_info['integria_user_level_pass']; - } - } - } - - if (is_array($params)) { - $params = implode($token, $params); - } - - $url_data = [ - 'user' => $user, - 'user_pass' => $user_pass, - 'pass' => $api_pass, - 'op' => $operation, - 'params' => io_safe_output($params), - ]; - - if ($return_type !== '') { - $url_data['return_type'] = $return_type; - } - - if ($token !== '') { - $url_data['token'] = $token; - } - - // Build URL for API request. - $url = $api_hostname.'/include/api.php'; - - // ob_start(); - // $out = fopen('php://output', 'w'); - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $url_data); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_VERBOSE, true); - curl_setopt($ch, CURLOPT_STDERR, $out); - $result = curl_exec($ch); - - // fclose($out); - // $debug = ob_get_clean(); - $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - $error = false; - - if ($result === false) { - $error = curl_error($ch); - } - - curl_close($ch); - - if ($error === true || $http_status !== 200) { - if ($show_credentials_error_msg === true) { - ui_print_error_message(__('API request failed. Please check Integria IMS\' access credentials in Pandora setup.')); - } - - return false; - } else { - return $result; - } -} - - -// Parse CSV consisting of one or more lines of the form key-value pair into an array. -function get_array_from_csv_data_pair($csv_data, &$array_values) -{ - $csv_array = explode("\n", $csv_data); - - foreach ($csv_array as $csv_value) { - if (empty($csv_value)) { - continue; - } - - $new_csv_value = str_getcsv($csv_value); - - $array_values[$new_csv_value[0]] = $new_csv_value[1]; - } -} - - -/** - * Parse CSV consisting of all lines into an array. - * - * @param string $csv_data Data returned of csv api call. - * @param string $array_values Returned array. - * @param array $index Array to create an associative index (opcional). - */ -function get_array_from_csv_data_all($csv_data, &$array_values, $index=false) -{ - $csv_array = explode("\n", $csv_data); - - foreach ($csv_array as $csv_value) { - if (empty($csv_value)) { - continue; - } - - $new_csv_value = str_getcsv($csv_value); - - if ($index !== false) { - foreach ($new_csv_value as $key => $value) { - $new_csv_value_index[$index[$key]] = str_replace(':::', ',', $value); - ; - } - - $array_values[$new_csv_value[0]] = $new_csv_value_index; - } else { - $new_csv_value_comma = array_map( - function ($item) { - return str_replace(':::', ',', $item); - }, - $new_csv_value - ); - $array_values[$new_csv_value[0]] = $new_csv_value_comma; - } - } -} - - -/** - * Print priority for Integria IMS with colors. - * - * @param string $priority value of priority in Integria IMS. - * @param string $priority_label text shown in color box. - * - * @return string HTML code. code to print the color box. - */ -function ui_print_integria_incident_priority($priority, $priority_label) -{ - global $config; - - $output = ''; - switch ($priority) { - case 0: - $color = COL_UNKNOWN; - break; - - case 1: - $color = COL_NORMAL; - break; - - case 10: - $color = COL_NOTINIT; - break; - - case 2: - $color = COL_WARNING; - break; - - case 3: - $color = COL_ALERTFIRED; - break; - - case 4: - $color = COL_CRITICAL; - break; - } - - $output = '
'; - $output .= $priority_label; - $output .= '
'; - - return $output; -} - - -/** - * Get tickets from Integria IMS. - * - * @param array $tickets_filters Filters to send to API. - * - * @return array Tickets returned by API call. - */ -function get_tickets_integriaims($tickets_filters) -{ - global $config; - - // Filters. - $incident_text = $tickets_filters['incident_text']; - $incident_status = $tickets_filters['incident_status']; - $incident_group = $tickets_filters['incident_group']; - $incident_owner = $tickets_filters['incident_owner']; - $incident_creator = $tickets_filters['incident_creator']; - $incident_priority = $tickets_filters['incident_priority']; - $incident_resolution = $tickets_filters['incident_resolution']; - $created_from = $tickets_filters['created_from']; - $created_to = $tickets_filters['created_to']; - - // API call. - $result_api_call_list = integria_api_call( - null, - null, - null, - null, - 'get_incidents', - [ - $incident_text, - $incident_status, - $incident_group, - $incident_priority, - '0', - $incident_owner, - $incident_creator, - ], - false, - '', - ',' - ); - - // Return array of api call 'get_incidents'. - $array_get_incidents = []; - get_array_from_csv_data_all($result_api_call_list, $array_get_incidents); - - // Modify $array_get_incidents if filter for resolution exists. - $filter_resolution = []; - foreach ($array_get_incidents as $key => $value) { - if ($incident_resolution !== '' && ($array_get_incidents[$key][12] == $incident_resolution)) { - $filter_resolution[$key] = $array_get_incidents[$key]; - continue; - } - } - - if ($incident_resolution !== '') { - $array_get_incidents = $filter_resolution; - } - - // Modify $array_get_incidents if filter for date is selected. - if ($created_from !== '' && $created_to !== '') { - $date = []; - $date_utimestamp = []; - foreach ($array_get_incidents as $key => $value) { - // Change format date / to -. - $date[$key] = date('Y-m-d', strtotime($array_get_incidents[$key][9])); - // Covert date to utimestamp. - $date_utimestamp[$key] = strtotime($date[$key]); - } - - // Change format date / to -. - $created_from_date = date('Y-m-d', strtotime($created_from)); - $created_to_date = date('Y-m-d', strtotime($created_to)); - - // Covert date to utimestamp. - $created_from_timestamp = strtotime($created_from_date); - $created_to_timestamp = strtotime($created_to_date); - - // Dates within the selected period. - $selected_period = array_filter( - $date_utimestamp, - function ($value) use ($created_from_timestamp, $created_to_timestamp) { - return ($value >= $created_from_timestamp && $value <= $created_to_timestamp); - } - ); - - // Return incidents with the correct dates. - $filter_date = []; - foreach ($array_get_incidents as $key => $value) { - foreach ($selected_period as $index => $value) { - if ($array_get_incidents[$key][0] == $index) { - $filter_date[$key] = $array_get_incidents[$key]; - continue; - } - } - } - - $array_get_incidents = $filter_date; - } - - return $array_get_incidents; -} - - -function integriaims_upload_file($filename, $incident_id, $file_description) -{ - if ($_FILES[$filename]['name'] != '') { - $filename = io_safe_input($_FILES[$filename]['name']); - $filesize = io_safe_input($_FILES[$filename]['size']); - - $extension = pathinfo($filename, PATHINFO_EXTENSION); - $invalid_extensions = '/^(bat|exe|cmd|sh|php|php1|php2|php3|php4|php5|pl|cgi|386|dll|com|torrent|js|app|jar|iso| - pif|vb|vbscript|wsf|asp|cer|csr|jsp|drv|sys|ade|adp|bas|chm|cpl|crt|csh|fxp|hlp|hta|inf|ins|isp|jse|htaccess| - htpasswd|ksh|lnk|mdb|mde|mdt|mdw|msc|msi|msp|mst|ops|pcd|prg|reg|scr|sct|shb|shs|url|vbe|vbs|wsc|wsf|wsh)$/i'; - - if (!preg_match($invalid_extensions, $extension)) { - // The following is if you have clamavlib installed. - // (php5-clamavlib) and enabled in php.ini - // http://www.howtoforge.com/scan_viruses_with_php_clamavlib - if (extension_loaded('clamav')) { - cl_setlimits(5, 1000, 200, 0, 10485760); - $malware = cl_scanfile($_FILES['file']['tmp_name']); - if ($malware) { - $error = 'Malware detected: '.$malware.'
ClamAV version: '.clam_get_version(); - die($error); - } - } - - $filecontent = base64_encode(file_get_contents($_FILES[$filename]['tmp_name'])); - - $result_api_call = integria_api_call(null, null, null, null, 'attach_file', [$incident_id, $filename, $filesize, $file_description, $filecontent], false, '', '|;|'); - - // API method returns '0' string if success. - $file_added = ($result_api_call === '0') ? true : false; - - ui_print_result_message( - $file_added, - __('File successfully added'), - __('File could not be added') - ); - } else { - ui_print_error_message(__('File has an invalid extension')); - } - } -} diff --git a/pandora_console/include/functions_menu.php b/pandora_console/include/functions_menu.php index a1927bb60a..346dee04b5 100644 --- a/pandora_console/include/functions_menu.php +++ b/pandora_console/include/functions_menu.php @@ -147,6 +147,12 @@ function menu_print_menu(&$menu) || $sec2 === 'enterprise/godmode/servers/manage_credential_boxes' ) { $sec2 = 'enterprise/godmode/servers/list_satellite'; + } else if ($sec2 === 'operation/ITSM/itsm') { + $sec2 = (string) get_parameter('sec2'); + $operation = (string) get_parameter('operation', ''); + if (empty($operation) === false) { + $sec2 = $sec2.'&operation='.$operation; + } } else { $sec2 = (string) get_parameter('sec2'); } @@ -287,7 +293,7 @@ function menu_print_menu(&$menu) } } - // Set class. + // Set class.; if (($sec2 == $subsec2 || $allsec2 == $subsec2 || $selected_submenu2) && isset($sub[$subsec2]['options']) && (get_parameter_get($sub[$subsec2]['options']['name']) == $sub[$subsec2]['options']['value']) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index 8bd6a879bf..171f6c6b42 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -4011,6 +4011,10 @@ function ui_print_datatable(array $parameters) $parameters['csv'] = 1; } + if (isset($parameters['no_move_elements_to_action']) === false) { + $parameters['no_move_elements_to_action'] = false; + } + $filter = ''; // Datatable filter. if (isset($parameters['form']) && is_array($parameters['form'])) { @@ -4167,13 +4171,13 @@ function ui_print_datatable(array $parameters) foreach ($names as $column) { if (is_array($column)) { - $table .= ''.__($column['text']); - $table .= $column['extra']; + $table .= ' style="'.($column['style'] ?? '').'">'.__($column['text']); + $table .= ($column['extra'] ?? ''); $table .= ''; } else { $table .= ''.__($column).''; @@ -7980,6 +7984,54 @@ function ui_print_status_div($status) } +function ui_print_div(?string $class='', ?string $title='') +{ + $return = '
'; + $return .= ' '; + $return .= '
'; + + return $return; +} + + +function ui_print_status_agent_div(int $status, ?string $title=null) +{ + $return = ''; + $class = 'status_rounded_rectangles forced_title'; + switch ((int) $status) { + case AGENT_STATUS_CRITICAL: + $return = ui_print_div('group_view_crit '.$class, $title); + break; + + case AGENT_STATUS_NORMAL: + $return = ui_print_div('group_view_ok '.$class, $title); + break; + + case AGENT_STATUS_NOT_INIT: + $return = ui_print_div('group_view_not_init '.$class, $title); + break; + + case AGENT_STATUS_UNKNOWN: + $return = ui_print_div('group_view_unk '.$class, $title); + break; + + case AGENT_STATUS_WARNING: + $return = ui_print_div('group_view_warn '.$class, $title); + break; + + case AGENT_STATUS_ALERT_FIRED: + $return = ui_print_div('group_view_alrm '.$class, $title); + break; + + default: + // Not posible. + break; + } + + return $return; +} + + function ui_print_fav_menu($id_element, $url, $label, $section) { global $config; diff --git a/pandora_console/include/javascript/ITSM.js b/pandora_console/include/javascript/ITSM.js new file mode 100644 index 0000000000..fa3802fffb --- /dev/null +++ b/pandora_console/include/javascript/ITSM.js @@ -0,0 +1,191 @@ +/* global $ jQuery */ + +/* Function get custom fields incidences */ +// eslint-disable-next-line no-unused-vars +function getInputFieldsIncidenceType(idIncidenceType, fieldsData, ajaxUrl) { + // Failed request handler. + var handleFail = function(jqXHR, textStatus, errorThrown) { + console.log(jqXHR, textStatus, errorThrown); + }; + + // Function which handle success case. + var handleSuccess = function(data) { + $(".object-type-fields").empty(); + $(".object-type-fields").append(data); + }; + + // Visual Console container request. + jQuery + .post( + ajaxUrl, + { + page: "operation/ITSM/itsm", + method: "getInputFieldsIncidenceType", + idIncidenceType: idIncidenceType, + fieldsData: fieldsData + }, + "html" + ) + .done(handleSuccess) + .fail(handleFail); +} + +/* Function get custom fields incidences */ +// eslint-disable-next-line no-unused-vars +function downloadIncidenceAttachment( + idIncidence, + idAttachment, + ajaxUrl, + filename +) { + $.ajax({ + type: "POST", + url: ajaxUrl, + data: { + page: "operation/ITSM/itsm", + method: "getDownloadIncidenceAttachment", + idIncidence: idIncidence, + idAttachment: idAttachment + }, + dataType: "binary", + xhrFields: { + responseType: "arraybuffer" + }, + success: function(data) { + var blob = new Blob([data], { type: "application/octetstream" }); + var link = document.createElement("a"); + link.href = window.URL.createObjectURL(blob); + link.download = filename; + document.body.appendChild(link); + link.click(); + }, + error: function(jqXHR, textStatus, message) { + console.error(textStatus, message); + } + }); +} + +/* Function check API */ +// eslint-disable-next-line no-unused-vars +function testConectionApi(pass, host) { + var hideLoadingImage = function() { + $("span#ITSM-spinner").hide(); + }; + var showLoadingImage = function() { + $("span#ITSM-spinner").show(); + }; + var hideSuccessImage = function() { + $("span#ITSM-success").hide(); + }; + var showSuccessImage = function() { + $("span#ITSM-success").show(); + }; + var hideFailureImage = function() { + $("span#ITSM-failure").hide(); + }; + var showFailureImage = function() { + $("span#ITSM-failure").show(); + }; + var hideMessage = function() { + $("span#ITSM-message").hide(); + }; + var showMessage = function() { + $("span#ITSM-message").show(); + }; + + hideSuccessImage(); + hideFailureImage(); + hideMessage(); + showLoadingImage(); + + var data = { + page: "operation/ITSM/itsm", + method: "checkConnectionApi", + pass: pass, + host: host + }; + + $.ajax({ + type: "POST", + url: "ajax.php", + dataType: "json", + data: data + }) + .done(function(data) { + if (data.valid == 1) { + showSuccessImage(); + } else { + showFailureImage(); + showMessage(); + } + }) + .fail(function() { + showFailureImage(); + showMessage(); + }) + .always(function() { + hideLoadingImage(); + }); +} + +/* Function check API */ +// eslint-disable-next-line no-unused-vars +function testConectionApiItsmToPandora(path) { + var hideLoadingImage = function() { + $("span#ITSM-spinner-pandora").hide(); + }; + var showLoadingImage = function() { + $("span#ITSM-spinner-pandora").show(); + }; + var hideSuccessImage = function() { + $("span#ITSM-success-pandora").hide(); + }; + var showSuccessImage = function() { + $("span#ITSM-success-pandora").show(); + }; + var hideFailureImage = function() { + $("span#ITSM-failure-pandora").hide(); + }; + var showFailureImage = function() { + $("span#ITSM-failure-pandora").show(); + }; + var hideMessage = function() { + $("span#ITSM-message-pandora").hide(); + }; + var showMessage = function() { + $("span#ITSM-message-pandora").show(); + }; + + hideSuccessImage(); + hideFailureImage(); + hideMessage(); + showLoadingImage(); + + var data = { + page: "operation/ITSM/itsm", + method: "checkConnectionApiITSMToPandora", + path: path + }; + + $.ajax({ + type: "POST", + url: "ajax.php", + dataType: "json", + data: data + }) + .done(function(data) { + if (data.valid == 1) { + showSuccessImage(); + } else { + showFailureImage(); + showMessage(); + } + }) + .fail(function() { + showFailureImage(); + showMessage(); + }) + .always(function() { + hideLoadingImage(); + }); +} diff --git a/pandora_console/include/javascript/datatablesFunction.js b/pandora_console/include/javascript/datatablesFunction.js index 6c9dc6a3f4..34fe301f41 100644 --- a/pandora_console/include/javascript/datatablesFunction.js +++ b/pandora_console/include/javascript/datatablesFunction.js @@ -131,6 +131,11 @@ if (dt.startDisabled === true) { startDisabled = true; } +var noMoveElementsToAction = false; +if (dt.no_move_elements_to_action === true) { + noMoveElementsToAction = true; +} + $(document).ready(function() { function checkPages() { if (dt_table.page.info().pages > 1) { @@ -226,7 +231,9 @@ $(document).ready(function() { ] : [], initComplete: function(settings, json) { - moveElementsToActionButtons(); + if (noMoveElementsToAction === false) { + moveElementsToActionButtons(); + } checkPages(); diff --git a/pandora_console/include/javascript/graph_analytics.js b/pandora_console/include/javascript/graph_analytics.js index e63540ae08..6c14f3f8c8 100644 --- a/pandora_console/include/javascript/graph_analytics.js +++ b/pandora_console/include/javascript/graph_analytics.js @@ -653,7 +653,8 @@ $("[data-button=export]").click(function(e) { }); }); -$("#button-export-modal").click(function(e) { +// Export graph. +function exportCustomGraph() { const filter = parseInt($("#export-filter-id").val()); const group = parseInt($("#export-group-id").val()); @@ -682,8 +683,19 @@ $("#button-export-modal").click(function(e) { } } }); + } else { + confirmDialog({ + title: titleExportError, + message: messageExportError, + hideCancelButton: true, + onAccept: function() { + $( + "button.ui-button.ui-corner-all.ui-widget.ui-button-icon-only.ui-dialog-titlebar-close" + ).click(); + } + }); } -}); +} // Remove graph. function removeGraph(e) { diff --git a/pandora_console/include/javascript/pandora_events.js b/pandora_console/include/javascript/pandora_events.js index 940fd3ce5d..5e272ee0e7 100644 --- a/pandora_console/include/javascript/pandora_events.js +++ b/pandora_console/include/javascript/pandora_events.js @@ -52,7 +52,7 @@ function show_event_dialog(event, dialog_page) { .empty() .append(data) .dialog({ - title: event.evento, + title: event.event_title, resizable: true, draggable: true, modal: false, diff --git a/pandora_console/include/lib/Cluster.php b/pandora_console/include/lib/Cluster.php index 9a01eea428..b7bd21d929 100644 --- a/pandora_console/include/lib/Cluster.php +++ b/pandora_console/include/lib/Cluster.php @@ -205,6 +205,92 @@ class Cluster extends Entity } + /** + * Counters modules involved status. + * + * @return array + */ + public function getCounters() :array + { + $id_agent_modules = $this->getIdsModulesInvolved(); + $sql = sprintf( + 'SELECT SUM( IF(estado = 1, 1, 0) ) AS critical, + SUM( IF(estado = 2, 1, 0) ) AS warning, + SUM( IF(estado = 0, 1, 0) ) AS normal, + SUM( IF(estado = 3, 1, 0) ) AS unknown, + SUM( IF(estado = 4 OR estado = 5, 1, 0) ) AS not_init, + COUNT(id_agente_modulo) AS total + FROM tagente_estado + WHERE id_agente_modulo IN (%s)', + implode(',', $id_agent_modules) + ); + + $counters = db_get_row_sql($sql); + if ($counters === false) { + $counters = []; + } + + return $counters; + } + + + /** + * Return Ids modules involved. + * + * @return array + */ + public function getIdsModulesInvolved(): array + { + $members = $this->getMembers(); + $modules_ids = []; + $modules_names = $this->getItemNames(); + if (empty($members) === false) { + foreach ($members as $agent) { + $modules_filtered = $agent->searchModules(['nombre' => $modules_names], 0); + if (empty($modules_filtered) === false) { + foreach ($modules_filtered as $idAgent => $module) { + $modules_ids[] = $module->id_agente_modulo(); + } + } + } + } + + return $modules_ids; + } + + + /** + * Return names modules involved. + * + * @return array + */ + public function getItemNames(): array + { + $result = []; + if (empty($this->getItems()) === false) { + $result = array_keys($this->getItems()); + } + + return $result; + } + + + /** + * Return name type. + * + * @return string + */ + public function getStringTypeName(): string + { + $result = __('Active').' / '.__('Active'); + if ($this->cluster_type() === 'AP') { + $result = __('Active').' / '.__('Pasive'); + } + + return $result; + } + + /** * Cleans members from cluster object. * diff --git a/pandora_console/include/lib/ClusterViewer/ClusterManager.php b/pandora_console/include/lib/ClusterViewer/ClusterManager.php index 3afff1adb3..7ee9a96ba1 100644 --- a/pandora_console/include/lib/ClusterViewer/ClusterManager.php +++ b/pandora_console/include/lib/ClusterViewer/ClusterManager.php @@ -216,15 +216,27 @@ class ClusterManager $err = ''; $id = get_parameter('id', null); - - try { - $cluster = new Cluster($id); - } catch (\Exception $e) { - $err = ui_print_error_message( - __('Cluster not found: '.$e->getMessage()), - '', - true - ); + if (empty($id) === true) { + $id_agente = get_parameter('id_agente', null); + try { + $cluster = Cluster::loadFromAgentId($id_agente, true); + } catch (\Exception $e) { + $err = ui_print_error_message( + __('Cluster not found: '.$e->getMessage()), + '', + true + ); + } + } else { + try { + $cluster = new Cluster($id); + } catch (\Exception $e) { + $err = ui_print_error_message( + __('Cluster not found: '.$e->getMessage()), + '', + true + ); + } } if ($cluster->agent()->id_agente() === null) { @@ -237,15 +249,60 @@ class ClusterManager $critical = true; } + $allGroups = agents_get_all_groups_agent( + $cluster->agent()->id_agente(), + $cluster->agent()->id_grupo() + ); + + $flag = (int) get_parameter('flag', 0); + if ($flag === 1 && check_acl_one_of_groups($config['id_user'], $allGroups, 'AW') === true) { + $id_agent_module = get_parameter('id_agente_modulo'); + db_process_sql_update( + 'tagente_modulo', + ['flag' => 1], + ['id_agente_modulo' => $id_agent_module] + ); + } + + $flag_agent = (int) get_parameter('flag_agent', 0); + if ($flag_agent === 1 && check_acl_one_of_groups($config['id_user'], $allGroups, 'AW') === true) { + db_process_sql_update( + 'tagente_modulo', + ['flag' => 1], + ['id_agente' => $cluster->agent()->id_agente()] + ); + } + + $counters = $cluster->getCounters(); + $counters_chart = []; + $counters_bullet = []; + foreach ($counters as $key => $value) { + if ($key === 'not_init') { + $counters_chart['Not init'] = $value; + } else { + $counters_chart[ucfirst($key)] = $value; + } + + $counters_bullet[$key.'_count'] = $value; + } + + unset($counters_chart['Total']); + + $module_involved_ids = $cluster->getIdsModulesInvolved(); + View::render( 'cluster/view', [ - 'message' => $msg, - 'error' => $err, - 'config' => $config, - 'model' => $this, - 'cluster' => $cluster, - 'critical' => $critical, + 'message' => $msg, + 'error' => $err, + 'config' => $config, + 'model' => $this, + 'cluster' => $cluster, + 'critical' => $critical, + 'allGroups' => $allGroups, + 'counters_chart' => $counters_chart, + 'counters_bullet' => $counters_bullet, + 'module_involved_ids' => array_combine($module_involved_ids, $module_involved_ids), ] ); } diff --git a/pandora_console/include/lib/ClusterViewer/ClusterWizard.php b/pandora_console/include/lib/ClusterViewer/ClusterWizard.php index 03e13d0f36..3c4c4eb293 100644 --- a/pandora_console/include/lib/ClusterViewer/ClusterWizard.php +++ b/pandora_console/include/lib/ClusterViewer/ClusterWizard.php @@ -725,14 +725,11 @@ class ClusterWizard extends \HTML } if ($this->page === 7) { - /* - * - * PARSE ALERTS - * - */ - - // There is no need to parse anything. Already managed by alert - // builder. + global $config; + $step = true; + $id_agente = $this->cluster->agent()->id_agente(); + $dont_display_alert_create_bttn = true; + include_once $config['homedir'].'/godmode/alerts/alert_list.php'; header('Location: '.$this->url.'&op=view&id='.$this->cluster->id()); } @@ -1212,26 +1209,15 @@ class ClusterWizard extends \HTML 'block_content' => $inputs, ]; } else if ($this->page === 6) { - /* - * - * Page: Alerts. - * - */ - - ob_start(); global $config; - + $step = true; $id_agente = $this->cluster->agent()->id_agente(); $dont_display_alert_create_bttn = true; - include_once $config['homedir'].'/godmode/alerts/alert_list.php'; + ob_start(); include_once $config['homedir'].'/godmode/alerts/alert_list.builder.php'; - - // XXX: Please do not use this kind of thing never more. - $hack = ob_get_clean(); - - // TODO: Alert form. - $form['pre-content'] = $hack; - + html_print_input_hidden('create_alert', 1); + $hack_form = ob_get_clean(); + $form['inputs'][] = ['extra' => $hack_form]; $final = true; } diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php index 9bedc71f50..82fc7cbda5 100644 --- a/pandora_console/include/lib/Dashboard/Widget.php +++ b/pandora_console/include/lib/Dashboard/Widget.php @@ -440,10 +440,26 @@ class Widget $className .= '\\'.$name; break; + case 'ITSMIncidences': + if (isset($config['ITSM_enabled']) === false || (bool) $config['ITSM_enabled'] === false) { + $not_installed = true; + } + + $className .= '\\'.$name; + break; + case 'heatmap': $className .= '\HeatmapWidget'; break; + case 'security_hardening': + if (\enterprise_installed() === false) { + $not_installed = true; + } + + $className .= '\SecurityHardening'; + break; + default: $className = false; break; diff --git a/pandora_console/include/lib/Dashboard/Widgets/ITSMIncidences.php b/pandora_console/include/lib/Dashboard/Widgets/ITSMIncidences.php new file mode 100644 index 0000000000..13a899fe41 --- /dev/null +++ b/pandora_console/include/lib/Dashboard/Widgets/ITSMIncidences.php @@ -0,0 +1,453 @@ +width = $width; + + // Height. + $this->height = $height; + + // Grid Width. + $this->gridWidth = $gridWidth; + + // Cell Id. + $this->cellId = $cellId; + + // Options. + $this->values = $this->decoders($this->getOptionsWidget()); + + // Positions. + $this->position = $this->getPositionWidget(); + + // Page. + $this->page = basename(__FILE__); + + // ClassName. + $class = new \ReflectionClass($this); + $this->className = $class->getShortName(); + + // Title. + $this->title = __('Pandora ITSM tickets'); + + // Name. + if (empty($this->name) === true) { + $this->name = 'ITSMIncidences'; + } + + // This forces at least a first configuration. + $this->configurationRequired = false; + if (isset($config['ITSM_enabled']) === false || (bool) $config['ITSM_enabled'] === false) { + $this->configurationRequired = true; + } else { + if (empty($this->values['customSearch']) === true || empty($this->values['fields']) === true) { + $this->configurationRequired = true; + } + } + + $this->overflow_scrollbars = false; + } + + + /** + * Decoders hack for retrocompability. + * + * @param array $decoder Values. + * + * @return array Returns the values ​​with the correct key. + */ + public function decoders(array $decoder): array + { + $values = []; + // Retrieve global - common inputs. + $values = parent::decoders($decoder); + + if (isset($decoder['show_full_legend']) === true) { + $values['showLegend'] = $decoder['show_full_legend']; + } + + if (isset($decoder['fields']) === true) { + if (is_array($decoder['fields']) === true) { + $decoder['fields'] = implode(',', $decoder['fields']); + } + + $values['fields'] = $decoder['fields']; + } + + if (isset($decoder['limit']) === true) { + $values['limit'] = $decoder['limit']; + } + + if (isset($decoder['customSearch']) === true) { + $values['customSearch'] = $decoder['customSearch']; + } + + return $values; + } + + + /** + * Generates inputs for form (specific). + * + * @return array Of inputs. + * + * @throws Exception On error. + */ + public function getFormInputs(): array + { + global $config; + $values = $this->values; + + // Retrieve global - common inputs. + $inputs = parent::getFormInputs(); + + // Default values. + if (isset($values['fields']) === false) { + $values['fields'] = implode( + ',', + [ + 'idIncidence', + 'title', + 'priority', + 'idCreator', + ] + ); + } + + if (isset($values['limit']) === false) { + $values['limit'] = $config['block_size']; + } + + $inputs[] = [ + 'label' => __('Limit'), + 'arguments' => [ + 'type' => 'number', + 'name' => 'limit', + 'value' => $values['limit'], + 'return' => true, + 'max' => 100, + 'min' => 0, + ], + ]; + + $customSearches = []; + if (isset($config['ITSM_enabled']) === true && (bool) $config['ITSM_enabled'] === true) { + try { + $ITSM = new ITSM(); + $customSearches = $ITSM->listCustomSearch(); + } catch (\Throwable $th) { + $error = $th->getMessage(); + } + } + + $inputs[] = [ + 'label' => __('Custom search'), + 'arguments' => [ + 'type' => 'select', + 'fields' => $customSearches, + 'name' => 'customSearch', + 'selected' => $values['customSearch'], + 'return' => true, + 'sort' => false, + ], + ]; + + $fields = [ + 'idIncidence' => __('ID'), + 'title' => __('Title'), + 'groupCompany' => __('Group').'/'.__('Company'), + 'statusResolution' => __('Status').'/'.__('Resolution'), + 'priority' => __('Priority'), + 'updateDate' => __('Updated'), + 'startDate' => __('Started'), + 'idCreator' => __('Creator'), + 'owner' => __('Owner'), + ]; + + $inputs[] = [ + 'label' => __('Fields to show'), + 'arguments' => [ + 'type' => 'select', + 'fields' => $fields, + 'name' => 'fields[]', + 'selected' => explode(',', $values['fields']), + 'return' => true, + 'multiple' => true, + 'sort' => false, + ], + ]; + + return $inputs; + } + + + /** + * Get Post for widget. + * + * @return array + */ + public function getPost():array + { + // Retrieve global - common inputs. + $values = parent::getPost(); + + $values['fields'] = \get_parameter('fields', []); + $values['limit'] = \get_parameter('limit', 20); + $values['customSearch'] = \get_parameter('customSearch', 20); + + return $values; + } + + + /** + * Draw widget. + * + * @return string; + */ + public function load() + { + global $config; + \ui_require_css_file('pandoraitsm', 'include/styles/', true); + + $fields = [ + 'idIncidence' => __('ID'), + 'title' => __('Title'), + 'groupCompany' => __('Group').'/'.__('Company'), + 'statusResolution' => __('Status').'/'.__('Resolution'), + 'priority' => __('Priority'), + 'updateDate' => __('Updated'), + 'startDate' => __('Started'), + 'idCreator' => __('Creator'), + 'owner' => __('Owner'), + ]; + + $fields_selected = explode(',', $this->values['fields']); + if (is_array($fields_selected) === false && empty($fields_selected) === true) { + $output = ''; + $output .= '
'; + $output .= \ui_print_info_message( + __('Not found fields selected'), + '', + true + ); + $output .= '
'; + + return $output; + } + + $columns = $fields_selected; + $column_names = []; + foreach ($fields_selected as $field) { + $column_names[] = $fields[$field]; + } + + $tableId = 'ITSMIncidence_'.$this->dashboardId.'_'.$this->cellId; + try { + ui_print_datatable( + [ + 'id' => $tableId, + 'class' => 'info_table table-widget-itsm', + 'style' => 'width: 99%', + 'columns' => $columns, + 'column_names' => $column_names, + 'ajax_url' => 'operation/ITSM/itsm', + 'ajax_data' => [ + 'method' => 'getListTickets', + 'customSearch' => $this->values['customSearch'], + ], + 'order' => [ + 'field' => 'updateDate', + 'direction' => 'desc', + ], + 'csv' => 0, + 'dom_elements' => 'frtip', + 'default_pagination' => $this->values['limit'], + ] + ); + } catch (\Exception $e) { + echo $e->getMessage(); + } + } + + + /** + * Get description. + * + * @return string. + */ + public static function getDescription() + { + return __('Pandora ITSM tickets'); + } + + + /** + * Get Name. + * + * @return string. + */ + public static function getName() + { + return 'ITSMIncidences'; + } + + + /** + * Get size Modal Configuration. + * + * @return array + */ + public function getSizeModalConfiguration(): array + { + $size = [ + 'width' => 450, + 'height' => 430, + ]; + + return $size; + } + + +} diff --git a/pandora_console/include/lib/Dashboard/Widgets/security_hardening.php b/pandora_console/include/lib/Dashboard/Widgets/security_hardening.php new file mode 100644 index 0000000000..2c936728ed --- /dev/null +++ b/pandora_console/include/lib/Dashboard/Widgets/security_hardening.php @@ -0,0 +1,1145 @@ +width = $width; + + // Height. + $this->height = $height; + + // Grid Width. + $this->gridWidth = $gridWidth; + + // Options. + $this->values = $this->getOptionsWidget(); + + // Positions. + $this->position = $this->getPositionWidget(); + + // Page. + $this->page = basename(__FILE__); + + // ClassName. + $class = new \ReflectionClass($this); + $this->className = $class->getShortName(); + + // Title. + $this->title = __('Security Hardening'); + + // Name. + if (empty($this->name) === true) { + $this->name = 'security_hardening'; + } + + $this->elements = [ + 'top_n_agents_sh' => __('Top-N agents with the worst score'), + 'top_n_checks_failed' => __('Top-N most frequent failed checks'), + 'top_n_categories_checks' => __('Top-N checks failed by category'), + 'vul_by_cat' => __('Vulnerabilities by category'), + 'scoring' => __('Scoring by date'), + 'evolution' => __('Evolution'), + ]; + } + + + /** + * Generates inputs for form (specific). + * + * @return array Of inputs. + * + * @throws Exception On error. + */ + public function getFormInputs(): array + { + $values = $this->values; + + // Retrieve global - common inputs. + $inputs = parent::getFormInputs(); + $categories = categories_of_cis(); + foreach ($categories as $id => $cat) { + $categories[$id] = implode(' ', $cat); + } + + $inputs[] = [ + 'label' => __('Data type'), + 'id' => 'row_data_type', + 'arguments' => [ + 'id' => 'select_data_type', + 'name' => 'data_type', + 'type' => 'select', + 'script' => 'selectData(this)', + 'fields' => $this->elements, + 'selected' => $values['data_type'], + ], + ]; + + $inputs[] = [ + 'label' => __('Group'), + 'id' => 'row_group', + 'class' => 'row_input', + 'arguments' => [ + 'id' => 'select_groups', + 'name' => 'group', + 'type' => 'select_groups', + 'selected' => (empty($values['group']) === false) ? $values['group'] : 0, + ], + ]; + + $inputs[] = [ + 'label' => __('Limit'), + 'id' => 'row_limit', + 'class' => 'row_input', + 'arguments' => [ + 'id' => 'limit', + 'name' => 'limit', + 'type' => 'number', + 'value' => (empty($values['limit']) === false) ? $values['limit'] : 10, + ], + ]; + + $inputs[] = [ + 'label' => __('Category'), + 'id' => 'row_category', + 'class' => 'row_input', + 'arguments' => [ + 'id' => 'select_categories', + 'name' => 'category', + 'type' => 'select', + 'fields' => $categories, + 'selected' => (empty($values['category']) === false) ? $values['category'] : 6, + ], + ]; + + $inputs[] = [ + 'label' => __('Ingore skipped'), + 'id' => 'row_ignore_skipped', + 'class' => 'row_input', + 'arguments' => [ + 'id' => 'ignore_skipped', + 'name' => 'ignore_skipped', + 'type' => 'switch', + 'class' => 'invisible', + 'value' => ($values['ignore_skipped'] === null) ? 1 : $values['ignore_skipped'], + 'return' => true, + ], + ]; + + $inputs[] = [ + 'label' => __('Date'), + 'id' => 'row_date', + 'class' => 'row_input', + 'arguments' => [ + 'id' => 'range', + 'name' => 'range', + 'type' => 'date_range', + 'selected' => 'chose_range', + 'date_init' => date('Y-m-d', $values['date_init']), + 'time_init' => date('H:i:s', $values['date_init']), + 'date_end' => date('Y-m-d', $values['date_end']), + 'time_end' => date('H:i:s', $values['date_end']), + 'return' => true, + ], + ]; + + return $inputs; + } + + + /** + * Get Post for widget. + * + * @return array + */ + public function getPost():array + { + // Retrieve global - common inputs. + $values = parent::getPost(); + + $values['data_type'] = \get_parameter('data_type', ''); + $values['group'] = \get_parameter('group', 0); + $values['limit'] = \get_parameter('limit', 10); + $values['category'] = \get_parameter('category', 6); + $values['ignore_skipped'] = \get_parameter_switch('ignore_skipped', 0); + $date = $this->getDateParameter(); + $values['date_init'] = $date['date_init']; + $values['date_end'] = $date['date_end']; + return $values; + } + + + /** + * Draw widget. + * + * @return string + */ + public function load() + { + global $config; + + $output = ''; + + $size = parent::getSize(); + $values = $this->values; + $data_type = $this->values['data_type']; + // If it is metaconsole we need to check it in the node. + $id_groups = $this->checkAcl($values['group']); + $output .= ''.$this->elements[$data_type].''; + + switch ($data_type) { + case 'top_n_agents_sh': + $output .= $this->loadTopNAgentsSh($id_groups, $values['limit']); + break; + + case 'top_n_checks_failed': + $output .= $this->topNChecksFailed($id_groups, $values['limit']); + break; + + case 'top_n_categories_checks': + $output .= $this->topNCategoriesChecks($id_groups, $values['limit']); + break; + + case 'vul_by_cat': + $output .= $this->vulnerabilitiesByCategory($id_groups, $values['category'], (bool) $values['ignore_skipped']); + break; + + case 'scoring': + $output .= $this->scoring($id_groups, $values['date_init'], $values['date_end']); + break; + + case 'evolution': + $output .= $this->evolution($id_groups, $values['date_init'], $values['date_end']); + break; + + default: + $output .= \ui_print_info_message(_('Please, configure this widget before use'), '', true); + break; + } + + return $output; + + } + + + /** + * Returns the date in an object obtained by parameter. + * + * @return object Object with date_init, date_end and period. + */ + private function getDateParameter() + { + $date_end = get_parameter('date_end', 0); + $time_end = get_parameter('time_end'); + $datetime_end = strtotime($date_end.' '.$time_end); + + $custom_date = get_parameter('custom_date', 0); + $range = get_parameter('range', SECONDS_1DAY); + $date_text = get_parameter('range_text', SECONDS_1DAY); + $date_init_less = (strtotime(date('Y/m/d')) - SECONDS_1DAY); + $date_init = get_parameter('date_init', date(DATE_FORMAT, $date_init_less)); + $time_init = get_parameter('time_init', date(TIME_FORMAT, $date_init_less)); + $datetime_init = strtotime($date_init.' '.$time_init); + if ($custom_date === '1') { + if ($datetime_init >= $datetime_end) { + $datetime_init = $date_init_less; + } + + $date_init = date('Y/m/d H:i:s', $datetime_init); + $date_end = date('Y/m/d H:i:s', $datetime_end); + $period = ($datetime_end - $datetime_init); + } else if ($custom_date === '2') { + $date_units = get_parameter('range_units'); + $date_end = date('Y/m/d H:i:s'); + $date_init = date('Y/m/d H:i:s', (strtotime($date_end) - ((int) $date_text * (int) $date_units))); + $period = (strtotime($date_end) - strtotime($date_init)); + } else if (in_array($range, ['this_week', 'this_month', 'past_week', 'past_month'])) { + if ($range === 'this_week') { + $monday = date('Y/m/d', strtotime('last monday')); + + $sunday = date('Y/m/d', strtotime($monday.' +6 days')); + $period = (strtotime($sunday) - strtotime($monday)); + $date_init = $monday; + $date_end = $sunday; + } else if ($range === 'this_month') { + $date_end = date('Y/m/d', strtotime('last day of this month')); + $first_of_month = date('Y/m/d', strtotime('first day of this month')); + $date_init = $first_of_month; + $period = (strtotime($date_end) - strtotime($first_of_month)); + } else if ($range === 'past_month') { + $date_end = date('Y/m/d', strtotime('last day of previous month')); + $first_of_month = date('Y/m/d', strtotime('first day of previous month')); + $date_init = $first_of_month; + $period = (strtotime($date_end) - strtotime($first_of_month)); + } else if ($range === 'past_week') { + $date_end = date('Y/m/d', strtotime('sunday', strtotime('last week'))); + $first_of_week = date('Y/m/d', strtotime('monday', strtotime('last week'))); + $date_init = $first_of_week; + $period = (strtotime($date_end) - strtotime($first_of_week)); + } + } else { + $date_end = date('Y/m/d H:i:s'); + $date_init = date('Y/m/d H:i:s', (strtotime($date_end) - $range)); + $period = (strtotime($date_end) - strtotime($date_init)); + } + + return [ + 'date_init' => strtotime($date_init), + 'date_end' => strtotime($date_end), + 'period' => $period, + ]; + } + + + /** + * Check user's acl using group. + * + * @param string $group Group to check your acl. + * + * @return string Groups to which the user has access. + */ + private function checkAcl($group) + { + global $config; + + $id_groups = explode(',', $group); + if (in_array(0, $id_groups) === true) { + $id_groups = array_keys(users_get_groups($config['id_user'], 'AR', false)); + } + + foreach ($id_groups as $key => $id_group) { + if ((bool) check_acl_restricted_all($config['id_user'], $id_group, 'AR') === false) { + unset($id_groups[$key]); + } + } + + $id_groups = implode(',', $id_groups); + if ($id_groups === '') { + $id_groups = -1; + } + + return $id_groups; + } + + + /** + * Get the hardening evolution. + * + * @param integer $group Id of group for filter. + * @param integer $date_init Date from which the data starts. + * @param integer $date_end Date from which the data finish. + * + * @return array $return html graph. + */ + private function evolution($group, $date_init, $date_end) + { + if (is_metaconsole() === true) { + $servers = metaconsole_get_servers(); + if (isset($servers) === true + && is_array($servers) === true + ) { + $calculate = [ + 'passed' => [], + 'failed' => [], + ]; + foreach ($servers as $server) { + if (metaconsole_connect($server) == NOERR) { + $evolution_node = get_hardening_evolution($group, $date_init, $date_end, true); + foreach ($evolution_node['passed'] as $key => $passed) { + if (key_exists($passed['utimestamp'], $calculate['passed'])) { + $calculate['passed'][$passed['utimestamp']] = [ + 'sum' => ($calculate['passed'][$passed['utimestamp']]['sum'] + $passed['sum']), + 'count' => ($calculate['passed'][$passed['utimestamp']]['count'] + $passed['count']), + ]; + } else { + $calculate['passed'][$passed['utimestamp']] = [ + 'sum' => $passed['sum'], + 'count' => $passed['count'], + ]; + } + } + + foreach ($evolution_node['failed'] as $key => $failed) { + if (key_exists($failed['utimestamp'], $calculate['failed'])) { + $calculate['failed'][$failed['utimestamp']] = [ + 'sum' => ($calculate['failed'][$failed['utimestamp']]['sum'] + $failed['sum']), + 'count' => ($calculate['failed'][$failed['utimestamp']]['count'] + $failed['count']), + ]; + } else { + $calculate['failed'][$failed['utimestamp']] = [ + 'sum' => $failed['sum'], + 'count' => $failed['count'], + ]; + } + } + } + + metaconsole_restore_db(); + } + + $evolution = [ + 'passed' => [], + 'failed' => [], + ]; + foreach ($calculate['passed'] as $key => $day) { + if (key_exists('count', $day) === true && $day['count'] > 0) { + $evolution['passed'][] = [ + 'utimestamp' => $key, + 'datos' => round(($day['sum'] / $day['count'])), + ]; + } + } + + foreach ($calculate['failed'] as $key => $day) { + if (key_exists('count', $day) === true && $day['count'] > 0) { + $evolution['failed'][] = [ + 'utimestamp' => $key, + 'datos' => round(($day['sum'] / $day['count'])), + ]; + } + } + + usort($evolution['passed'], fn($a, $b) => ($a['utimestamp'] - $b['utimestamp'])); + usort($evolution['failed'], fn($a, $b) => ($a['utimestamp'] - $b['utimestamp'])); + } + } else { + $evolution = get_hardening_evolution($group, $date_init, $date_end, false); + } + + $dates = []; + $dataset_passed = []; + $dataset_failed = []; + foreach ($evolution['passed'] as $key => $raw_data) { + $dates[] = date('Y-m-d', $raw_data['utimestamp']); + $dataset_passed[] = $raw_data['datos']; + } + + foreach ($evolution['failed'] as $key => $raw_data) { + $dataset_failed[] = $raw_data['datos']; + } + + $options = ['labels' => $dates]; + + $data = [ + [ + 'label' => 'Passed', + 'backgroundColor' => '#82b92e', + 'borderColor' => '#82b92e', + 'pointBackgroundColor' => '#82b92e', + 'pointBorderColor' => '#fff', + 'pointHoverBackgroundColor' => '#fff', + 'pointHoverBorderColor' => '#82b92e', + 'data' => $dataset_passed, + ], + [ + 'label' => 'Failed', + 'backgroundColor' => '#e63c52', + 'borderColor' => '#e63c52', + 'pointBackgroundColor' => '#e63c52', + 'pointBorderColor' => '#fff', + 'pointHoverBackgroundColor' => '#fff', + 'pointHoverBorderColor' => '#e63c52', + 'data' => $dataset_failed, + ], + ]; + + $graph_area = line_graph($data, $options); + + return html_print_div( + [ + 'content' => $graph_area, + 'class' => 'flex', + 'style' => 'width: 90%; height: 90%;', + ], + true + ); + } + + + /** + * Return all scoring of agents in range time. + * + * @param integer $group Id of group for filter. + * @param integer $date_init Date from which the data starts. + * @param integer $date_end Date from which the data finish. + * + * @return string Html table with scoring agents. + */ + private function scoring($group, $date_init, $date_end) + { + global $config; + if (is_metaconsole() === true) { + $servers = metaconsole_get_servers(); + if (isset($servers) === true + && is_array($servers) === true + ) { + $scoring_agents = []; + foreach ($servers as $server) { + if (metaconsole_connect($server) == NOERR) { + $scoring_agents = array_merge($scoring_agents, get_scoring_by_agent($group, $date_init, $date_end)); + } + + metaconsole_restore_db(); + } + + $data = $scoring_agents; + } + } else { + $data = get_scoring_by_agent($group, $date_init, $date_end); + } + + if (count($data) === 0) { + return ui_print_info_message(__('No data found'), '', true); + } + + $table = new \stdClass(); + + $table->class = 'info_table'; + $table->width = '100%'; + $table->cellpadding = 0; + $table->cellspacing = 0; + $table->size = []; + $table->size[0] = '30%'; + $table->size[1] = '30%'; + $table->size[2] = '30%'; + + $table->align = []; + $table->align[0] = 'left'; + $table->align[1] = 'left'; + + $table->head = []; + $table->head[0] = __('Date'); + $table->head[1] = __('Agent'); + $table->head[2] = __('Scoring'); + + $table->headstyle = []; + $table->headstyle[0] = 'text-align:left;background-color: '.$this->values['background']; + $table->headstyle[1] = 'text-align:left; background-color: '.$this->values['background']; + $table->headstyle[2] = 'text-align:left; background-color: '.$this->values['background']; + + $table->style = []; + $table->style[0] = 'padding: 0px 10px; background-color: '.$this->values['background'].';'; + $table->style[1] = 'padding: 0px 5px; background-color: '.$this->values['background'].';'; + $table->style[2] = 'text-align:left; background-color: '.$this->values['background'].'; font-weight: bolder;'; + + foreach ($data as $id => $agent) { + $row = []; + $row[0] = date($config['date_format'], $agent['date']); + $row[1] = $agent['agent']; + $row[2] = $agent['scoring'].' %'; + + $table->data[] = $row; + } + + $output = html_print_table($table, true); + + return $output; + } + + + /** + * Get all vunerabilties of category. + * + * @param integer $group Id group for filter. + * @param string $category Category Cis for filter. + * @param boolean $ignore_skipped Boolean for ignore skipped elements. + * + * @return string Html ring graph. + */ + private function vulnerabilitiesByCategory($group, $category, $ignore_skipped=true) + { + $labels = [ + __('Passed'), + __('Failed'), + ]; + + if (is_metaconsole() === true) { + $servers = metaconsole_get_servers(); + if (isset($servers) === true + && is_array($servers) === true + ) { + $vulnerabilities = [ + 'fail' => [], + 'pass' => [], + 'skipped' => [], + ]; + foreach ($servers as $server) { + if (metaconsole_connect($server) == NOERR) { + $vulnerabilities_node = vulnerability_by_category($group, $category, (bool) $ignore_skipped); + if (key_exists('fail', $vulnerabilities_node) === true && count($vulnerabilities_node['fail']) > 0) { + $vulnerabilities['fail'] = ($vulnerabilities['fail'] + $vulnerabilities_node['fail']); + } + + if (key_exists('pass', $vulnerabilities_node) === true && count($vulnerabilities_node['pass']) > 0) { + $vulnerabilities['pass'] = ($vulnerabilities['pass'] + $vulnerabilities_node['pass']); + } + + if (key_exists('skipped', $vulnerabilities_node) === true && count($vulnerabilities_node['skipped']) > 0) { + $vulnerabilities['skipped'] = ($vulnerabilities['skipped'] + $vulnerabilities_node['skipped']); + } + } + + metaconsole_restore_db(); + } + + if (count($vulnerabilities) > 0) { + $data = [ + count($vulnerabilities['pass']), + count($vulnerabilities['fail']), + ]; + $total = (count($vulnerabilities['pass']) + count($vulnerabilities['fail'])); + + if ((bool) $ignore_skipped === false && key_exists('skipped', $vulnerabilities) === true) { + $data[] = count($vulnerabilities['skipped']); + $total += count($vulnerabilities['skipped']); + $labels[] = __('Skipped'); + } + } + } + } else { + $vulnerabilities = vulnerability_by_category($group, $category, $ignore_skipped); + $data = [ + count($vulnerabilities['pass']), + count($vulnerabilities['fail']), + ]; + + $total = (count($vulnerabilities['pass']) + count($vulnerabilities['fail'])); + + if ($ignore_skipped === false) { + $data[] = count($vulnerabilities['skipped']); + $total += count($vulnerabilities['skipped']); + $labels[] = __('Skipped'); + } + } + + $pie = ring_graph( + $data, + [ + 'legend' => [ + 'display' => true, + 'position' => 'right', + 'align' => 'center', + ], + 'elements' => [ + 'center' => [ + 'text' => $total, + 'color' => '#2c3e50', + ], + ], + 'labels' => $labels, + 'colors' => [ + '#82b92e', + '#e63c52', + '#E4E4E4', + ], + ] + ); + + return html_print_div( + [ + 'content' => $pie, + 'class' => 'flex', + 'style' => 'width: 80%; height: 90%;', + ], + true + ); + } + + + /** + * Get top cheks failed by category. + * + * @param integer $group Id of group for filter. + * @param integer $limit Limit of agents for show. + * + * @return string Html table with top n categories checks. + */ + private function topNCategoriesChecks($group, $limit=10) + { + if (is_metaconsole() === true) { + $servers = metaconsole_get_servers(); + $top_category = []; + if (isset($servers) === true + && is_array($servers) === true + ) { + foreach ($servers as $server) { + if (metaconsole_connect($server) == NOERR) { + $top_n_category_fail_in_node = top_n_categories_checks($group, $limit); + foreach ($top_n_category_fail_in_node as $id => $check) { + if (array_key_exists($id, $top_category) === true) { + $top_category[$id]['total'] = ($top_category[$id]['total'] + $check['total']); + } else { + $top_category[$id] = $check; + } + } + } + + metaconsole_restore_db(); + } + + usort( + $top_category, + function ($a, $b) { + if ($a['total'] == $b['total']) { + return 0; + } + + return ($a['total'] > $b['total']) ? -1 : 1; + } + ); + $data = array_slice($top_category, 0, $limit); + } + } else { + $data = top_n_categories_checks($group, $limit); + } + + if (count($data) === 0) { + return ui_print_info_message(__('No data found'), '', true); + } + + $table = new \stdClass(); + + $table->class = 'info_table'; + $table->width = '100%'; + $table->cellpadding = 0; + $table->cellspacing = 0; + $table->size = []; + $table->size[0] = '70%'; + $table->size[1] = '30%'; + + $table->align = []; + $table->align[0] = 'left'; + $table->align[1] = 'left'; + + $table->head = []; + $table->head[0] = __('Category'); + $table->head[1] = __('Total Failed'); + + $table->headstyle = []; + $table->headstyle[0] = 'text-align:left;background-color: '.$this->values['background']; + $table->headstyle[1] = 'text-align:left; background-color: '.$this->values['background']; + + $table->style = []; + $table->style[0] = 'padding: 0px 10px; background-color: '.$this->values['background'].';'; + $table->style[1] = 'background-color: '.$this->values['background'].'; font-weight: bolder;'; + + foreach ($data as $id => $agent) { + $row = []; + $row[0] = $agent['category']; + $row[1] = $agent['total']; + + $table->data[] = $row; + } + + $output = html_print_table($table, true); + + return $output; + } + + + /** + * Get top checks with more failed. + * + * @param integer $group Id of group for filter. + * @param integer $limit Limit of agents for show. + * + * @return string Html table. + */ + private function topNChecksFailed($group, $limit=10) + { + if (is_metaconsole() === true) { + $servers = metaconsole_get_servers(); + $top_checks = []; + if (isset($servers) === true + && is_array($servers) === true + ) { + $numbers_of_nodes = count($servers); + if ($limit > $numbers_of_nodes && $numbers_of_nodes > 0) { + $limit_in_node = ceil(($limit / $numbers_of_nodes)); + } else { + $limit_in_node = 1; + } + + foreach ($servers as $server) { + if (metaconsole_connect($server) == NOERR) { + $top_n_checks_in_node = top_n_checks_failed($group, $limit_in_node); + foreach ($top_n_checks_in_node as $id => $check) { + if (array_key_exists($id, $top_checks) === true) { + $top_checks[$id]['total'] = ($top_checks[$id]['total'] + $check['total']); + } else { + $top_checks[$id] = $check; + } + } + } + + metaconsole_restore_db(); + } + + usort( + $top_checks, + function ($a, $b) { + if ($a['total'] == $b['total']) { + return 0; + } + + return ($a['total'] < $b['total']) ? (-1) : 1; + } + ); + + $data = array_slice($top_checks, 0, $limit); + } + } else { + $data = top_n_checks_failed($group, $limit); + } + + if (count($data) === 0) { + return ui_print_info_message(__('No data found'), '', true); + } + + $table = new \stdClass(); + + $table->class = 'info_table'; + $table->width = '100%'; + $table->cellpadding = 0; + $table->cellspacing = 0; + $table->size = []; + $table->size[0] = '70%'; + $table->size[1] = '30%'; + + $table->align = []; + $table->align[0] = 'left'; + $table->align[1] = 'left'; + + $table->head = []; + $table->head[0] = __('Title'); + $table->head[1] = __('Total Failed'); + + $table->headstyle = []; + $table->headstyle[0] = 'text-align:left;background-color: '.$this->values['background']; + $table->headstyle[1] = 'text-align:left; background-color: '.$this->values['background']; + + $table->style = []; + $table->style[0] = 'padding: 0px 10px; background-color: '.$this->values['background'].';'; + $table->style[1] = 'background-color: '.$this->values['background'].'; font-weight: bolder;'; + + foreach ($data as $id => $agent) { + $row = []; + $row[0] = $agent['title']; + $row[1] = $agent['total']; + + $table->data[] = $row; + } + + $output = html_print_table($table, true); + + return $output; + } + + + /** + * Get top agents with worst score. + * + * @param integer $group Id of group for filter. + * @param integer $limit Limit of agents for show. + * + * @return string Html table. + */ + private function loadTopNAgentsSh($group, $limit=10) + { + global $config; + if (is_metaconsole() === true) { + $servers = metaconsole_get_servers(); + $top_agents = []; + if (isset($servers) === true + && is_array($servers) === true + ) { + $numbers_of_nodes = count($servers); + if ($limit > $numbers_of_nodes && $numbers_of_nodes > 0) { + $limit_in_node = ceil(($limit / $numbers_of_nodes)); + } else { + $limit_in_node = 1; + } + + foreach ($servers as $server) { + if (metaconsole_connect($server) == NOERR) { + $top_agents = array_merge($top_agents, top_n_agents_worses_by_group($group, $limit_in_node)); + } + + metaconsole_restore_db(); + } + + usort( + $top_agents, + function ($a, $b) { + if ($a['datos'] == $b['datos']) { + return 0; + } + + return ($a['datos'] < $b['datos']) ? (-1) : 1; + } + ); + $data = array_slice($top_agents, 0, $limit); + } + } else { + $data = top_n_agents_worses_by_group($group, $limit); + } + + if (count($data) === 0) { + return ui_print_info_message(__('No data found'), '', true); + } + + $table = new \stdClass(); + + $table->class = 'info_table'; + $table->width = '100%'; + $table->cellpadding = 0; + $table->cellspacing = 0; + $table->size = []; + $table->size[0] = '35%'; + $table->size[1] = '32%'; + $table->size[2] = '32%'; + + $table->align = []; + $table->align[0] = 'left'; + $table->align[1] = 'left'; + $table->align[2] = 'left'; + + $table->head = []; + $table->head[0] = __('Alias'); + $table->head[1] = __('Last audit scan'); + $table->head[2] = __('Score'); + + $table->headstyle = []; + $table->headstyle[0] = 'text-align:left;background-color: '.$this->values['background']; + $table->headstyle[1] = 'text-align:left; background-color: '.$this->values['background']; + $table->headstyle[2] = 'text-align:left;background-color: '.$this->values['background']; + + $table->style = []; + $table->style[0] = 'padding: 0px 10px; background-color: '.$this->values['background'].';'; + $table->style[1] = 'background-color: '.$this->values['background'].';'; + $table->style[2] = 'background-color: '.$this->values['background'].'; font-size: 1em; font-weight: bolder;'; + + foreach ($data as $id => $agent) { + $row = []; + $row[0] = $agent['alias']; + $row[1] = date($config['date_format'], $agent['utimestamp']); + $row[2] = $agent['datos'].' %'; + + $table->data[] = $row; + } + + $output = html_print_table($table, true); + + return $output; + } + + + /** + * Return aux javascript code for forms. + * + * @return string + */ + public function getFormJS() + { + $id = uniqid(); + return ' + const dataTypes_'.$id.' = { + "top_n_agents_sh": ["#row_group", "#row_limit"], + "top_n_checks_failed": ["#row_group", "#row_limit"], + "top_n_categories_checks": ["#row_group", "#row_limit"], + "vul_by_cat": ["#row_group", "#row_category", "#row_ignore_skipped"], + "scoring": ["#row_group", "#row_date"], + "evolution": ["#row_group", "#row_date"], + } + function selectData(e){ + $(".row_input").hide(); + dataTypes_'.$id.'[e.value].forEach(element => { + console.log(element); + $(element).show(); + }); + } + $(document).ready(function() { + const input = $("#data_type")[0]; + selectData(input); + }); + '; + } + + + /** + * Get description. + * + * @return string. + */ + public static function getDescription() + { + return __('Security Hardening'); + } + + + /** + * Get Name. + * + * @return string. + */ + public static function getName() + { + return 'security_hardening'; + } + + + /** + * Get size Modal Configuration. + * + * @return array + */ + public function getSizeModalConfiguration(): array + { + $size = [ + 'width' => 400, + 'height' => 530, + ]; + + return $size; + } + + +} diff --git a/pandora_console/include/lib/ITSM/ITSM.php b/pandora_console/include/lib/ITSM/ITSM.php new file mode 100644 index 0000000000..4879ac9f39 --- /dev/null +++ b/pandora_console/include/lib/ITSM/ITSM.php @@ -0,0 +1,612 @@ +userLevelConf = (bool) $config['ITSM_user_level_conf']; + $this->url = ($host ?? $config['ITSM_hostname']); + + $this->userBearer = ($token ?? $config['ITSM_token']); + if ($this->userLevelConf === true) { + $this->userBearer = ($token ?? $user_info['integria_user_level_pass']); + } + } + + + /** + * Call api ITSM. + * + * @param string $action Endpoint. + * @param array $queryParams Params send get. + * @param array $postFields Params send post. + * @param mixed $id Specific id for path. + * @param string|null $method Request method. + * @param array|null $file Upload file. + * @param boolean $download Download file. + * + * @return array Array result. + * @throws \Exception On error. + */ + public function callApi( + string $action, + ?array $queryParams=null, + ?array $postFields=null, + mixed $id=null, + ?string $method='POST', + ?array $file=null, + ?bool $download=false + ) { + $headers = [ + 'accept: application/json', + 'Content-Type: application/json', + 'Authorization: Bearer '.$this->userBearer, + ]; + + $path = $this->pathAction($action, $queryParams, $id); + $url = $this->url.$path; + + $data = []; + // Clean safe_input forms. + if (empty($postFields) === false) { + foreach ($postFields as $key => $field) { + if ($field !== null) { + $field = io_safe_output($field); + } + + $data[$key] = $field; + } + } + + if ($file !== null && file_exists($file['tmp_name']) === true) { + $data['attachment'] = curl_file_create( + $file['tmp_name'], + $file['type'], + $file['name'] + ); + + $headers = [ + 'Content-Type: multipart/form-data', + 'Authorization: Bearer '.$this->userBearer, + ]; + } else { + $data = json_encode($data); + } + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_VERBOSE, true); + $response = curl_exec($ch); + + if ($download === true) { + return $response; + } + + $result = json_decode($response, true); + if (json_last_error() !== JSON_ERROR_NONE) { + throw new \Exception(__('Invalid response').', '.$response); + } + + $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if ($http_status !== 200) { + throw new \Exception($result['error']); + } + + return $result; + } + + + /** + * Convert path to endpoint ITSM. + * + * @param string $action EndPoint. + * @param array|null $queryParams Params to url. + * @param mixed $id Specific id for path. + * + * @return string Return path to Endpoint. + */ + private function pathAction(string $action, ?array $queryParams=null, mixed $id=null): string + { + $path = ''; + switch ($action) { + case 'ping': + $path = '/ping'; + break; + + case 'listTickets': + $path = '/incidence/list'; + break; + + case 'listObjectTypes': + $path = '/incidencetype/list'; + break; + + case 'listGroups': + $path = '/group/list'; + break; + + case 'listResolutions': + $path = '/incidence/resolution/list'; + break; + + case 'listStatus': + $path = '/incidence/status/list'; + break; + + case 'listPriorities': + $path = '/incidence/priority/list'; + break; + + case 'listUsers': + $path = '/user/list'; + break; + + case 'listCompanies': + $path = '/company/list'; + break; + + case 'createIncidence': + $path = '/incidence'; + break; + + case 'updateIncidence': + $path = '/incidence/'.$id; + break; + + case 'incidenceTypeFields': + $path = '/incidencetype/'.$id.'/field/list'; + break; + + case 'incidence': + $path = '/incidence/'.$id; + break; + + case 'deleteIncidence': + $path = '/incidence/'.$id; + break; + + case 'incidenceWus': + $path = '/incidence/'.$id.'/workunit/list'; + break; + + case 'incidenceFiles': + $path = '/incidence/'.$id.'/attachment/list'; + break; + + case 'createIncidenceAttachment': + $path = '/incidence/'.$id.'/attachment'; + break; + + case 'createIncidenceWu': + $path = '/incidence/'.$id.'/workunit'; + break; + + case 'deleteIncidenceAttachment': + $path = '/incidence/'.$id['idIncidence'].'/attachment/'.$id['idAttachment']; + break; + + case 'downloadIncidenceAttachment': + $path = '/incidence/'.$id['idIncidence'].'/attachment/'.$id['idAttachment'].'/download'; + break; + + case 'getIncidencesGroupedByStatus': + $path = '/incidence/statistic/groupedByStatus'; + break; + + case 'getIncidencesGroupedByPriorities': + $path = '/incidence/statistic/groupedByPriorities'; + break; + + case 'getIncidencesGroupedByGroups': + $path = '/incidence/statistic/groupedByGroups'; + break; + + case 'getIncidencesGroupedByOwners': + $path = '/incidence/statistic/groupedByOwners'; + break; + + case 'listCustomSearch': + $path = '/customSearch/list'; + break; + + case 'customSearch': + $path = '/customSearch/'.$id; + break; + + case 'inventory': + $path = '/inventory/'.$id; + break; + + case 'createNode': + $path = '/pandorafms/nodes'; + break; + + case 'getNode': + $path = '/pandorafms/node/'.$id; + break; + + case 'pingItsmToPandora': + $path = '/pandorafms/node/ping'; + break; + + default: + // Not posible. + break; + } + + if (empty($queryParams) === false) { + if (isset($queryParams['field']) === true) { + $queryParams['sortField'] = $queryParams['field']; + unset($queryParams['field']); + } + + if (isset($queryParams['direction']) === true) { + $queryParams['sortDirection'] = $queryParams['direction']; + unset($queryParams['direction']); + } + + $path .= '?'; + $path .= http_build_query($queryParams); + } + + return $path; + } + + + /** + * Ping API. + * + * @return boolean Data incidence + */ + public function ping(): bool + { + $result = $this->callApi( + 'ping', + [], + [], + null, + 'GET' + ); + + return $result['valid']; + } + + + /** + * Get Groups. + * + * @return array Return mode select. + */ + public function getGroups(): array + { + $listGroups = $this->callApi('listGroups'); + $result = []; + foreach ($listGroups['data'] as $group) { + if ($group['idGroup'] > 1) { + $result[$group['idGroup']] = $group['name']; + } + } + + return $result; + } + + + /** + * Get Priorities. + * + * @return array Return mode select. + */ + public function getPriorities(): array + { + $listPriorities = $this->callApi('listPriorities'); + return $listPriorities; + } + + + /** + * Get Status. + * + * @return array Return mode select. + */ + public function getStatus(): array + { + $listStatus = $this->callApi('listStatus'); + $result = []; + foreach ($listStatus['data'] as $status) { + $result[$status['idIncidenceStatus']] = $status['name']; + } + + return $result; + } + + + /** + * Get Incidences types. + * + * @return array Return mode select. + */ + public function getObjectypes(): array + { + $listObjectTypes = $this->callApi('listObjectTypes'); + $result = []; + foreach ($listObjectTypes['data'] as $objectType) { + $result[$objectType['idIncidenceType']] = $objectType['name']; + } + + return $result; + } + + + /** + * Get fields incidence type. + * + * @param integer $idIncidenceType Incidence Type ID. + * + * @return array Fields array. + */ + public function getObjecTypesFields(int $idIncidenceType): array + { + $result = $this->callApi( + 'incidenceTypeFields', + [ + 'page' => 0, + 'sizePage' => 0, + 'field' => 'idIncidenceTypeField', + 'direction' => 'ascending', + ], + [], + $idIncidenceType + ); + + return $result['data']; + } + + + /** + * List custom search. + * + * @return array Result. + */ + public function listCustomSearch(): array + { + $listCustomSearch = $this->callApi( + 'listCustomSearch', + [ + 'page' => 0, + 'sizePage' => 0, + ], + ['section' => 'incidences'] + ); + + $result = []; + foreach ($listCustomSearch['data'] as $customSearch) { + $result[$customSearch['idCustomSearch']] = $customSearch['name']; + } + + return $result; + } + + + /** + * Get Custom search. + * + * @param integer $idCustomSearch Custom search ID. + * + * @return array Data custom search. + */ + public function getCustomSearch(int $idCustomSearch): array + { + $result = $this->callApi( + 'customSearch', + [], + [], + $idCustomSearch, + 'GET' + ); + + return $result; + } + + + /** + * List incidences. + * + * @param integer $idAgent Agent id. + * + * @return array list Incidences. + */ + public function listIncidenceAgents(int $idAgent, ?bool $blocked=null): array + { + global $config; + $listIncidences = $this->callApi( + 'listTickets', + [ + 'page' => 0, + 'sizePage' => 0, + ], + [ + 'externalIdLike' => $config['metaconsole_node_id'].'-'.$idAgent, + 'blocked' => $blocked, + ] + ); + + return $listIncidences['data']; + } + + + /** + * Get table incicidences for agent. + * + * @param integer $idAgent Id agent. + * @param boolean|null $mini Visual mode mini. + * @param integer|null $blocked Blocked. + * + * @return string Html output. + */ + public function getTableIncidencesForAgent(int $idAgent, ?bool $mini=false, ?int $blocked=null) + { + \ui_require_css_file('pandoraitsm'); + \ui_require_javascript_file('ITSM'); + + global $config; + $columns = [ + 'idIncidence', + 'title', + 'groupCompany', + 'statusResolution', + 'priority', + 'updateDate', + 'startDate', + 'idCreator', + 'owner', + ]; + + $column_names = [ + __('ID'), + __('Title'), + __('Group').'/'.__('Company'), + __('Status').'/'.__('Resolution'), + __('Priority'), + __('Updated'), + __('Started'), + __('Creator'), + __('Owner'), + ]; + + $options = [ + 'id' => 'itms_list_tickets', + 'class' => 'info_table', + 'style' => 'width: 99%', + 'columns' => $columns, + 'column_names' => $column_names, + 'ajax_url' => 'operation/ITSM/itsm', + 'ajax_data' => [ + 'method' => 'getListTickets', + 'externalIdLike' => $config['metaconsole_node_id'].'-'.$idAgent, + 'blocked' => $blocked, + ], + 'no_sortable_columns' => [ + 2, + 3, + -1, + ], + 'order' => [ + 'field' => 'updateDate', + 'direction' => 'desc', + ], + 'return' => true, + ]; + + if ($mini === true) { + $options['csv'] = 0; + $options['dom_elements'] = 'frtip'; + } + + return ui_print_datatable($options); + } + + + /** + * Create Node in pandora ITSM. + * + * @param array $data Info connect to node from ITSM. + * + * @return boolean + */ + public function createNode(array $data): array + { + return $this->callApi('createNode', null, $data); + } + + + /** + * Get info node sincronization. + * + * @param string $serverAuth Server Auth. + * + * @return array Array. + */ + public function getNode(string $serverAuth): array + { + $result = $this->callApi( + 'getNode', + [], + [], + $serverAuth, + 'GET' + ); + + return $result; + } + + + /** + * Ping Itsm to pandora node. + * + * @param string $path Path. + * + * @return boolean + */ + public function pingItsmtoPandora(string $path): bool + { + global $config; + + $result = $this->callApi( + 'pingItsmToPandora', + [], + [ + 'path' => $path, + 'apiPass' => $config['api_password'], + 'serverAuth' => $config['server_unique_identifier'], + ] + ); + + return (bool) $result['valid']; + } + + +} diff --git a/pandora_console/include/lib/ITSM/Manager.php b/pandora_console/include/lib/ITSM/Manager.php new file mode 100644 index 0000000000..3e98ca4307 --- /dev/null +++ b/pandora_console/include/lib/ITSM/Manager.php @@ -0,0 +1,1512 @@ +operation = \get_parameter('operation', 0); + + // Urls. + $this->url = \ui_get_full_url( + 'index.php?sec=reporting&sec2=operation/dashboard/dashboard' + ); + + $this->ajaxController = $page; + } + + + /** + * Checks if target method is available to be called using AJAX. + * + * @param string $method Target method. + * + * @return boolean True allowed, false not. + */ + public function ajaxMethod(string $method): bool + { + return in_array($method, $this->AJAXMethods); + } + + + /** + * Prints error. + * + * @param string $msg Message. + * + * @return void + */ + public function error(string $msg) + { + if ((bool) \is_ajax() === true) { + echo json_encode(['error' => $msg]); + } else { + \ui_print_error_message($msg); + } + } + + + /** + * Init manager ITSM. + * + * @return void + */ + public function run() + { + \ui_require_css_file('pandoraitsm'); + \ui_require_javascript_file('ITSM'); + switch ($this->operation) { + case 'list': + $this->showList(); + break; + + case 'edit': + $this->showEdit(); + break; + + case 'detail': + $this->showDetail(); + break; + + case 'dashboard': + default: + $this->showDashboard(); + break; + } + } + + + /** + * Draw list tickets. + * + * @return void + */ + private function showList() + { + $idIncidence = \get_parameter('idIncidence', 0); + $error = ''; + $successfullyMsg = ''; + $groups = []; + $status = []; + $priorities = []; + + $headerTabs = $this->headersTabs('list'); + + try { + $ITSM = new ITSM(); + $groups = $ITSM->getGroups(); + $status = $ITSM->getStatus(); + $priorities = $ITSM->getPriorities(); + if (empty($idIncidence) === false) { + $this->deleteIncidence($ITSM, $idIncidence); + $successfullyMsg = __('Delete ticket successfully'); + } + } catch (\Throwable $th) { + $error = $th->getMessage(); + } + + View::render( + 'ITSM/ITSMTicketListView', + [ + 'ajaxController' => $this->ajaxController, + 'urlAjax' => \ui_get_full_url('ajax.php'), + 'error' => $error, + 'successfullyMsg' => $successfullyMsg, + 'groups' => $groups, + 'status' => $status, + 'priorities' => $priorities, + 'headerTabs' => $headerTabs, + ] + ); + } + + + /** + * Draw list tickets. + * + * @return void + */ + private function showEdit() + { + global $config; + $create_incidence = (bool) \get_parameter('create_incidence', 0); + $update_incidence = (bool) \get_parameter('update_incidence', 0); + $idIncidence = (int) \get_parameter('idIncidence', 0); + $idEvent = (int) \get_parameter('from_event', 0); + + $headerTabs = $this->headersTabs('edit', $idIncidence); + + $error = ''; + try { + $ITSM = new ITSM(); + $objectTypes = $ITSM->getObjectypes(); + $groups = $ITSM->getGroups(); + $priorities = $ITSM->getPriorities(); + $resolutions = $this->getResolutions($ITSM); + $status = $ITSM->getStatus(); + + if (empty($idIncidence) === false) { + $incidenceData = $this->getIncidence($ITSM, $idIncidence); + } + } catch (\Throwable $th) { + $error = $th->getMessage(); + } + + $default_values = [ + 'title' => '', + 'idIncidenceType' => 0, + 'idGroup' => 0, + 'priority' => 'LOW', + 'status' => 'NEW', + 'idCreator' => '', + 'owner' => '', + 'resolution' => null, + 'description' => '', + ]; + + if (empty($idEvent) === false) { + $default_values = [ + 'title' => $config['cr_incident_title'], + 'idIncidenceType' => $config['cr_incident_type'], + 'idGroup' => $config['cr_default_group'], + 'priority' => $config['cr_default_criticity'], + 'status' => $config['cr_incident_status'], + 'idCreator' => '', + 'owner' => $config['cr_default_owner'], + 'resolution' => null, + 'description' => $config['cr_incident_content'], + ]; + } + + $incidence = [ + 'title' => \get_parameter('title', ($incidenceData['title'] ?? $default_values['title'])), + 'idIncidenceType' => \get_parameter('idIncidenceType', ($incidenceData['idIncidenceType'] ?? $default_values['idIncidenceType'])), + 'idGroup' => \get_parameter('idGroup', ($incidenceData['idGroup'] ?? $default_values['idGroup'])), + 'priority' => \get_parameter('priority', ($incidenceData['priority'] ?? $default_values['priority'])), + 'status' => \get_parameter('status', ($incidenceData['status'] ?? $default_values['status'])), + 'idCreator' => \get_parameter('idCreator', ($incidenceData['idCreator'] ?? $default_values['idCreator'])), + 'owner' => \get_parameter('owner_hidden', ($incidenceData['owner'] ?? $default_values['owner'])), + 'resolution' => \get_parameter('resolution', ($incidenceData['resolution'] ?? $default_values['resolution'])), + 'description' => \get_parameter('description', ($incidenceData['description'] ?? $default_values['description'])), + ]; + + $successfullyMsg = ''; + try { + if (empty($incidence['idIncidenceType']) === false + && ($create_incidence === true || $update_incidence === true) + ) { + $customFields = \get_parameter('custom-fields', []); + if (empty($customFields) === false) { + $typeFieldData = []; + foreach ($customFields as $idField => $data) { + $typeFieldData[] = [ + 'idIncidenceTypeField' => $idField, + 'data' => $data, + ]; + } + } + + $incidence['typeFieldData'] = $typeFieldData; + } else { + $incidence['typeFieldData'] = $incidenceData['typeFieldData']; + } + + if ($create_incidence === true) { + $incidence = $this->createIncidence($ITSM, $incidence); + $idIncidence = $incidence['idIncidence']; + $successfullyMsg = __('Successfully create ticket'); + } + + if ($update_incidence === true) { + $incidence = $this->updateIncidence($ITSM, $incidence, $idIncidence); + $successfullyMsg = __('Successfully update ticket'); + } + } catch (\Throwable $th) { + $error = $th->getMessage(); + } + + View::render( + 'ITSM/ITSMTicketEditView', + [ + 'ajaxController' => $this->ajaxController, + 'urlAjax' => \ui_get_full_url('ajax.php'), + 'objectTypes' => $objectTypes, + 'groups' => $groups, + 'priorities' => [], + 'resolutions' => $resolutions, + 'status' => $status, + 'priorities' => $priorities, + 'error' => $error, + 'incidence' => $incidence, + 'idIncidence' => $idIncidence, + 'successfullyMsg' => $successfullyMsg, + 'headerTabs' => $headerTabs, + ] + ); + } + + + /** + * Draw list tickets. + * + * @return void + */ + private function showDetail() + { + $idIncidence = (int) \get_parameter('idIncidence', 0); + $uploadFile = (bool) \get_parameter('upload_file', 0); + $idAttachment = (int) \get_parameter('idAttachment', 0); + $addComment = (bool) \get_parameter('addComment', 0); + + $headerTabs = $this->headersTabs('detail', $idIncidence); + + $error = ''; + $error_upload = ''; + $error_comment = ''; + $error_delete_attachment = ''; + $successfullyMsg = null; + $incidence = null; + $objectTypes = null; + $groups = null; + $resolutions = null; + $status = null; + $wus = null; + $files = null; + $users = null; + $priorities = null; + $priorityDiv = null; + $inventories = null; + $ITSM = new ITSM(); + + try { + if ($uploadFile === true) { + $attachment = [ + 'description' => get_parameter('file_description', ''), + ]; + + $incidenceAttachment = $this->createIncidenceAttachment( + $ITSM, + $idIncidence, + $attachment, + get_parameter('userfile') + ); + + if ($incidenceAttachment !== false) { + $successfullyMsg = __('File added succesfully'); + } + } + } catch (\Exception $e) { + hd($e->getMessage()); + $error_upload = $e->getMessage(); + } + + try { + if ($addComment === true) { + $wu = [ + 'description' => get_parameter('comment_description', ''), + ]; + + $incidenceAttachment = $this->createIncidenceWu( + $ITSM, + $idIncidence, + $wu + ); + + if ($incidenceAttachment !== false) { + $successfullyMsg = __('Comment added succesfully'); + } + } + } catch (\Exception $e) { + $error_comment = $e->getMessage(); + } + + try { + if (empty($idAttachment) === false) { + $this->deleteIncidenceAttachment($ITSM, $idIncidence, $idAttachment); + $successfullyMsg = __('Delete File successfully'); + } + } catch (\Exception $e) { + $error_delete_attachment = $e->getMessage(); + } + + try { + if (empty($idIncidence) === false) { + $incidence = $this->getIncidence($ITSM, $idIncidence); + $objectTypes = $ITSM->getObjectypes(); + $groups = $ITSM->getGroups(); + $resolutions = $this->getResolutions($ITSM); + $status = $ITSM->getStatus(); + $priorities = $ITSM->getPriorities(); + $wus = $this->getIncidenceWus($ITSM, $idIncidence); + $files = $this->getIncidenceFiles($ITSM, $idIncidence); + + $usersInvolved = []; + $usersInvolved[$incidence['idCreator']] = $incidence['idCreator']; + $usersInvolved[$incidence['owner']] = $incidence['owner']; + $usersInvolved[$incidence['closedBy']] = $incidence['closedBy']; + + foreach ($wus['data'] as $wu) { + $usersInvolved[$wu['idUser']] = $wu['idUser']; + } + + foreach ($files['data'] as $file) { + $usersInvolved[$file['idUser']] = $file['idUser']; + } + + $users = $this->getUsers($ITSM, $usersInvolved); + + $inventories = []; + $priorityDiv = $this->priorityDiv($incidence['priority'], $priorities[$incidence['priority']]); + if (empty($incidence) === false + && isset($incidence['inventories']) === true + && empty($incidence['inventories']) === false + ) { + foreach ($incidence['inventories'] as $inventory) { + $inventories[] = $this->getInventory($ITSM, $inventory['idInventory']); + } + } + } + } catch (\Exception $e) { + $error = $e->getMessage(); + } + + View::render( + 'ITSM/ITSMTicketDetailView', + [ + 'ajaxController' => $this->ajaxController, + 'urlAjax' => \ui_get_full_url('ajax.php'), + 'error' => $error, + 'error_upload' => $error_upload, + 'error_comment' => $error_comment, + 'error_delete_attachment' => $error_delete_attachment, + 'successfullyMsg' => $successfullyMsg, + 'incidence' => $incidence, + 'objectTypes' => $objectTypes, + 'groups' => $groups, + 'resolutions' => $resolutions, + 'status' => $status, + 'wus' => $wus, + 'files' => $files, + 'users' => $users, + 'priorities' => $priorities, + 'priorityDiv' => $priorityDiv, + 'headerTabs' => $headerTabs, + 'inventories' => $inventories, + ] + ); + } + + + /** + * Draw list dashboards. + * + * @return void + */ + private function showDashboard() + { + $error = ''; + + $headerTabs = $this->headersTabs('dashboard'); + + try { + $ITSM = new ITSM(); + $status = $ITSM->getStatus(); + $incidencesByStatus = $this->getIncidencesGroupedByStatus($ITSM, $status); + $priorities = $ITSM->getPriorities(); + $incidencesByPriorities = $this->getIncidencesGroupedByPriorities($ITSM, $priorities); + $incidencesByGroups = $this->getIncidencesGroupedByGroups($ITSM); + $incidencesByOwners = $this->getIncidencesGroupedByOwners($ITSM); + } catch (\Throwable $th) { + $error = $th->getMessage(); + } + + View::render( + 'ITSM/ITSMDashboardView', + [ + 'ajaxController' => $this->ajaxController, + 'urlAjax' => \ui_get_full_url('ajax.php'), + 'incidencesByStatus' => $incidencesByStatus, + 'incidencesByPriorities' => $incidencesByPriorities, + 'incidencesByGroups' => $incidencesByGroups, + 'incidencesByOwners' => $incidencesByOwners, + 'error' => $error, + 'headerTabs' => $headerTabs, + ] + ); + } + + + /** + * Get Resolutions. + * + * @param ITSM $ITSM Object for callApi. + * + * @return array Return mode select. + */ + private function getResolutions(ITSM $ITSM): array + { + $listResolutions = $ITSM->callApi('listResolutions'); + $result = []; + foreach ($listResolutions['data'] as $resolution) { + $result[$resolution['idIncidenceResolution']] = $resolution['name']; + } + + return $result; + } + + + /** + * Create incidence + * + * @param ITSM $ITSM Object for callApi. + * @param array $incidence Params insert. + * + * @return array + */ + private function createIncidence(ITSM $ITSM, array $incidence): array + { + $incidence = $ITSM->callApi('createIncidence', null, $incidence); + return $incidence; + } + + + /** + * Update incidence + * + * @param ITSM $ITSM Object for callApi. + * @param array $incidence Params insert. + * @param integer $idIncidence Id incidence. + * + * @return array + */ + private function updateIncidence(ITSM $ITSM, array $incidence, int $idIncidence): array + { + $incidence = $ITSM->callApi( + 'updateIncidence', + null, + $incidence, + $idIncidence, + 'PUT' + ); + return $incidence; + } + + + /** + * Get Incidence. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idIncidence Incidence ID. + * + * @return array Data incidence + */ + private function getIncidence(ITSM $ITSM, int $idIncidence): array + { + $result = $ITSM->callApi( + 'incidence', + [], + [], + $idIncidence, + 'GET' + ); + + return $result; + } + + + /** + * Delete Incidence. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idIncidence Incidence ID. + * + * @return void + */ + private function deleteIncidence(ITSM $ITSM, int $idIncidence): void + { + $ITSM->callApi( + 'deleteIncidence', + [], + [], + $idIncidence, + 'DELETE' + ); + } + + + /** + * Get fields incidence type. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idIncidenceType Incidence Type ID. + * + * @return array Fields array. + */ + private function getFieldsIncidenceType(ITSM $ITSM, int $idIncidenceType): array + { + $result = $ITSM->callApi( + 'incidenceTypeFields', + [ + 'page' => 0, + 'sizePage' => 0, + 'field' => 'idIncidenceTypeField', + 'direction' => 'ascending', + ], + [], + $idIncidenceType + ); + + return $result; + } + + + /** + * Get Incidence Work units. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idIncidence Incidence ID. + * + * @return array Data workUnits incidence. + */ + private function getIncidenceWus(ITSM $ITSM, int $idIncidence): array + { + $result = $ITSM->callApi( + 'incidenceWus', + [ + 'page' => 0, + 'sizePage' => 0, + ], + [], + $idIncidence + ); + + return $result; + } + + + /** + * Get Incidence Attachments. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idIncidence Incidence ID. + * + * @return array Data attachment incidence. + */ + private function getIncidenceFiles(ITSM $ITSM, int $idIncidence): array + { + $result = $ITSM->callApi( + 'incidenceFiles', + [ + 'page' => 0, + 'sizePage' => 0, + ], + [], + $idIncidence + ); + + return $result; + } + + + /** + * Get Users. + * + * @param ITSM $ITSM Object for callApi. + * @param array $users Users ID. + * + * @return array Users. + */ + private function getUsers(ITSM $ITSM, array $users): array + { + $result = $ITSM->callApi( + 'listUsers', + [ + 'page' => 0, + 'sizePage' => 0, + ], + [ + 'multipleSearchString' => [ + 'field' => 'idUser', + 'data' => $users, + ], + ] + ); + + $res = []; + if (empty($result['data']) === false) { + $res = array_reduce( + $result['data'], + function ($carry, $user) { + $carry[$user['idUser']] = [ + 'fullName' => $user['fullName'], + 'idCompany' => $user['idCompany'], + ]; + return $carry; + } + ); + } + + return $res; + } + + + /** + * Get Companies. + * + * @param ITSM $ITSM Object for callApi. + * @param array $companies Companies ID. + * + * @return array Companies. + */ + private function getCompanies(ITSM $ITSM, array $companies): array + { + $result = $ITSM->callApi( + 'listCompanies', + [ + 'page' => 0, + 'sizePage' => 0, + ], + [ + 'multipleSearchString' => [ + 'field' => 'idCompany', + 'data' => $companies, + ], + ] + ); + + $res = []; + if (empty($result['data']) === false) { + $res = array_reduce( + $result['data'], + function ($carry, $company) { + $carry[$company['idCompany']] = $company['name']; + return $carry; + } + ); + } + + return $res; + } + + + /** + * Create incidence Attachment. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idIncidence Id incidence. + * @param array $attachment Params insert. + * @param array $file Info file. + * + * @return array + */ + private function createIncidenceAttachment(ITSM $ITSM, int $idIncidence, array $attachment, array $file): array + { + $incidenceAttachment = $ITSM->callApi( + 'createIncidenceAttachment', + null, + $attachment, + $idIncidence, + 'POST', + $file + ); + return $incidenceAttachment; + } + + + /** + * Create incidence Wu. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idIncidence Id incidence. + * @param array $wu Params insert. + * + * @return array + */ + private function createIncidenceWu(ITSM $ITSM, int $idIncidence, array $wu): array + { + $incidenceWu = $ITSM->callApi( + 'createIncidenceWu', + null, + $wu, + $idIncidence, + 'POST' + ); + return $incidenceWu; + } + + + /** + * Delete Attachment. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idIncidence Incidence ID. + * @param integer $idAttachment Attachment ID. + * + * @return void + */ + private function deleteIncidenceAttachment(ITSM $ITSM, int $idIncidence, int $idAttachment): void + { + $ITSM->callApi( + 'deleteIncidenceAttachment', + [], + [], + [ + 'idIncidence' => $idIncidence, + 'idAttachment' => $idAttachment, + ], + 'DELETE' + ); + } + + + /** + * Download Attachment. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idIncidence Incidence ID. + * @param integer $idAttachment Attachment ID. + * + * @return mixed + */ + private function downloadIncidenceAttachment(ITSM $ITSM, int $idIncidence, int $idAttachment) + { + return $ITSM->callApi( + 'downloadIncidenceAttachment', + [], + [], + [ + 'idIncidence' => $idIncidence, + 'idAttachment' => $idAttachment, + ], + 'GET', + null, + true + ); + } + + + /** + * Get Incidences group by for status. + * + * @param ITSM $ITSM Object for callApi. + * @param array $status Status. + * + * @return array + */ + private function getIncidencesGroupedByStatus(ITSM $ITSM, array $status): array + { + $listStatus = $ITSM->callApi('getIncidencesGroupedByStatus'); + $result = []; + foreach ($status as $key => $value) { + if (isset($listStatus[$key]) === false) { + $listStatus[$key] = 0; + } + + $result[$value] = $listStatus[$key]; + } + + return $result; + } + + + /** + * Get Incidences group by for priorities. + * + * @param ITSM $ITSM Object for callApi. + * @param array $priorities Priorities. + * + * @return array + */ + private function getIncidencesGroupedByPriorities(ITSM $ITSM, array $priorities): array + { + $listPriorities = $ITSM->callApi('getIncidencesGroupedByPriorities'); + $result = []; + foreach ($priorities as $key => $value) { + if (isset($listPriorities[$key]) === false) { + $listPriorities[$key] = 0; + } + + $result[$value] = $listPriorities[$key]; + } + + return $result; + } + + + /** + * Get Inventory. + * + * @param ITSM $ITSM Object for callApi. + * @param integer $idInventory Inventory ID. + * + * @return array Data inventory + */ + private function getInventory(ITSM $ITSM, int $idInventory): array + { + $result = $ITSM->callApi( + 'inventory', + [], + [], + $idInventory, + 'GET' + ); + + return $result; + } + + + /** + * Get Incidences group by for groups. + * + * @param ITSM $ITSM Object for callApi. + * + * @return array + */ + private function getIncidencesGroupedByGroups(ITSM $ITSM): array + { + return $ITSM->callApi('getIncidencesGroupedByGroups'); + } + + + /** + * Get Incidences group by for owner. + * + * @param ITSM $ITSM Object for callApi. + * + * @return array + */ + private function getIncidencesGroupedByOwners(ITSM $ITSM): array + { + return $ITSM->callApi('getIncidencesGroupedByOwners'); + } + + + /** + * Draw priority div. + * + * @param string $priority Priority incidence. + * @param string $label Name. + * + * @return string Html output. + */ + private function priorityDiv(string $priority, string $label) + { + $output = ''; + switch ($priority) { + case 'LOW': + $color = COL_NORMAL; + break; + + case 'INFORMATIVE': + $color = COL_UNKNOWN; + break; + + case 'MEDIUM': + $color = COL_WARNING; + break; + + case 'SERIOUS': + $color = COL_ALERTFIRED; + break; + + case 'VERY_SERIOUS': + $color = COL_CRITICAL; + break; + + default: + $color = COL_NOTINIT; + break; + } + + $output = '
'; + $output .= $label; + $output .= '
'; + + return $output; + } + + + /** + * Headers tabs + * + * @param string $active_tab Section. + * @param integer $idIncidence Id incidence. + * + * @return array Headers. + */ + private function headersTabs(string $active_tab, int $idIncidence=0): array + { + $url_tabs = ui_get_full_url('index.php?sec=ITSM&sec2=operation/ITSM/itsm'); + $url_setup = ui_get_full_url('index.php?sec=general&sec2=godmode/setup/setup§ion=ITSM'); + + $setup_tab['text'] = ''; + $setup_tab['text'] .= html_print_image( + 'images/configuration@svg.svg', + true, + [ + 'title' => __('Configure Pandora ITSM'), + 'class' => 'main_menu_icon invert_filter', + ] + ); + $setup_tab['text'] .= ''; + + $list_tab['text'] = ''; + $list_tab['text'] .= html_print_image( + 'images/logs@svg.svg', + true, + [ + 'title' => __('List'), + 'class' => 'main_menu_icon invert_filter', + ] + ); + $list_tab['text'] .= ''; + + $create_tab['text'] = ''; + $create_tab['text'] .= html_print_image( + 'images/edit.svg', + true, + [ + 'title' => __('New'), + 'class' => 'main_menu_icon invert_filter', + ] + ); + $create_tab['text'] .= ''; + + $dashboard_tab['text'] = ''; + $dashboard_tab['text'] .= html_print_image( + 'images/item-icon.svg', + true, + [ + 'title' => __('Dashboard'), + 'class' => 'main_menu_icon invert_filter', + ] + ); + $dashboard_tab['text'] .= ''; + + if ($idIncidence !== 0) { + $create_tab['text'] = ''; + $create_tab['text'] .= html_print_image( + 'images/edit.svg', + true, + [ + 'title' => __('Edit'), + 'class' => 'main_menu_icon invert_filter', + ] + ); + $create_tab['text'] .= ''; + + $view_tab['text'] = ''; + $view_tab['text'] .= html_print_image( + 'images/enable.svg', + true, + [ + 'title' => __('Detail'), + 'class' => 'main_menu_icon invert_filter', + ] + ); + $view_tab['text'] .= ''; + } + + switch ($active_tab) { + case 'setup': + $setup_tab['active'] = true; + $list_tab['active'] = false; + $create_tab['active'] = false; + $dashboard_tab['active'] = false; + if ($idIncidence !== 0) { + $view_tab['active'] = false; + } + break; + + case 'list': + $setup_tab['active'] = false; + $list_tab['active'] = true; + $create_tab['active'] = false; + $dashboard_tab['active'] = false; + if ($idIncidence !== 0) { + $view_tab['active'] = false; + } + break; + + case 'edit': + $setup_tab['active'] = false; + $list_tab['active'] = false; + $create_tab['active'] = true; + $dashboard_tab['active'] = false; + if ($idIncidence !== 0) { + $view_tab['active'] = false; + } + break; + + case 'detail': + $setup_tab['active'] = false; + $list_tab['active'] = false; + $create_tab['active'] = false; + $dashboard_tab['active'] = false; + if ($idIncidence !== 0) { + $view_tab['active'] = true; + } + break; + + case 'dashboard': + $setup_tab['active'] = false; + $list_tab['active'] = false; + $create_tab['active'] = false; + $dashboard_tab['active'] = true; + if ($idIncidence !== 0) { + $view_tab['active'] = false; + } + break; + + default: + // Not possible. + break; + } + + $onheader = []; + $onheader['configure'] = $setup_tab; + $onheader['dashboard'] = $dashboard_tab; + $onheader['list'] = $list_tab; + if ($idIncidence !== 0) { + $onheader['view'] = $view_tab; + } + + $onheader['create'] = $create_tab; + + return $onheader; + } + + + /** + * Get list tickets and prepare data for datatable. + * + * @return void + */ + public function getListTickets() + { + global $config; + + // Init data. + $data = []; + + // Catch post parameters. + $start = (int) get_parameter('start', 1); + $length = (int) get_parameter('length', $config['block_size']); + $order = get_datatable_order(true); + $filters = get_parameter('filter', []); + + $customSearch = (int) get_parameter('customSearch', 0); + if (empty($customSearch) === false) { + try { + $ITSM = new ITSM(); + $customSearchData = ($ITSM->getCustomSearch($customSearch)['formValues'] ?? []); + } catch (\Throwable $th) { + $error = $th->getMessage(); + $customSearchData = []; + } + + $filters = $customSearchData; + } + + $externalIdLike = get_parameter('externalIdLike', ''); + if (empty($externalIdLike) === false) { + $filters['externalIdLike'] = $externalIdLike; + } + + $blocked = get_parameter('blocked', null); + if (isset($blocked) === true) { + $filters['blocked'] = $blocked; + } + + if (isset($filters['status']) === true && empty($filters['status']) === true) { + unset($filters['status']); + } + + if (isset($filters['priority']) === true && empty($filters['priority']) === true) { + unset($filters['priority']); + } + + if (isset($filters['idGroup']) === true && (empty($filters['idGroup']) === true || $filters['idGroup'] < 0)) { + unset($filters['idGroup']); + } + + if (isset($filters['fromDate']) === true && empty($filters['fromDate']) === false) { + $filters['fromDate'] = ($filters['fromDate'] / SECONDS_1DAY); + } + + if (isset($filters['form_itms_list_tickets_search_bt']) === true) { + unset($filters['form_itms_list_tickets_search_bt']); + } + + if (isset($filters['fromDate_select']) === true) { + unset($filters['fromDate_select']); + } + + if (isset($filters['fromDate_text']) === true) { + unset($filters['fromDate_text']); + } + + if (isset($filters['fromDate_units']) === true) { + unset($filters['fromDate_units']); + } + + try { + ob_start(); + $queryParams = [ + 'page' => ($start === 0) ? $start : ($start / $length), + 'sizePage' => $length, + 'sortField' => $order['field'], + 'sortDirection' => $order['direction'], + ]; + + $ITSM = new ITSM(); + $result = $ITSM->callApi( + 'listTickets', + $queryParams, + $filters + ); + + $groups = $ITSM->getGroups(); + $resolutions = $this->getResolutions($ITSM); + $resolutions['NOTRESOLVED'] = __('None'); + $status = $ITSM->getStatus(); + $priorities = $ITSM->getPriorities(); + + $usersInvolved = []; + $usersCreators = []; + foreach ($result['data'] as $incidence) { + $usersCreators[$incidence['idCreator']] = $incidence['idCreator']; + $usersInvolved[$incidence['idCreator']] = $incidence['idCreator']; + $usersInvolved[$incidence['owner']] = $incidence['owner']; + $usersInvolved[$incidence['closedBy']] = $incidence['closedBy']; + } + + $users = $this->getUsers($ITSM, $usersInvolved); + $companiesCreator = []; + foreach ($usersCreators as $userInfo) { + $companiesCreator[$userInfo] = $users[$userInfo]['idCompany']; + } + + if (empty($companiesCreator) === false) { + $companies = $this->getCompanies($ITSM, $companiesCreator); + } + + $url = \ui_get_full_url('index.php?sec=manageTickets&sec2=operation/ITSM/itsm'); + + if (empty($result['data']) === false) { + $data = array_reduce( + $result['data'], + function ( + $carry, + $item + ) use ( + $groups, + $resolutions, + $status, + $priorities, + $users, + $companies, + $url + ) { + // Transforms array of arrays $data into an array + // of objects, making a post-process of certain fields. + $tmp = (object) $item; + + $new = (object) []; + $new->idIncidence = $tmp->idIncidence; + $new->title = ''; + $new->title .= $tmp->title; + $new->title .= ''; + $new->groupCompany = $groups[$tmp->idGroup]; + if (empty($users[$tmp->idCreator]['idCompany']) === false) { + $new->groupCompany .= ' / '.$companies[$users[$tmp->idCreator]['idCompany']]; + } + + $new->statusResolution = $status[$tmp->status].'/'.$resolutions[$tmp->resolution]; + $new->priority = $this->priorityDiv($tmp->priority, $priorities[$tmp->priority]); + $new->updateDate = $tmp->updateDate; + $new->startDate = $tmp->startDate; + $new->idCreator = $users[$tmp->idCreator]['fullName']; + $new->owner = $users[$tmp->owner]['fullName']; + + $new->operation = ''; + + $carry[] = $new; + return $carry; + } + ); + } + + echo json_encode( + [ + 'data' => $data, + 'recordsTotal' => $result['paginationData']['totalRegisters'], + 'recordsFiltered' => $result['paginationData']['totalRegisters'], + ] + ); + // Capture output. + $response = ob_get_clean(); + } catch (Throwable $e) { + echo json_encode(['error' => $e->getMessage()]); + exit; + } + + // If not valid, show error with issue. + json_decode($response); + if (json_last_error() === JSON_ERROR_NONE) { + // If valid dump. + echo $response; + } else { + echo json_encode( + ['error' => $response] + ); + } + + exit; + } + + + /** + * Get list tickets and prepare data for datatable. + * + * @return void + */ + public function getUserSelect() + { + global $config; + + try { + $ITSM = new ITSM(); + $result = $ITSM->callApi( + 'listUsers', + [ + 'page' => 0, + 'sizePage' => 0, + ], + ['freeSearch' => \get_parameter('search_term', '')] + ); + + $response = array_reduce( + $result['data'], + function ($carry, $user) { + $carry[$user['idUser']] = $user['fullName']; + return $carry; + } + ); + } catch (Throwable $e) { + echo json_encode(['error' => $e->getMessage()]); + exit; + } + + echo json_encode($response); + exit; + } + + + /** + * Get Input fields of type incidence. + * + * @return void + */ + public function getInputFieldsIncidenceType() + { + $idIncidenceType = (int) get_parameter('idIncidenceType', true); + $fieldsData = json_decode(base64_decode(get_parameter('fieldsData')), true); + if (empty($fieldsData) === false) { + $fieldsData = array_reduce( + $fieldsData, + function ($carry, $user) { + $carry[$user['idIncidenceField']] = $user['data']; + return $carry; + } + ); + } else { + $fieldsData = []; + } + + $error = ''; + try { + $ITSM = new ITSM(); + $result = $this->getFieldsIncidenceType($ITSM, $idIncidenceType); + $customFields = $result['data']; + } catch (Throwable $e) { + $error = $e->getMessage(); + } + + View::render( + 'ITSM/ITSMCustomFields', + [ + 'ajaxController' => $this->ajaxController, + 'urlAjax' => \ui_get_full_url('ajax.php'), + 'customFields' => $customFields, + 'fieldsData' => $fieldsData, + 'error' => $error, + ] + ); + exit; + } + + + /** + * Get Download. + * + * @return void + */ + public function getDownloadIncidenceAttachment() + { + $idIncidence = (int) get_parameter('idIncidence', true); + $idAttachment = (int) get_parameter('idAttachment', true); + + try { + $ITSM = new ITSM(); + $result = $this->downloadIncidenceAttachment($ITSM, $idIncidence, $idAttachment); + } catch (Throwable $e) { + echo $e->getMessage(); + exit; + } + + echo $result; + exit; + } + + + /** + * Ping API, check connection. + * + * @return void + */ + public function checkConnectionApi() + { + $pass = (string) get_parameter('pass', ''); + $host = (string) get_parameter('host', ''); + try { + $ITSM = new ITSM($host, $pass); + $result = $ITSM->ping(); + } catch (Throwable $e) { + echo $e->getMessage(); + $result = false; + exit; + } + + echo json_encode(['valid' => ($result !== false) ? 1 : 0]); + exit; + } + + + /** + * Ping API, check connection pandora ITSM to pandora. + * + * @return void + */ + public function checkConnectionApiITSMToPandora() + { + $path = (string) get_parameter('path', ''); + try { + $ITSM = new ITSM(); + $result = $ITSM->pingItsmtoPandora($path); + } catch (Throwable $e) { + echo $e->getMessage(); + hd($e->getMessage(), true); + $result = false; + exit; + } + + echo json_encode(['valid' => ($result !== false) ? 1 : 0]); + exit; + } + + +} diff --git a/pandora_console/include/styles/menu.css b/pandora_console/include/styles/menu.css index ff618b500c..f32241eb1a 100644 --- a/pandora_console/include/styles/menu.css +++ b/pandora_console/include/styles/menu.css @@ -264,6 +264,12 @@ background-size: 18px; } +/* ITSM */ +.icon_oper-itsm { + background: url(../../images/menu/itsm.svg) no-repeat 50% 50%; + background-size: 18px; +} + /* trap console */ .icon_oper-snmpc, .icon_god-snmpc { diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 8d6fa524d4..45cacafb6b 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -6215,19 +6215,18 @@ div#status_pie { padding: 15px; } -/* .agent_details_content { display: flex; align-items: flex-start; padding: 20px; padding-bottom: 0; } -*/ -.agent_details_content { + +.agent_details_content_cluster { display: flex; + flex-direction: row; + justify-content: space-between; align-items: flex-start; - padding: 20px; - padding-bottom: 0; } .agent_details_content .agent_details_graph { @@ -6240,10 +6239,69 @@ div#status_pie { justify-content: center; } -.agent_details_content .agent_details_info { - flex: 1 1 70%; - overflow: hidden; - padding-left: 15px; +.agent_details_content_cluster .agent_details_graph { + display: flex; + flex-direction: column; + margin-left: 10px; + min-width: 35%; + max-width: 50%; +} + +.agent_details_content_cluster .agent_details_graph > div { + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + width: 100%; + margin-bottom: 5px; +} + +.agent_details_content_cluster div#status_pie { + margin: 0px; +} + +.agent_details_content_cluster .agent_details_info { + display: flex; + flex-direction: column; + margin-right: 10px; + min-width: 35%; + max-width: 50%; + justify-content: space-between; + align-items: center; + height: 180px; +} + +.agent_details_content_cluster .agent_details_info > div { + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: flex-end; + width: 100%; + margin-bottom: 5px; +} + +.agent_details_content_cluster .agent_details_info { + display: flex; + flex-direction: column; + margin-left: 10px; + min-width: 35%; + max-width: 50%; + justify-content: space-around; + align-items: flex-end; + margin-right: 20px; +} + +.agent_event_chart_cluster { + margin-left: 10px; + margin-bottom: 10px; +} + +.agent_event_chart_cluster div b { + margin-left: 0px; +} + +.agent_event_chart_cluster .white-table-graph-content { + height: auto; } .agent_details_info { @@ -6280,6 +6338,17 @@ div#status_pie { justify-content: flex-start; } +.agent_details_bullets_cluster #bullets_modules { + display: flex; + justify-content: flex-start; + flex-direction: column; +} + +.agent_details_bullets_cluster #bullets_modules > div { + padding: 0px; + margin-bottom: 10px; +} + .agent_details_bullets #bullets_modules > div { display: flex; align-items: center; @@ -8543,7 +8612,7 @@ div.graph div.legend table { padding: 5px; } -.integria_title .ehorus_title { +.ITSM_title .ehorus_title { color: #515151; } @@ -12566,3 +12635,25 @@ tr[id^="network_component-plugin-snmp-fields-dynamicMacroRow-"] input { .ui-date-range-in > a { background-color: #81b92e3b !important; } + +.ui-datepicker-title > span { + color: #82b92e !important; +} + +.div-report_export_filter { + left: 0em; + top: 0em; + position: relative; +} + +.button-export_filter { + position: relative; + left: 17em; + top: -38px; + width: 30%; +} + +.filter_label_position_after { + position: relative; + top: -92px; +} diff --git a/pandora_console/include/styles/pandora_black.css b/pandora_console/include/styles/pandora_black.css index 725a1c67d0..bc861bd8f9 100644 --- a/pandora_console/include/styles/pandora_black.css +++ b/pandora_console/include/styles/pandora_black.css @@ -1013,7 +1013,7 @@ div#dashboard-controls { color: #fff; } -.integria_details_shadow { +.ITSM_details_shadow { background-color: #222; border-bottom: 1px solid #e2e2e2; border-left: 1px solid #e2e2e2; @@ -1022,7 +1022,7 @@ div#dashboard-controls { border-top-right-radius: 5px; } -div.integria_details_description textarea { +div.ITSM_details_description textarea { width: 100%; background-color: #111; color: #fff; diff --git a/pandora_console/include/styles/integriaims.css b/pandora_console/include/styles/pandoraitsm.css similarity index 53% rename from pandora_console/include/styles/integriaims.css rename to pandora_console/include/styles/pandoraitsm.css index bca6df5038..8c7c95c35d 100644 --- a/pandora_console/include/styles/integriaims.css +++ b/pandora_console/include/styles/pandoraitsm.css @@ -1,31 +1,30 @@ -/* --- Integria IMS --- */ div.priority { width: 80px; color: #fff; text-align: center; border-radius: 5px; - padding: 5px; + padding: 0px; display: table-cell; vertical-align: middle; } /* Details view */ -div.integria_details { +div.ITSM_details { display: grid; grid-column-gap: 10px; grid-template-columns: repeat(3, minmax(min-content, auto)); grid-auto-rows: 1fr; } -div.integria_details div.box-shadow.white_table_graph { +div.ITSM_details div.box-shadow.white_table_graph { box-shadow: none; } -div.integria_details div.priority { +div.ITSM_details div.priority { display: inline-block; } -div.integriaims_details_row { +div.pandoraitsm_details_row { display: grid; grid-gap: 10px; text-align: center; @@ -33,30 +32,25 @@ div.integriaims_details_row { margin-bottom: 8px; } -div.integriaims_details_titles { +div.pandoraitsm_details_titles { font-weight: bold; } -div.integria_details_row_five { +div.ITSM_details_row_five { grid-template-columns: repeat(5, 1fr); } -div.integria_details_row_three { +div.ITSM_details_row_three { grid-template-columns: repeat(3, 1fr); } -div.integria_details_description { +div.ITSM_details_description { width: 100%; + overflow: auto; + padding: 0px 10px; } -div.integria_details_description textarea { - width: 100%; - background-color: #fbfbfb; - resize: vertical; - color: #000; -} - -.integriaims_details_box { +.pandoraitsm_details_box { display: grid; grid-column-gap: 10px; grid-row-gap: 5px; @@ -65,18 +59,18 @@ div.integria_details_description textarea { text-align: center; } -.integriaims_details_box_five { +.pandoraitsm_details_box_five { grid-template-rows: repeat(3, 1fr); grid-template-columns: repeat(5, 1fr); } -.integriaims_details_box_three { +.pandoraitsm_details_box_three { grid-template-rows: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr); } /* ui_toggles */ -.integria_details_shadow { +.ITSM_details_shadow { background-color: #fff; border-bottom: 1px solid #e2e2e2; border-left: 1px solid #e2e2e2; @@ -85,35 +79,17 @@ div.integria_details_description textarea { border-top-right-radius: 5px; } -.integria_details_shadow .white_table_graph_header { +.ITSM_details_shadow .white_table_graph_header { border-left: none; border-right: none; } -.integria_details_content { +.ITSM_details_content { border-bottom: none; border-left: none; border-right: none; } -/* Inputs type text shown as a black line */ -.integria_incidents_options input[type="text"] { - background-color: transparent; - border: none; - border-radius: 0; - border-bottom: 1px solid #ccc; - font-size: 10pt; - padding: 2px 5px; - box-sizing: border-box; - background-repeat: no-repeat; - background-position: left bottom 2px; - margin-bottom: 4px; -} - -.integria_incident_options input[readonly] { - color: #848484; -} - .comment_title { padding: 5px 10px 5px 20px; background-color: rgba(130, 185, 46, 0.16); @@ -123,3 +99,46 @@ div.integria_details_description textarea { .comment_body { padding: 15px 20px 15px 20px; } + +/*---*/ +div.incidence-type-custom-fields { + display: flex; + flex-direction: row; + justify-content: center; + align-items: baseline; + flex-wrap: wrap; +} + +.incidence-type-custom-fields > div { + flex: 1 1 45%; + display: flex; + margin: 0px 20px; + flex-direction: column; +} + +.incidence-type-custom-fields > div.incidence-type-custom-fields-textarea { + flex: 1 1 100%; +} + +.label_select, +.label_select_simple { + display: flex; + flex-direction: column; + margin: 0; +} + +div.container-statistics { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + +div.container-statistics > div { + flex: 1 1 45%; + max-width: 46%; + margin: 1%; +} + +table.table-widget-itsm tr > td { + text-align: left; +} diff --git a/pandora_console/install.php b/pandora_console/install.php index c4b30d898a..e181906a0b 100644 --- a/pandora_console/install.php +++ b/pandora_console/install.php @@ -131,7 +131,7 @@
'[ITSM]'.$e->getMessage() ]); + } else { + echo '[ITSM]'.$e->getMessage(); + } + + // Stop this execution, but continue 'globally'. + return; +} + +// AJAX controller. +if (is_ajax() === true) { + $method = get_parameter('method'); + + if (method_exists($cs, $method) === true) { + if ($cs->ajaxMethod($method) === true) { + $cs->{$method}(); + } else { + $cs->error('Unavailable method.'); + } + } else { + $cs->error('Method not found. ['.$method.']'); + } +} else { + // Run. + $cs->run(); +} diff --git a/pandora_console/operation/agentes/alerts_status.php b/pandora_console/operation/agentes/alerts_status.php index 176ac6bce8..a7ce53646c 100755 --- a/pandora_console/operation/agentes/alerts_status.php +++ b/pandora_console/operation/agentes/alerts_status.php @@ -109,6 +109,7 @@ $sec = safe_url_extraclean($sec); $flag_alert = (bool) get_parameter('force_execution', 0); $alert_validate = (bool) get_parameter('alert_validate', 0); $tab = get_parameter_get('tab', null); +$op = get_parameter('op', null); $refr = (int) get_parameter('refr', 0); $pure = get_parameter('pure', 0); @@ -119,8 +120,11 @@ if ($flag_alert == 1 && check_acl($config['id_user'], $id_group, 'AW')) { forceExecution($id_group); } - -$idAgent = get_parameter_get('id_agente', 0); +if (isset($id_agente) === false || empty($id_agente) === true) { + $idAgent = get_parameter_get('id_agente', 0); +} else { + $idAgent = $id_agente; +} // Show alerts for specific agent. if ($idAgent != 0) { @@ -207,6 +211,10 @@ if ($idAgent != 0) { $alerts = []; +if ($op != null) { + $url = $url.'&op='.$op; +} + if ($tab != null) { $url = $url.'&tab='.$tab; } diff --git a/pandora_console/operation/agentes/estado_agente.php b/pandora_console/operation/agentes/estado_agente.php index 44d64fddaf..75b1c6222a 100644 --- a/pandora_console/operation/agentes/estado_agente.php +++ b/pandora_console/operation/agentes/estado_agente.php @@ -1153,11 +1153,8 @@ foreach ($agents as $agent) { $cluster = PandoraFMS\Cluster::loadFromAgentId( $agent['id_agente'] ); - $url = 'index.php?sec=reporting&sec2='; - $url .= 'operation/cluster/cluster'; - $url = ui_get_full_url( - $url.'&op=view&id='.$cluster->id() - ); + $url_cluster = 'index.php?sec=reporting&sec2=operation/cluster/cluster'; + $url = $url_cluster.'&op=view&id='.$cluster->id(); } else { $url = 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$agent['id_agente']; } diff --git a/pandora_console/operation/agentes/estado_generalagente.php b/pandora_console/operation/agentes/estado_generalagente.php index 641f58c714..62963f6b29 100755 --- a/pandora_console/operation/agentes/estado_generalagente.php +++ b/pandora_console/operation/agentes/estado_generalagente.php @@ -26,15 +26,15 @@ * ============================================================================ */ +use PandoraFMS\ITSM\ITSM; + // Begin. global $config; require_once 'include/functions_agents.php'; - require_once $config['homedir'].'/include/functions_graph.php'; require_once $config['homedir'].'/include/functions_groups.php'; require_once $config['homedir'].'/include/functions_ui.php'; -require_once $config['homedir'].'/include/functions_incidents.php'; require_once $config['homedir'].'/include/functions_reporting_html.php'; require_once $config['homedir'].'/include/functions_clippy.php'; @@ -79,215 +79,11 @@ $alive_animation = agents_get_starmap($id_agente, 200, 50); /* * START: TABLE AGENT BUILD. */ -$agentCaptionAddedMessage = []; -$agentCaption = ''.ucfirst(agents_get_alias($agent['id_agente'])).''; -$in_planned_downtime = (bool) db_get_sql( - 'SELECT executed FROM tplanned_downtime - INNER JOIN tplanned_downtime_agents - ON tplanned_downtime.id = tplanned_downtime_agents.id_downtime - WHERE tplanned_downtime_agents.id_agent = '.$agent['id_agente'].' AND tplanned_downtime.executed = 1' -); -if ((bool) $agent['disabled'] === true) { - $agentCaptionAddedMessage[] = __('Disabled'); -} else if ((bool) $agent['quiet'] === true) { - $agentCaptionAddedMessage[] = __('Quiet'); -} - -if ($in_planned_downtime === true) { - $agentCaptionAddedMessage[] = __('In scheduled downtime'); -} - -if (empty($agentCaptionAddedMessage) === false) { - $agentCaption .= ' ('.implode(' - ', $agentCaptionAddedMessage).')'; -} - -$agentIconGroup = ((bool) $config['show_group_name'] === false) ? ui_print_group_icon( - $agent['id_grupo'], - true, - '', - 'padding-right: 6px;', - true, - false, - false, - '', - true -) : ''; - -$agentIconStatus = agents_detail_view_status_img( - $agent['critical_count'], - $agent['warning_count'], - $agent['unknown_count'], - $agent['total_count'], - $agent['notinit_count'] -); - -$agent_details_agent_caption = html_print_div( - [ - 'class' => 'agent_details_agent_caption', - 'content' => $agentCaption, - ], - true -); - -$agent_details_agent_data = html_print_div( - [ - 'class' => 'agent_details_agent_data', - 'content' => $agentIconGroup, - ], - true -); - -$agent_details_agent_status_image = html_print_div( - [ - 'class' => 'icono_right', - 'content' => $agentIconStatus, - ], - true -); - -$agentStatusHeader = html_print_div( - [ - 'class' => 'agent_details_header', - 'content' => $agent_details_agent_caption.$agent_details_agent_data.$agent_details_agent_status_image, - ], - true -); +$agentStatusHeader = get_resume_agent_status_header($agent); // Fixed width non interactive charts. -$status_chart_width = 150; -$graph_width = 150; - -$table_status = new stdClass(); -$table_status->id = 'agent_status_main'; -$table_status->width = '100%'; -$table_status->cellspacing = 0; -$table_status->cellpadding = 0; -$table_status->class = 'floating_form'; -$table_status->style[0] = 'height: 32px; width: 30%; padding-right: 5px; text-align: end; vertical-align: top'; -$table_status->style[1] = 'height: 32px; width: 70%; padding-left: 5px; font-weight: lighter; vertical-align: top'; - -$agentStatusGraph = html_print_div( - [ - 'id' => 'status_pie', - 'style' => 'width: '.$graph_width.'px;', - 'content' => graph_agent_status( - $id_agente, - $graph_width, - $graph_width, - true, - false, - false, - true - ), - ], - true -); - -/* - $table_agent_graph = '
'; - $table_agent_graph .= graph_agent_status( - $id_agente, - $graph_width, - $graph_width, - true, - false, - false, - true - ); -$table_agent_graph .= '
';*/ - -/* - $table_agent_os = '

'.ui_print_os_icon( - $agent['id_os'], - false, - true, - true, - false, - false, - false, - [ - 'title' => get_os_name($agent['id_os']), - 'width' => '20px;', - ] - ); -*/ - -$table_status->data['agent_os'][0] = __('OS'); -$agentOS = []; -$agentOS[] = html_print_div([ 'content' => (empty($agent['os_version']) === true) ? get_os_name((int) $agent['id_os']) : $agent['os_version']], true); -$agentOS[] = html_print_div([ 'style' => 'width: 16px;padding-left: 5px', 'content' => ui_print_os_icon($agent['id_os'], false, true, true, false, false, false, ['width' => '16px'])], true); -$table_status->data['agent_os'][1] = html_print_div(['class' => 'agent_details_agent_data', 'content' => implode('', $agentOS)], true); - -// $table_agent_os .= (empty($agent['os_version']) === true) ? get_os_name((int) $agent['id_os']) : $agent['os_version'].'

'; -$addresses = agents_get_addresses($id_agente); -$address = agents_get_address($id_agente); - -foreach ($addresses as $k => $add) { - if ($add == $address) { - unset($addresses[$k]); - } -} - -if (empty($address) === false) { - $table_status->data['ip_address'][0] = __('IP address'); - $table_status->data['ip_address'][1] = (empty($address) === true) ? ''.__('N/A').'' : $address; - /* - $table_agent_ip = '

'.html_print_image( - 'images/world.png', - true, - [ - 'title' => __('IP address'), - 'class' => 'invert_filter', - ] - ); - $table_agent_ip .= ''; - $table_agent_ip .= (empty($address) === true) ? ''.__('N/A').'' : $address; - $table_agent_ip .= '

'; - */ -} - -$table_status->data['agent_version'][0] = __('Agent Version'); -$table_status->data['agent_version'][1] = (empty($agent['agent_version']) === true) ? ''.__('N/A').'' : $agent['agent_version']; - -$table_status->data['description'][0] = __('Description'); -$table_status->data['description'][1] = (empty($agent['comentarios']) === true) ? ''.__('N/A').'' : $agent['comentarios']; - -/* - $table_agent_version = '

'.html_print_image( - 'images/version.png', - true, - [ - 'title' => __('Agent Version'), - 'class' => 'invert_filter', - ] - ); - $table_agent_version .= ''; - $table_agent_version .= (empty($agent['agent_version']) === true) ? ''.__('N/A').'' : $agent['agent_version']; - $table_agent_version .= '

'; - - $table_agent_description = '

'.html_print_image( - 'images/list.png', - true, - [ - 'title' => __('Description'), - 'class' => 'invert_filter', - ] - ); - $table_agent_description .= ''; - $table_agent_description .= (empty($agent['comentarios']) === true) ? ''.__('N/A').'' : $agent['comentarios']; - $table_agent_description .= '

'; -*/ - -/* - $table_agent_count_modules = reporting_tiny_stats( - $agent, - true, - 'agent', - // Useless. - ':', - true -);*/ +$agentStatusGraph = get_status_agent_chart_pie($id_agente, 150); $agentCountModules = html_print_div( [ @@ -304,6 +100,40 @@ $agentCountModules = html_print_div( true ); +$table_status = new stdClass(); +$table_status->id = 'agent_status_main'; +$table_status->width = '100%'; +$table_status->cellspacing = 0; +$table_status->cellpadding = 0; +$table_status->class = 'floating_form'; +$table_status->style[0] = 'height: 32px; width: 30%; padding-right: 5px; text-align: end; vertical-align: top'; +$table_status->style[1] = 'height: 32px; width: 70%; padding-left: 5px; font-weight: lighter; vertical-align: top'; +$table_status->data['agent_os'][0] = __('OS'); +$agentOS = []; +$agentOS[] = html_print_div([ 'content' => (empty($agent['os_version']) === true) ? get_os_name((int) $agent['id_os']) : $agent['os_version']], true); +$agentOS[] = html_print_div([ 'style' => 'width: 16px;padding-left: 5px', 'content' => ui_print_os_icon($agent['id_os'], false, true, true, false, false, false, ['width' => '16px'])], true); +$table_status->data['agent_os'][1] = html_print_div(['class' => 'agent_details_agent_data', 'content' => implode('', $agentOS)], true); + +$addresses = agents_get_addresses($id_agente); +$address = agents_get_address($id_agente); + +foreach ($addresses as $k => $add) { + if ($add == $address) { + unset($addresses[$k]); + } +} + +if (empty($address) === false) { + $table_status->data['ip_address'][0] = __('IP address'); + $table_status->data['ip_address'][1] = (empty($address) === true) ? ''.__('N/A').'' : $address; +} + +$table_status->data['agent_version'][0] = __('Agent Version'); +$table_status->data['agent_version'][1] = (empty($agent['agent_version']) === true) ? ''.__('N/A').'' : $agent['agent_version']; + +$table_status->data['description'][0] = __('Description'); +$table_status->data['description'][1] = (empty($agent['comentarios']) === true) ? ''.__('N/A').'' : $agent['comentarios']; + $has_remote_conf = enterprise_hook( 'config_agents_has_remote_configuration', [$agent['id_agente']] @@ -347,163 +177,6 @@ $table_agent = $agentStatusHeader.' * END: TABLE AGENT BUILD. */ -/* - *START: TABLE CONTACT BUILD. - */ - -$table_contact = new stdClass(); -$table_contact->id = 'agent_contact_main'; -$table_contact->width = '100%'; -$table_contact->cellspacing = 0; -$table_contact->cellpadding = 0; -$table_contact->class = 'floating_form'; -$table_contact->style[0] = 'height: 32px; width: 30%; padding-right: 5px; text-align: end; vertical-align: top'; -$table_contact->style[1] = 'height: 32px; width: 70%; padding-left: 5px; font-weight: lighter; vertical-align: top'; - -$agentContactCaption = html_print_div( - [ - 'class' => 'agent_details_agent_caption', - 'content' => ''.__('Agent contact').'', - ], - true -); - -$buttonsRefreshAgent = html_print_button( - __('Refresh data'), - 'refresh_data', - false, - 'window.location.assign("index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$id_agente.'&refr=60")', - [ 'mode' => 'link' ], - true -); - -if (check_acl_one_of_groups($config['id_user'], $all_groups, 'AW') === true) { - $buttonsRefreshAgent .= html_print_button( - __('Force checks'), - 'force_checks', - false, - 'window.location.assign("index.php?sec=estado&sec2=operation/agentes/ver_agente&flag_agent=1&id_agente='.$id_agente.'")', - [ 'mode' => 'link' ], - true - ); -} - -$buttons_refresh_agent_view = html_print_div( - [ - 'class' => 'buttons_agent_view', - 'content' => $buttonsRefreshAgent, - ], - true -); - -// Data for agent contact. -$intervalHumanTime = human_time_description_raw($agent['intervalo']); -$lastContactDate = ui_print_timestamp($agent['ultimo_contacto'], true); -$remoteContactDate = ($agent['ultimo_contacto_remoto'] === '01-01-1970 00:00:00') ? __('Never') : date_w_fixed_tz($agent['ultimo_contacto_remoto']); -$lastAndRemoteContact = sprintf('%s / %s', $lastContactDate, $remoteContactDate); -$progress = agents_get_next_contact($id_agente); -$tempTimeToShow = ($agent['intervalo'] - (strtotime('now') - strtotime($agent['ultimo_contacto']))); -$progressCaption = ($tempTimeToShow >= 0) ? sprintf('%d s', $tempTimeToShow) : __('Out of bounds'); -$ajaxNextContactInterval = (empty($agent['intervalo']) === true) ? 0 : (100 / $agent['intervalo']); -$secondary_groups = enterprise_hook('agents_get_secondary_groups', [$id_agente]); -$secondaryLinks = []; -if (empty($secondary_groups['for_select']) === true) { - $secondaryLinks[] = ''.__('N/A').''; -} else { - foreach ($secondary_groups['for_select'] as $id => $name) { - $secondaryLinks[] = html_print_anchor( - [ - 'href' => 'index.php?sec=estado&sec2=operation/agentes/estado_agente&refr=60&group_id='.$id, - 'content' => $name, - ], - true - ); - } -} - -$last_status_change_agent = agents_get_last_status_change($agent['id_agente']); -$time_elapsed = (empty($last_status_change_agent) === false) ? human_time_comparation($last_status_change_agent) : ''.__('N/A').''; - -// Agent Interval. -$data = []; -$data[0] = __('Interval'); -$data[1] = $intervalHumanTime; -$table_contact->data[] = $data; - -// Last & Remote contact. -$data = []; -$data[0] = __('Last contact').' / '.__('Remote'); -$data[1] = $lastAndRemoteContact; -$table_contact->data[] = $data; - -// Next contact progress. -$data = []; -$data[0] = __('Next contact'); -$data[1] = ui_progress( - $progress, - '80%', - '1.2', - '#ececec', - true, - $progressCaption, - [ - 'page' => 'operation/agentes/ver_agente', - 'interval' => $ajaxNextContactInterval, - 'data' => [ - 'id_agente' => $id_agente, - 'refresh_contact' => 1, - ], - - ] -); -$table_contact->data[] = $data; - -// Group line. -$data = []; -$data[0] = ''.__('Group').''; -$data[1] = html_print_anchor( - [ - 'href' => 'index.php?sec=gagente&sec2=godmode/groups/tactical&id_group='.$agent['id_grupo'], - 'content' => groups_get_name($agent['id_grupo']), - ], - true -); -$table_contact->data[] = $data; - -// Secondary groups. -$data = []; -$data[0] = ''.__('Secondary groups').''; -$data[1] = implode(', ', $secondaryLinks); -$table_contact->data[] = $data; - -// Parent agent line. -if (enterprise_installed() === true) { - $data = []; - $data[0] = ''.__('Parent').''; - if ((int) $agent['id_parent'] === 0) { - $data[1] = ''.__('N/A').''; - } else { - $data[1] = html_print_anchor( - [ - 'href' => 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$agent['id_parent'], - 'content' => agents_get_alias($agent['id_parent']), - ], - true - ); - } - - $table_contact->data[] = $data; -} - -// Last status change line. -$data = []; -$data[0] = ''.__('Last status change').''; -$data[1] = $time_elapsed; -$table_contact->data[] = $data; - -/* - * END: TABLE CONTACT BUILD - */ /* * START: TABLE DATA BUILD @@ -688,44 +361,6 @@ if ((bool) $config['agentaccess'] === true && $access_agent > 0) { * END: ACCESS RATE GRAPH */ -/* - * START: TABLE INCIDENTS - */ - -$last_incident = db_get_row_sql( - sprintf( - 'SELECT * FROM tincidencia - WHERE estado IN (0,1) - AND id_agent = %d - ORDER BY actualizacion DESC', - $id_agente - ) -); - -if ($last_incident != false) { - $table_incident = new stdClass(); - $table_incident->id = 'agent_incident_main'; - $table_incident->width = '100%'; - $table_incident->cellspacing = 0; - $table_incident->cellpadding = 0; - $table_incident->class = 'info_table tactical_table'; - - $table_incident->head[0] = ''.__('Author').''; - $table_incident->head[1] = ''.__('Title').''; - $table_incident->head[2] = ''.__('Timestamp').''; - $table_incident->head[3] = ''.__('Priority').''; - - $data = []; - $data[0] = $last_incident['id_creator']; - $data[1] = ''.$last_incident['titulo'].''; - $data[2] = $last_incident['inicio']; - $data[3] = incidents_print_priority_img($last_incident['prioridad'], true); - $table_incident->data[] = $data; -} - -/* - * END: TABLE INCIDENTS - */ /* * START: TABLE INTERFACES @@ -881,15 +516,7 @@ if (empty($network_interfaces) === false) { }); 'agent_details_header', - 'content' => $agentContactCaption.$buttons_refresh_agent_view, - ], - true -); - -$agent_contact .= html_print_table($table_contact, true); +$agent_contact = get_resume_agent_concat($id_agente, $all_groups, $agent); $agentDetails = html_print_div( [ @@ -984,6 +611,46 @@ if (empty($agentAdditionalInfo) === false) { ); } +if ((bool) $config['ITSM_enabled'] === true) { + $show_tab_issue = false; + try { + $ITSM = new ITSM(); + $list = $ITSM->listIncidenceAgents($id_agente, false); + if (empty($list) === false) { + $show_tab_issue = true; + } + } catch (\Throwable $th) { + $show_tab_issue = false; + } + + if ($show_tab_issue === true) { + try { + $table_itsm = $ITSM->getTableIncidencesForAgent($id_agente, true, 0); + } catch (Exception $e) { + $table_itsm = $e->getMessage(); + } + + $itsmInfo = ui_toggle( + $table_itsm, + ''.__('Incidences').'', + 'status_monitor_agent', + false, + false, + true, + '', + 'white-box-content', + 'box-flat white_table_graph w100p' + ); + + html_print_div( + [ + 'class' => 'agent_details_line', + 'content' => $itsmInfo, + ] + ); + } +} + if (empty($agentIncidents) === false) { html_print_div( [ @@ -1003,19 +670,6 @@ if (empty($agentIncidents) === false) { ); } - - -/* - // Show both graphs, events and access rate. - if ($table_access_rate) { - echo '
'.$table_access_rate.$table_events.'
'; - } else { - echo '
'.$table_events.'
'; - } - - echo $agent_incidents; -*/ - if (isset($table_interface) === true) { ui_toggle( html_print_table($table_interface, true), diff --git a/pandora_console/operation/agentes/estado_monitores.php b/pandora_console/operation/agentes/estado_monitores.php index 43255d226f..372a636044 100755 --- a/pandora_console/operation/agentes/estado_monitores.php +++ b/pandora_console/operation/agentes/estado_monitores.php @@ -371,6 +371,7 @@ ui_require_css_file('cluetip', 'include/styles/js/'); ui_require_jquery_file('cluetip'); echo "
"; +echo "
"; ui_include_time_picker(); ui_require_jquery_file('ui.datepicker-'.get_user_language(), 'include/javascript/i18n/'); @@ -453,6 +454,34 @@ ui_require_jquery_file('ui.datepicker-'.get_user_language(), 'include/javascript } }); } + + // Show the modal window of an module + function show_cluster_module_detail(cluster_id, module_name) { + title = ; + $.ajax({ + type: "POST", + url: "", + data: "page=include/ajax/module&get_cluster_module_detail=1&cluster_id="+cluster_id+"&module_name="+module_name, + dataType: "html", + success: function(data) { + $("#cluster_module_detail").hide () + .empty () + .append (data) + .dialog ({ + resizable: true, + draggable: true, + modal: true, + title: title + module_name, + overlay: { + opacity: 0.5, + background: "black" + }, + width: "auto" + }).css({"min-width": "650px"}) + .show (); + } + }); + } function datetime_picker_callback() { $("#text-time_from, #text-time_to").timepicker({ diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index 8d033185af..4e0299fa86 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -27,6 +27,7 @@ */ use PandoraFMS\Enterprise\Metaconsole\Node; +use PandoraFMS\ITSM\ITSM; global $config; @@ -1655,18 +1656,30 @@ if ((bool) $config['activate_gis'] === true) { } // Incident tab. -$total_incidents = agents_get_count_incidents($id_agente); -if ($total_incidents > 0) { - $incidenttab['text'] = html_print_menu_button( - [ - 'href' => 'index.php?sec=gagente&sec2=operation/agentes/ver_agente&tab=incident&id_agente='.$id_agente, - 'image' => 'images/logs@svg.svg', - 'title' => __('Incidents'), - ], - true - ); +if ((bool) $config['ITSM_enabled'] === true) { + $show_tab_issue = false; + try { + $ITSM = new ITSM(); + $list = $ITSM->listIncidenceAgents($id_agente); + if (empty($list) === false) { + $show_tab_issue = true; + } + } catch (\Throwable $th) { + $show_tab_issue = false; + } - $incidenttab['active'] = ($tab === 'incident'); + if ($show_tab_issue === true) { + $incidenttab['text'] = html_print_menu_button( + [ + 'href' => 'index.php?sec=gagente&sec2=operation/agentes/ver_agente&tab=incident&id_agente='.$id_agente, + 'image' => 'images/logs@svg.svg', + 'title' => __('Incidents'), + ], + true + ); + + $incidenttab['active'] = ($tab === 'incident'); + } } // Url address tab. @@ -1743,7 +1756,7 @@ if ((bool) $config['ehorus_enabled'] === true && empty($config['ehorus_custom_fi if (empty($ehorus_agent_id) === false) { $tab_url = 'index.php?sec=estado&sec2=operation/agentes/ver_agente&tab=ehorus&id_agente='.$id_agente; $ehorus_tab['text'] = ''.html_print_image( - 'images/ehorus/ehorus.png', + 'images/RC.png', true, [ 'title' => __('eHorus'), diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index 4aba7b15dc..6b73db3b6e 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -512,8 +512,10 @@ if (is_ajax() === true) { ); } - $tmp->evento = str_replace('"', '', io_safe_output($tmp->evento)); - $event_text = $tmp->evento; + $output_event_name = str_replace('"', '', io_safe_output($tmp->evento)); + $tmp->event_title = $output_event_name; + $tmp->b64 = base64_encode(json_encode($tmp)); + $tmp->evento = $output_event_name; $tmp->evento = ui_print_truncate_text( $tmp->evento, @@ -630,7 +632,7 @@ if (is_ajax() === true) { $total_sec = strtotime($tmp->timestamp); $total_sec += $dif; - $last_contact = date($confb64ig['date_format'], $total_sec); + $last_contact = date($config['date_format'], $total_sec); $last_contact_value = ui_print_timestamp($last_contact, true, $options); } else { $title = date($config['date_format'], strtotime($tmp->timestamp)); @@ -669,11 +671,6 @@ if (is_ajax() === true) { ); } - $aux_event = $tmp->evento; - $tmp->evento = $event_text; - $tmp->b64 = base64_encode(json_encode($tmp)); - $tmp->evento = $aux_event; - $tmp->user_comment = ui_print_comments( event_get_last_comment( $item, diff --git a/pandora_console/operation/events/sound_events.php b/pandora_console/operation/events/sound_events.php index 1a25c20c64..7c04359f98 100644 --- a/pandora_console/operation/events/sound_events.php +++ b/pandora_console/operation/events/sound_events.php @@ -31,6 +31,7 @@ global $config; require_once '../../include/config.php'; require_once '../../include/functions.php'; require_once '../../include/functions_db.php'; +require_once '../../include/functions_events.php'; require_once '../../include/auth/mysql.php'; require_once $config['homedir'].'/include/class/HTML.class.php'; diff --git a/pandora_console/operation/incidents/configure_integriaims_incident.php b/pandora_console/operation/incidents/configure_integriaims_incident.php deleted file mode 100644 index d8aed83388..0000000000 --- a/pandora_console/operation/incidents/configure_integriaims_incident.php +++ /dev/null @@ -1,454 +0,0 @@ - '', - 'label' => __('Issues'), - ], - [ - 'link' => '', - 'label' => $title_header, - ], - ] -); - -// Check if Integria integration enabled. -if ($config['integria_enabled'] == 0) { - ui_print_error_message(__('In order to access ticket management system, integration with Integria IMS must be enabled and properly configured')); - return; -} - -// Check connection to Integria IMS API. -$has_connection = integria_api_call(null, null, null, null, 'get_login'); - -if ($has_connection === false) { - ui_print_error_message(__('Integria IMS API is not reachable')); - return; -} - -// Styles. -ui_require_css_file('integriaims'); - -// If everything OK, get parameters from Integria IMS API in order to populate combos. -$integria_group_values = []; -$integria_criticity_values = []; -$integria_users_values = []; -$integria_types_values = []; -$integria_status_values = []; - -$integria_groups_csv = integria_api_call(null, null, null, null, 'get_groups'); - -get_array_from_csv_data_pair($integria_groups_csv, $integria_group_values); - -$integria_status_csv = integria_api_call(null, null, null, null, 'get_incidents_status'); - -get_array_from_csv_data_pair($integria_status_csv, $integria_status_values); - -$integria_criticity_levels_csv = integria_api_call(null, null, null, null, 'get_incident_priorities'); - -get_array_from_csv_data_pair($integria_criticity_levels_csv, $integria_criticity_values); - -$integria_users_csv = integria_api_call(null, null, null, null, 'get_users'); - -$csv_array = explode("\n", $integria_users_csv); - -foreach ($csv_array as $csv_line) { - if (!empty($csv_line)) { - $integria_users_values[$csv_line] = $csv_line; - } -} - -$integria_types_csv = integria_api_call(null, null, null, null, 'get_types'); - -get_array_from_csv_data_pair($integria_types_csv, $integria_types_values); - -$integria_resolution_csv = integria_api_call(null, null, null, null, 'get_incidents_resolutions'); - -get_array_from_csv_data_pair($integria_resolution_csv, $integria_resolution_values); - -$event_id = (int) get_parameter('from_event'); -$incident_id_edit = (int) get_parameter('incident_id'); -$create_incident = (bool) get_parameter('create_incident', 0); -$update_incident = (bool) get_parameter('update_incident', 0); -$incident_group_id = (int) get_parameter('group'); -$incident_criticity_id = (int) get_parameter('criticity'); -$incident_owner = get_parameter('owner'); -$incident_type = (int) get_parameter('type'); -$incident_creator = get_parameter('creator'); -$incident_status = (int) get_parameter('status'); -$incident_resolution = (int) get_parameter('resolution'); -$incident_title = events_get_field_value_by_event_id($event_id, get_parameter('incident_title')); -$incident_content = events_get_field_value_by_event_id($event_id, get_parameter('incident_content')); -$file_description = get_parameter('file_description'); - -// Separator conversions. -$incident_title = str_replace(',', ':::', $incident_title); -$incident_content = str_replace(',', ':::', $incident_content); - -// Perform action. -if ($create_incident === true) { - // Disregard incident resolution unless status is 'closed'. - if ($incident_status !== 7) { - $incident_resolution = 0; - } - - // Call Integria IMS API method to create an incident. - $result_api_call = integria_api_call(null, null, null, null, 'create_incident', [$incident_title, $incident_group_id, $incident_criticity_id, $incident_content, '', $incident_type, '', $incident_owner, '0', $incident_status, '', $incident_resolution], false, '', ','); - - if ($userfile !== '' && $result_api_call !== false) { - integriaims_upload_file('userfile', $result_api_call, $file_description); - } - - // Necessary to explicitly set true if not false because function returns result of api call in case of success instead of true value. - $incident_created_ok = ($result_api_call != false) ? true : false; - - ui_print_result_message( - $incident_created_ok, - __('Successfully created in Integria IMS'), - __('Could not be created in Integria IMS') - ); -} else if ($update_incident === true) { - // Disregard incident resolution unless status is 'closed'. - if ($incident_status !== 7) { - $incident_resolution = 0; - } - - // Call Integria IMS API method to update an incident. - $result_api_call = integria_api_call(null, null, null, null, 'update_incident', [$incident_id_edit, $incident_title, $incident_content, '', $incident_group_id, $incident_criticity_id, $incident_resolution, $incident_status, $incident_owner, 0, $incident_type], false, '', ','); - - if ($userfile !== '') { - integriaims_upload_file('userfile', $incident_id_edit, $file_description); - } - - // Necessary to explicitly set true if not false because function returns api call result in case of success instead of true value. - $incident_updated_ok = ($result_api_call != false) ? true : false; - - ui_print_result_message( - $incident_updated_ok, - __('Successfully updated in Integria IMS'), - __('Could not be updated in Integria IMS') - ); -} - -// If incident id is specified, retrieve incident values from api to populate combos with such values. -if ($update) { - // Call Integria IMS API method to get details of an incident given its id. - $result_api_call = integria_api_call(null, null, null, null, 'get_incident_details', [$incident_id_edit], false, '', ','); - - // API call does not return indexes, therefore future modifications of API function in Integria IMS may lead to inconsistencies when accessing resulting array in this file. - $incident_details_separator = explode(',', $result_api_call); - - $incident_details = array_map( - function ($item) { - return str_replace(':::', ',', $item); - }, - $incident_details_separator - ); -} - -// Main table. -$table = new stdClass(); -$table->width = '100%'; -$table->id = 'add_alert_table'; -$table->class = 'databox filter-table-adv'; -$table->head = []; -$table->data = []; -$table->size = []; -$table->size = []; -$table->colspan[0][0] = 2; -$table->colspan[4][0] = 3; -$table->colspan[6][0] = 3; -$help_macros = isset($_GET['from_event']) ? ui_print_help_icon('response_macros', true) : ''; - -if ($update) { - $input_value_title = $incident_details[3]; - $input_value_type = $incident_details[17]; - $input_value_status = $incident_details[6]; - $input_value_group = $incident_details[8]; - $input_value_criticity = $incident_details[7]; - $input_value_owner = $incident_details[5]; - $input_value_content = $incident_details[4]; - $input_value_resolution = $incident_details[12]; -} else if (isset($_GET['from_event'])) { - $input_value_title = $config['cr_incident_title']; - $input_value_type = $config['cr_incident_type']; - $input_value_status = $config['cr_incident_status']; - $input_value_group = $config['cr_default_group']; - $input_value_criticity = $config['cr_default_criticity']; - $input_value_owner = $config['cr_default_owner']; - $input_value_content = $config['cr_incident_content']; - $input_value_resolution = 0; -} else { - $input_value_title = ''; - $input_value_type = ''; - $input_value_status = ''; - $input_value_group = ''; - $input_value_criticity = ''; - $input_value_owner = ''; - $input_value_content = ''; - $input_value_resolution = 0; -} - -$table->data[0][0] = html_print_label_input_block( - __('Title').$help_macros, - html_print_input_text( - 'incident_title', - $input_value_title, - __('Name'), - 50, - 100, - true, - false, - true, - '', - 'w100p' - ) -); - -$integria_logo = 'images/integria_logo_gray.png'; -if ($config['style'] === 'pandora_black' && !is_metaconsole()) { - $integria_logo = 'images/integria_logo.svg'; -} - -$table->data[0][2] = html_print_image($integria_logo, true, ['style' => 'width: 30%; float: right;'], false); - -$table->data[1][0] = html_print_label_input_block( - __('Type'), - html_print_select( - $integria_types_values, - 'type', - $input_value_type, - '', - __('Select'), - 0, - true, - false, - true, - '', - false, - 'width: 100%;' - ) -); - -$table->data[1][1] = html_print_label_input_block( - __('Group'), - html_print_select( - $integria_group_values, - 'group', - $input_value_group, - '', - '', - 0, - true, - false, - true, - '', - false, - 'width: 100%;' - ) -); - -$table->data[1][2] = html_print_label_input_block( - __('Priority'), - html_print_select( - $integria_criticity_values, - 'criticity', - $input_value_criticity, - '', - __('Select'), - 0, - true, - false, - true, - '', - false, - 'width: 100%;' - ) -); - -$table->data[2][0] = html_print_label_input_block( - __('Status'), - html_print_select( - $integria_status_values, - 'status', - $input_value_status, - '', - __('Select'), - 1, - true, - false, - true, - '', - false, - 'width: 100%;' - ) -); - -$table->data[2][1] = html_print_label_input_block( - __('Creator').ui_print_help_tip(__('This field corresponds to the Integria IMS user specified in Integria IMS setup'), true), - html_print_input_text( - 'creator', - $config['integria_user'], - '', - '30', - 100, - true, - true, - false, - '', - 'w100p' - ) -); - -$table->data[2][2] = html_print_label_input_block( - __('Owner'), - html_print_autocomplete_users_from_integria( - 'owner', - $input_value_owner, - true, - '30', - false, - false, - 'w100p' - ), - ['div_class' => 'inline'] -); - -$table->data[3][0] = html_print_label_input_block( - __('Resolution'), - html_print_select( - $integria_resolution_values, - 'resolution', - $input_value_resolution, - '', - '', - 1, - true, - false, - true, - '', - false, - 'width: 100%;' - ) -); - -$table->data[4][0] = html_print_label_input_block( - __('Description').$help_macros, - html_print_textarea( - 'incident_content', - 3, - 20, - $input_value_content, - '', - true - ) -); - -$table->data[5][0] = html_print_label_input_block( - __('File name'), - html_print_input_file('userfile', true) -); - -$table->data[6][0] = html_print_label_input_block( - __('Attachment description'), - html_print_textarea( - 'file_description', - 3, - 20, - '', - '', - true - ) -); - -// Print forms and stuff. -echo '
'; -html_print_table($table); -$buttons = ''; -if (!$update) { - $buttons .= html_print_input_hidden('create_incident', 1, true); - $buttons .= html_print_submit_button( - __('Create'), - 'accion', - false, - [ 'icon' => 'next' ], - true - ); -} else { - $buttons .= html_print_input_hidden('update_incident', 1, true); - $buttons .= html_print_submit_button( - __('Update'), - 'accion', - false, - [ 'icon' => 'upd' ], - true - ); -} - -html_print_action_buttons($buttons); - -echo '
'; -?> - - diff --git a/pandora_console/operation/incidents/dashboard_detail_integriaims_incident.php b/pandora_console/operation/incidents/dashboard_detail_integriaims_incident.php deleted file mode 100644 index 97e3991b02..0000000000 --- a/pandora_console/operation/incidents/dashboard_detail_integriaims_incident.php +++ /dev/null @@ -1,451 +0,0 @@ - '', - 'label' => __('Issues'), - ], - [ - 'link' => '', - 'label' => __('Details'), - ], - ] -); - -// Data. -$status = $array_get_incidents[6]; -$resolution = $array_get_incidents[12]; -$group = $array_get_incidents[8]; -$priority = $array_get_incidents[7]; -$type = $array_get_incidents[17]; -$description = $array_get_incidents[4]; -$creator = $array_get_incidents[10]; -$owner = $array_get_incidents[5]; -$closed_by = $array_get_incidents[23]; -$created_at = $array_get_incidents[1]; -$updated_at = $array_get_incidents[9]; -$closed_at = $array_get_incidents[2]; - -if ($closed_at == '0000-00-00 00:00:00') { - $closed_at = __('Not yet'); -} - -if ($closed_by == '') { - $closed_by = __('Not closed yet'); -} - - -// API calls. -$status_text = integriaims_get_details('status', $status); -$group_text = integriaims_get_details('group', $group); -$priority_text = integriaims_get_details('priority', $priority); -$resolution_text = integriaims_get_details('resolution', $resolution); -$type_text = integriaims_get_details('type', $type); - -// Incident file management. -$upload_file = (bool) get_parameter('upload_file'); -$delete_file_id = get_parameter('delete_file'); -$download_file_id = get_parameter('download_file'); -$download_file_name = get_parameter('download_file_name'); - -// Files section table. -$table_files_section = new stdClass(); -$table_files_section->width = '100%'; -$table_files_section->id = 'files_section_table'; -$table_files_section->class = 'databox filters'; -$table_files_section->head = []; - -$table_files_section->data = []; -$table_files_section->size = []; -$table_files_section->colspan[2][0] = 3; - -// Files list table. -$table_files = new stdClass(); -$table_files->width = '100%'; -$table_files->class = 'info_table'; -$table_files->head = []; - -$table_files->head[0] = __('Filename'); -$table_files->head[1] = __('Timestamp'); -$table_files->head[2] = __('Description'); -$table_files->head[3] = __('User'); -$table_files->head[4] = __('Size'); -$table_files->head[5] = __('Delete'); - -$table_files->data = []; - -$filedescription = get_parameter('file_description', __('No description available')); - -if ($upload_file === true) { - integriaims_upload_file('userfile', $incident_id, $filedescription); -} - -// Delete file. -if (isset($_GET['delete_file'])) { - $result_api_call = integria_api_call(null, null, null, null, 'delete_file', [$delete_file_id]); - - $file_deleted = false; - - if ($result_api_call === '0') { - $file_deleted = true; - } - - ui_print_result_message( - $file_deleted, - __('File successfully deleted'), - __('File could not be deleted') - ); -} - -// Download file. -if (isset($_GET['download_file'])) { - $file_base64 = integria_api_call(null, null, null, null, 'download_file', [$download_file_id]); - ob_end_clean(); - - $decoded = base64_decode($file_base64); - - file_put_contents($download_file_name, $decoded); - ob_end_clean(); - - if (file_exists($download_file_name)) { - header('Content-Description: File Transfer'); - header('Content-Type: application/octet-stream'); - header('Content-Disposition: attachment; filename="'.basename($download_file_name).'"'); - header('Expires: 0'); - header('Cache-Control: must-revalidate'); - header('Pragma: public'); - header('Content-Length: '.filesize($download_file_name)); - ob_end_clean(); - readfile($download_file_name); - unlink($download_file_name); - exit; - } - - header('Location: index.php?sec=incident&sec2=operation/incidents/dashboard_detail_integriaims_incident&incident_id='.$incident_id); -} - -// Retrieve files belonging to incident and create list table. -$result_api_call = integria_api_call(null, null, null, null, 'get_incident_files', [$incident_id]); - -if ($result_api_call != false && strlen($result_api_call) > 0) { - $files = []; - $csv_array = explode("\n", $result_api_call); - - foreach ($csv_array as $csv_line) { - if (!empty($csv_line)) { - $files[] = explode(',', $csv_line); - } - } -} - -$i = 0; - -foreach ($files as $key => $value) { - $table_files->data[$i][0] = '
'.$value[11].''; - $table_files->data[$i][1] = $value[14]; - $table_files->data[$i][2] = $value[12]; - $table_files->data[$i][3] = $value[8]; - $table_files->data[$i][4] = $value[13]; - $table_files->data[$i][5] .= ''; - $table_files->data[$i][5] .= html_print_image('images/delete.svg', true, ['title' => __('Delete'), 'class' => 'invert_filter']); - - - $table_files->data[$i][5] .= ''; - - $i++; -} - -$table_files_section->data[0][0] = '

'.__('File name').':

'; -$table_files_section->data[0][0] .= html_print_input_file('userfile', true); -$table_files_section->data[1][0] = '

'.__('Attachment description').':

'; -$table_files_section->data[1][0] .= html_print_textarea( - 'file_description', - 3, - 20, - '', - '', - true -); - -$table_files_section->data[2][0] .= '
'.html_print_submit_button(__('Upload'), 'accion', false, ['icon' => 'wand', 'mode' => 'mini secondary'], true).'
'; - -$upload_file_form = '
'; - -$upload_file_form .= '
'.'

'.__('Add attachment').'

'.html_print_table($table_files_section, true).html_print_input_hidden('upload_file', true, true); - -$upload_file_form .= '

'.__('Attached files').'

'.html_print_table($table_files, true).'
'; - -// Incident comments management. -$upload_comment = get_parameter('upload_comment'); -$comment_description = get_parameter('comment_description'); - -// Comments section table. -$table_comments_section = new stdClass(); -$table_comments_section->width = '100%'; -$table_comments_section->id = 'files_section_table'; -$table_comments_section->class = 'databox filters'; -$table_comments_section->head = []; - -$table_comments_section->data = []; -$table_comments_section->size = []; - -// Comments list table. -$table_comments = new stdClass(); -$table_comments->width = '100%'; -$table_comments->class = 'info_table'; -$table_comments->head = []; - -$table_comments->head[0] = __('Filename'); -$table_comments->head[1] = __('Timestamp'); -$table_comments->head[2] = __('Description'); -$table_comments->head[3] = __('User'); -$table_comments->head[4] = __('Size'); -$table_comments->head[5] = __('Delete'); - -$table_comments->data = []; - -$comment_disabled = ($array_get_incidents[6] == 7); - -if ($comment_disabled === true) { - $attribute = 'disabled=disabled'; -} - -$table_comments_section->data[0][0] = '

'.__('Description').':

'; -$table_comments_section->data[0][0] .= html_print_textarea( - 'comment_description', - 3, - 20, - '', - $attribute, - true -); - -$table_comments_section->data[1][1] .= '
'.html_print_submit_button(__('Add'), 'accion', $comment_disabled, ['icon' => 'wand', 'mode' => 'mini secondary'], true).'
'; - -// Upload comment. If ticket is closed, this action cannot be performed. -if ($upload_comment && $array_get_incidents[6] != 7) { - $result_api_call = integria_api_call(null, null, null, null, 'create_workunit', [$incident_id, $comment_description, '0.00', 0, 1, '0'], false, '', '|;|'); - - // API method returns id of new comment if success. - $comment_added = ($result_api_call >= '0') ? true : false; - - ui_print_result_message( - $comment_added, - __('Comment successfully added'), - __('Comment could not be added') - ); -} - -// Retrieve comments belonging to incident and create comments table. -$result_api_call = integria_api_call(null, null, null, null, 'get_incident_workunits', [$incident_id]); - -if ($result_api_call != false && strlen($result_api_call) > 0) { - $comments = []; - $csv_array = explode("\n", $result_api_call); - - foreach ($csv_array as $csv_line) { - if (!empty($csv_line)) { - $comments[] = explode(',', $csv_line); - } - } -} - -$comment_table = ''; - -if (!empty($comments)) { - foreach ($comments as $key => $value) { - $comment_table .= '
'.$value[3].' said '.$value[1].''.$value[2].' Hours
'; - $comment_table .= '
'.$value[4].'
'; - } -} else { - $comment_table = __('No comments found'); -} - -$upload_comment_form = '
'; - -$upload_comment_form .= '

'.__('Add comment').'

'.html_print_table($table_comments_section, true).html_print_input_hidden('upload_comment', 1, true).'
'; - - -$upload_comment_form .= '

'.__('Comments').'

'.$comment_table.'
'; - -// Details box. -$details_box = '
'; -$details_box .= ' -
'.__('Status').'
-
'.__('Resolution').'
-
'.__('Group').'
-
'.__('Priority').'
-
'.__('Type').'
'; -$details_box .= ' -
'.html_print_image('images/heart.png', true, ['class' => 'invert_filter']).'
-
'.html_print_image('images/builder@svg.svg', true, ['class' => 'invert_filter']).'
-
'.html_print_image('images/user_green.png', true, ['class' => 'invert_filter']).'
-
'.ui_print_integria_incident_priority($priority, $priority_text).'
-
'.html_print_image('images/incidents.png', true, ['class' => 'invert_filter']).'
'; -$details_box .= ' -
'.$status_text.'
-
'.$resolution_text.'
-
'.$group_text.'
-
'.$priority_text.'
-
'.$type_text.'
'; -$details_box .= '
'; - - -// People box. -$people_box = '
'; -$people_box .= ' -
'.html_print_image('images/header_user_green.png', true, ['width' => '21']).'
-
'.html_print_image('images/header_user_green.png', true, ['width' => '21']).'
-
'.html_print_image('images/header_user_green.png', true, ['width' => '21']).'
'; -$people_box .= ' -
'.__('Created by').':
-
'.__('Owned by').':
-
'.__('Closed by').':
'; -$people_box .= ' -
'.$creator.'
-
'.$owner.'
-
'.$closed_by.'
'; -$people_box .= '
'; - - -// Dates box. -$dates_box = '
'; -$dates_box .= ' -
'.html_print_image('images/tick.png', true, ['class' => 'invert_filter']).'
-
'.html_print_image('images/update.png', true, ['width' => '21', 'class' => 'invert_filter']).'
-
'.html_print_image('images/mul.png', true, ['class' => 'invert_filter']).'
'; -$dates_box .= ' -
'.__('Created at').':
-
'.__('Updated at').':
-
'.__('Closed at').':
'; -$dates_box .= ' -
'.$created_at.'
-
'.$updated_at.'
-
'.$closed_at.'
'; -$dates_box .= '
'; - - -// Show details, people and dates. -echo '
'; - ui_toggle($details_box, __('Details'), '', 'details_box', false, false, '', 'integria_details_content white-box-content', 'integria_details_shadow box-flat white_table_graph'); - ui_toggle($people_box, __('People'), '', 'people_box', false, false, '', 'integria_details_content white-box-content', 'integria_details_shadow box-flat white_table_graph'); - ui_toggle($dates_box, __('Dates'), '', 'dates_box', false, false, '', 'integria_details_content white-box-content', 'integria_details_shadow box-flat white_table_graph'); -echo '
'; - - // Show description. -$description_box = '
'.html_print_textarea( - 'integria_details_description', - 3, - 0, - $description, - 'disabled="disabled"', - true -).'
'; -ui_toggle($description_box, __('Description'), '', '', false); - -echo '
'; -ui_toggle( - $upload_file_form, - __('Attached files'), - '', - '', - true, - false, - 'white-box-content', - 'w98p' -); -echo '
'; - -echo '
'; -ui_toggle( - $upload_comment_form, - __('Comments'), - '', - '', - true, - false, - 'white-box-content', - 'w98p' -); -echo '
'; - -?> - \ No newline at end of file diff --git a/pandora_console/operation/incidents/incident_statistics.php b/pandora_console/operation/incidents/incident_statistics.php deleted file mode 100755 index a2b3e3cf92..0000000000 --- a/pandora_console/operation/incidents/incident_statistics.php +++ /dev/null @@ -1,60 +0,0 @@ - '', - 'label' => __('Issues'), - ], - [ - 'link' => '', - 'label' => __('Statistics'), - ], - ] -); - -if (!$config['integria_enabled']) { - ui_print_error_message(__('In order to access ticket management system, integration with Integria IMS must be enabled and properly configured')); - exit; -} - -echo '
'; -echo ' -

'.__('Incidents by status').'

'; -echo graph_incidents_status(); - -echo '

'.__('Incidents by priority').'

'; -echo grafico_incidente_prioridad(); - -echo '

'.__('Incidents by group').'

'; -echo graphic_incident_group(); - -echo '

'.__('Incidents by user').'

'; -echo graphic_incident_user(); - -echo '
'; -echo '
'; diff --git a/pandora_console/operation/incidents/integriaims_export_csv.php b/pandora_console/operation/incidents/integriaims_export_csv.php deleted file mode 100644 index 08665db8ad..0000000000 --- a/pandora_console/operation/incidents/integriaims_export_csv.php +++ /dev/null @@ -1,124 +0,0 @@ - $value) { - // Status. - if ($tickets_csv_array[$key][6] == 0) { - $tickets_csv_array[$key][6] = 'None'; - } else { - $tickets_csv_array[$key][6] = $status_incident[$tickets_csv_array[$key][6]]; - } - - // Priority. - $tickets_csv_array[$key][7] = $priority_incident[$tickets_csv_array[$key][7]]; - - // Group. - $tickets_csv_array[$key][8] = $group_incident[$tickets_csv_array[$key][8]]; - - // Resolution. - if ($tickets_csv_array[$key][12] == 0) { - $tickets_csv_array[$key][12] = 'None'; - } else { - $tickets_csv_array[$key][12] = $resolution_incident[$tickets_csv_array[$key][12]]; - } - - $tickets_csv_array_filter[$key] = [ - 'id_incidencia' => $tickets_csv_array[$key][0], - 'titulo' => $tickets_csv_array[$key][3], - 'id_grupo' => $tickets_csv_array[$key][8], - 'estado' => $tickets_csv_array[$key][6], - 'resolution' => $tickets_csv_array[$key][12], - 'prioridad' => $tickets_csv_array[$key][7], - 'actualizacion' => $tickets_csv_array[$key][9], - 'inicio' => $tickets_csv_array[$key][1], - 'id_creator' => $tickets_csv_array[$key][10], - 'owner' => $tickets_csv_array[$key][5], - ]; -} - -// Header for CSV file. -$header = [ - __('ID Ticket'), - __('Title'), - __('Group/Company'), - __('Status'), - __('Resolution'), - __('Priority'), - __('Updated'), - __('Started'), - __('Creator'), - __('Owner'), -]; - -$header_csv = ''; -foreach ($header as $key => $value) { - $header_csv .= $value.','; -} - -$header_csv = io_safe_output($header_csv).PHP_EOL; - - -// Join header and content. -$tickets_csv = ''; -foreach ($tickets_csv_array_filter as $key => $value) { - $tickets_csv .= implode(',', $tickets_csv_array_filter[$key]).PHP_EOL; -} - -$tickets_csv = $header_csv.$tickets_csv; - - -// Create csv file. -$filename = 'tickets_export-'.date('Ymd').'-'.date('His').'.csv'; - -ob_clean(); - -// Set cookie for download control. -setDownloadCookieToken(); - -header('Content-Type: text/csv; charset=utf-8'); -header('Content-Disposition: attachment; filename='.$filename); - -// BOM. -echo pack('C*', 0xEF, 0xBB, 0xBF); - -// CSV file. -echo io_safe_output($tickets_csv); diff --git a/pandora_console/operation/incidents/list_integriaims_incidents.php b/pandora_console/operation/incidents/list_integriaims_incidents.php deleted file mode 100644 index cd3e6a2137..0000000000 --- a/pandora_console/operation/incidents/list_integriaims_incidents.php +++ /dev/null @@ -1,678 +0,0 @@ - '', - 'label' => __('Issues'), - ], - [ - 'link' => '', - 'label' => __('Integria IMS Tickets'), - ], - ] -); - -// Check if Integria integration enabled. -if ($config['integria_enabled'] == 0) { - ui_print_error_message(__('In order to access ticket management system, integration with Integria IMS must be enabled and properly configured')); - return; -} - -// Check connection to Integria IMS API. -$has_connection = integria_api_call(null, null, null, null, 'get_login', []); - -if ($has_connection === false) { - ui_print_error_message(__('Integria IMS API is not reachable')); - return; -} - -// Styles. -ui_require_css_file('integriaims'); - -// Get parameters for filters. -$incident_text = (string) get_parameter('incident_text', ''); -$incident_status = (int) get_parameter('incident_status', 0); -$incident_group = (int) get_parameter('incident_group', 1); -$incident_owner = (string) get_parameter('incident_owner', ''); -$incident_creator = (string) get_parameter('incident_creator', ''); -$incident_priority = (int) get_parameter('incident_priority', -1); -$incident_resolution = (string) get_parameter('incident_resolution', ''); -$created_from = (string) get_parameter('created_from', ''); -$created_to = (string) get_parameter('created_to', ''); - -$offset = (int) get_parameter('offset'); - -$delete_incident = get_parameter('delete_incident'); - -// Sorting. -$sort_field = get_parameter('sort_field'); -$sort = get_parameter('sort', 'none'); - -$selected = true; -$select_incident_id_up = false; -$select_incident_id_down = false; -$select_title_up = false; -$select_title_down = false; -$select_group_company_up = false; -$select_group_company_down = false; -$select_status_resolution_up = false; -$select_status_resolution_down = false; -$select_priority_up = false; -$select_priority_down = false; -$select_creator_up = false; -$select_creator_down = false; -$select_owner_up = false; -$select_owner_down = false; - -$order[] = [ - 'field' => 'incident_id', - 'order' => 'ASC', -]; - -switch ($sort_field) { - case 'incident_id': - switch ($sort) { - case 'up': - $select_incident_id_up = $selected; - $order = [ - 'field' => 0, - 'order' => 'ASC', - ]; - break; - - case 'down': - $select_incident_id_down = $selected; - $order = [ - 'field' => 0, - 'order' => 'DESC', - ]; - break; - - default: - // Nothing to do. - break; - } - break; - - case 'title': - switch ($sort) { - case 'up': - $select_title_up = $selected; - $order = [ - 'field' => 3, - 'order' => 'ASC', - ]; - break; - - case 'down': - $select_title_down = $selected; - $order = [ - 'field' => 3, - 'order' => 'DESC', - ]; - break; - - default: - // Nothing to do. - break; - } - break; - - case 'group_company': - switch ($sort) { - case 'up': - $select_group_company_up = $selected; - $order = [ - 'field' => 'group_company', - 'order' => 'ASC', - ]; - break; - - case 'down': - $select_group_company_down = $selected; - $order = [ - 'field' => 'group_company', - 'order' => 'DESC', - ]; - break; - - default: - // Nothing to do. - break; - } - break; - - case 'status_resolution': - switch ($sort) { - case 'up': - $select_status_resolution_up = $selected; - $order = [ - 'field' => 'status_resolution', - 'order' => 'ASC', - ]; - break; - - case 'down': - $select_status_resolution_down = $selected; - $order = [ - 'field' => 'status_resolution', - 'order' => 'DESC', - ]; - break; - - default: - // Nothing to do. - break; - } - break; - - case 'priority': - switch ($sort) { - case 'up': - $select_priority_up = $selected; - $order = [ - 'field' => 7, - 'order' => 'ASC', - ]; - break; - - case 'down': - $select_priority_down = $selected; - $order = [ - 'field' => 7, - 'order' => 'DESC', - ]; - break; - - default: - // Nothing to do. - break; - } - break; - - case 'creator': - switch ($sort) { - case 'up': - $select_creator_up = $selected; - $order = [ - 'field' => 10, - 'order' => 'ASC', - ]; - break; - - case 'down': - $select_creator_down = $selected; - $order = [ - 'field' => 10, - 'order' => 'DESC', - ]; - break; - - default: - // Nothing to do. - break; - } - break; - - case 'owner': - switch ($sort) { - case 'up': - $select_owner_up = $selected; - $order = [ - 'field' => 5, - 'order' => 'ASC', - ]; - break; - - case 'down': - $select_owner_down = $selected; - $order = [ - 'field' => 5, - 'order' => 'DESC', - ]; - break; - - default: - // Nothing to do. - break; - } - break; - - default: - $select_incident_id_up = $selected; - $select_incident_id_down = false; - $select_title_up = false; - $select_title_down = false; - $select_group_company_up = false; - $select_group_company_down = false; - $select_status_resolution_up = false; - $select_status_resolution_down = false; - $select_priority_up = false; - $select_priority_down = false; - $select_creator_up = false; - $select_creator_down = false; - $select_owner_up = false; - $select_owner_down = false; - $order = [ - 'field' => 'id_user', - 'order' => 'ASC', - ]; - break; -} - -if ($delete_incident) { - // Call Integria IMS API method to delete an incident. - $result_api_call_delete = integria_api_call( - null, - null, - null, - null, - 'delete_incident', - [$delete_incident] - ); - - $incident_deleted_ok = ($result_api_call_delete !== false) ? true : false; - - ui_print_result_message( - $incident_deleted_ok, - __('Successfully deleted'), - __('Could not be deleted') - ); -} - -// ---- FILTERS ---- -// API calls to fill the filters. -$status_incident = integriaims_get_details('status'); -$group_incident = integriaims_get_details('group'); -$priority_incident = integriaims_get_details('priority'); -$resolution_incident = integriaims_get_details('resolution'); - - -// TABLE FILTERS. -$table = new StdClass(); -$table->width = '100%'; -$table->size = []; -$table->size[0] = '33%'; -$table->size[1] = '33%'; -$table->size[2] = '33%'; -$table->class = 'filter-table-adv'; - -$table->data = []; -$table->data[0][0] = html_print_label_input_block( - __('Text filter'), - html_print_input_text('incident_text', $incident_text, '', 30, 100, true) -); - -$table->data[0][1] = html_print_label_input_block( - __('Status'), - html_print_select( - $status_incident, - 'incident_status', - $incident_status, - '', - __('All'), - 0, - true - ) -); - -$table->data[0][2] = html_print_label_input_block( - __('Group'), - html_print_select( - $group_incident, - 'incident_group', - $incident_group, - '', - __('All'), - 1, - true - ) -); - -$table->data[1][0] = html_print_label_input_block( - __('Owner'), - html_print_autocomplete_users_from_integria( - 'incident_owner', - $incident_owner, - true, - '30', - false, - false, - 'w100p' - ), - ['div_class' => 'inline'] -); - -$table->data[1][1] = html_print_label_input_block( - __('Creator'), - html_print_autocomplete_users_from_integria( - 'incident_creator', - $incident_creator, - true, - '30', - false, - false, - 'w100p' - ), - ['div_class' => 'inline'] -); - -$table->data[1][2] = html_print_label_input_block( - __('Priority'), - html_print_select( - $priority_incident, - 'incident_priority', - $incident_priority, - '', - __('All'), - -1, - true - ) -); - -$table->data[2][0] = html_print_label_input_block( - __('Resolution'), - html_print_select( - $resolution_incident, - 'incident_resolution', - $incident_resolution, - '', - __('All'), - '', - true - ) -); - -$input_date = '
'; -$input_date .= html_print_input_text_extended( - 'created_from', - $created_from, - 'created_from', - '', - 12, - 50, - false, - '', - 'placeholder="'.__('Created from').'"', - true -); -$input_date .= html_print_input_text_extended( - 'created_to', - $created_to, - 'created_to', - '', - 12, - 50, - false, - '', - 'class="mrgn_lft_5px" placeholder="'.__('Created to').'"', - true -); -$input_date .= '
'; - -$table->data[2][2] = html_print_label_input_block( - __('Date'), - $input_date -); - -// Send filters to get_tickets_integriaims(). -$tickets_filters = [ - 'incident_text' => $incident_text, - 'incident_status' => $incident_status, - 'incident_group' => $incident_group, - 'incident_owner' => $incident_owner, - 'incident_creator' => $incident_creator, - 'incident_priority' => $incident_priority, - 'incident_resolution' => $incident_resolution, - 'created_from' => $created_from, - 'created_to' => $created_to, -]; - -// Data to export to csv file. -$decode_csv = base64_encode(json_encode($tickets_filters)); - -// Full url with all filters. -$url = ui_get_full_url( - 'index.php?sec=incident&sec2=operation/incidents/list_integriaims_incidents&incident_text='.$incident_text.'&incident_status='.$incident_status.'&incident_group='.$incident_group.'&incident_owner='.$incident_owner.'&incident_creator='.$incident_creator.'&incident_priority='.$incident_priority.'&incident_resolution='.$incident_resolution.'&created_from='.$created_from.'&created_to='.$created_to.'&offset='.$offset.'&sort_field='.$sort_field.'&sort='.$sort -); - -// ---- PRINT TABLE FILTERS ---- -$integria_incidents_form = '
'; -$integria_incidents_form .= html_print_table($table, true); -$buttons = html_print_submit_button( - __('Filter'), - 'filter_button', - false, - [ - 'icon' => 'search', - 'mode' => 'mini secondary', - ], - true -); -$buttons .= html_print_button( - __('Export to CSV'), - 'csv_export', - false, - "blockResubmit($(this)); location.href='operation/incidents/integriaims_export_csv.php?tickets_filters=$decode_csv'", - [ - 'icon' => 'cog', - 'mode' => 'mini secondary', - ], - true -); - -$integria_incidents_form .= html_print_div( - [ - 'class' => 'action-buttons', - 'content' => $buttons, - ], - true -); -$integria_incidents_form .= '
'; - -ui_toggle( - $integria_incidents_form, - ''.__('Filters').'', - 'filter_form', - '', - true, - false, - '', - 'white-box-content', - 'box-flat white_table_graph fixed_filter_bar' -); - -/* - * Order api call 'get_incidents'. - * - * resolution = $array_get_incidents[$key][12] - * id_incidencia = $array_get_incidents[$key][0] - * titulo = $array_get_incidents[$key][3] - * id_grupo = $array_get_incidents[$key][8] - * estado = $array_get_incidents[$key][6] - * prioridad = $array_get_incidents[$key][7] - * actualizacion = $array_get_incidents[$key][9] - * id_creator = $array_get_incidents[$key][10] - * - */ - -// ---- LIST OF INCIDENTS ---- -// Get list of incidents. -$array_get_incidents = get_tickets_integriaims($tickets_filters); - -$props = [ - 'order' => $order, - 'group_incident' => $group_incident, - 'status_incident' => $status_incident, - 'resolution_incident' => $resolution_incident, -]; - -usort( - $array_get_incidents, - function ($a, $b) use ($props) { - $order_field = $props['order']['field']; - - $item_a = $a[$order_field]; - $item_b = $b[$order_field]; - - if ($order_field === 'group_company') { - $item_a = $props['group_incident'][$a[8]]; - $item_b = $props['group_incident'][$b[8]]; - } else if ($order_field === 'status_resolution') { - $item_a = $props['status_incident'][$a[6]].' / '.$props['resolution_incident'][$a[12]]; - $item_b = $props['status_incident'][$b[6]].' / '.$props['resolution_incident'][$b[12]]; - } - - if ($props['order']['order'] === 'DESC') { - return $item_a < $item_b; - } else { - return $item_a > $item_b; - } - } -); - -// Prepare pagination. -$incidents_limit = $config['block_size']; -$incidents_paginated = array_slice($array_get_incidents, $offset, $incidents_limit, true); - -// TABLE INCIDENTS. -$table = new stdClass(); -$table->width = '100%'; -$table->class = 'info_table'; -$table->head = []; - -$url_incident_id_up = $url.'&sort_field=incident_id&sort=up'; -$url_incident_id_down = $url.'&sort_field=incident_id&sort=down'; -$url_title_up = $url.'&sort_field=title&sort=up'; -$url_title_down = $url.'&sort_field=title&sort=down'; -$url_group_company_up = $url.'&sort_field=group_company&sort=up'; -$url_group_company_down = $url.'&sort_field=group_company&sort=down'; -$url_status_resolution_up = $url.'&sort_field=status_resolution&sort=up'; -$url_status_resolution_down = $url.'&sort_field=status_resolution&sort=down'; -$url_priority_up = $url.'&sort_field=priority&sort=up'; -$url_priority_down = $url.'&sort_field=priority&sort=down'; -$url_creator_up = $url.'&sort_field=creator&sort=up'; -$url_creator_down = $url.'&sort_field=creator&sort=down'; -$url_owner_up = $url.'&sort_field=owner&sort=up'; -$url_owner_down = $url.'&sort_field=owner&sort=down'; - -$table->head[0] = __('ID').ui_get_sorting_arrows($url_incident_id_up, $url_incident_id_down, $select_incident_id_up, $select_incident_id_down); -$table->head[1] = __('Title').ui_get_sorting_arrows($url_title_up, $url_title_down, $select_title_up, $select_title_down); -$table->head[2] = __('Group/Company').ui_get_sorting_arrows($url_group_company_up, $url_group_company_down, $select_group_company_up, $select_group_company_down); -$table->head[3] = __('Status/Resolution').ui_get_sorting_arrows($url_status_resolution_up, $url_status_resolution_down, $select_status_resolution_up, $select_status_resolution_down); -$table->head[4] = __('Priority').ui_get_sorting_arrows($url_priority_up, $url_priority_down, $select_priority_up, $select_priority_down); -$table->head[5] = __('Updated/Started'); -$table->head[6] = __('Creator').ui_get_sorting_arrows($url_creator_up, $url_creator_down, $select_creator_up, $select_creator_down); -$table->head[7] = __('Owner').ui_get_sorting_arrows($url_owner_up, $url_owner_down, $select_owner_up, $select_owner_down); -$table->head[8] = ''; - -$table->data = []; -$i = 0; - -foreach ($incidents_paginated as $key => $value) { - if ($array_get_incidents[$key][6] == 0) { - $status_incident[$array_get_incidents[$key][6]] = __('None'); - } - - if ($array_get_incidents[$key][12] == 0) { - $resolution_incident[$array_get_incidents[$key][12]] = __('None'); - } - - $table->data[$i][0] = '#'.$array_get_incidents[$key][0]; - $table->data[$i][1] = ''; - $table->data[$i][1] .= ui_print_truncate_text($array_get_incidents[$key][3], 160, false); - $table->data[$i][1] .= ''; - $table->data[$i][2] = $group_incident[$array_get_incidents[$key][8]]; - $table->data[$i][3] = $status_incident[$array_get_incidents[$key][6]].' / '.$resolution_incident[$array_get_incidents[$key][12]]; - $table->data[$i][4] = ui_print_integria_incident_priority($array_get_incidents[$key][7], $priority_incident[$array_get_incidents[$key][7]]); - $table->data[$i][5] = $array_get_incidents[$key][9].' / '.$array_get_incidents[$key][1]; - $table->data[$i][6] = $array_get_incidents[$key][10]; - $table->data[$i][7] = $array_get_incidents[$key][5]; - $table->data[$i][8] = ''; - $table->cellclass[$i][8] = 'table_action_buttons'; - $table->data[$i][8] .= ''; - $table->data[$i][8] .= html_print_image('images/edit.svg', true, ['title' => __('Edit')]); - $table->data[$i][8] .= ''; - - $table->data[$i][8] .= ''; - $table->data[$i][8] .= html_print_image('images/delete.svg', true, ['title' => __('Delete'), 'class' => 'invert_filter main_menu_icon']); - $table->data[$i][8] .= ''; - - $i++; -} - -$tablePagination = ''; -// Show table incidents. -if (empty($table->data) === true) { - ui_print_info_message(['no_close' => true, 'message' => __('No tickets to show').'.' ]); -} else { - html_print_table($table); - $tablePagination = ui_pagination( - count($array_get_incidents), - $url, - $offset, - 0, - true, - 'offset', - false, - '' - ); -} - -// Show button to create incident. -echo '
'; -html_print_action_buttons( - html_print_submit_button( - __('Create'), - 'create_new_incident', - false, - [ 'icon' => 'next' ], - true - ), - [ - 'type' => 'data_table', - 'class' => 'fixed_action_buttons', - 'right_content' => $tablePagination, - ] -); -echo '
'; - -// Datapicker library for show calendar. -ui_require_jquery_file('ui.datepicker-'.get_user_language(), 'include/javascript/i18n/'); -?> - - diff --git a/pandora_console/operation/inventory/inventory.php b/pandora_console/operation/inventory/inventory.php index 432ee3e8d8..7355662366 100755 --- a/pandora_console/operation/inventory/inventory.php +++ b/pandora_console/operation/inventory/inventory.php @@ -31,6 +31,7 @@ use PandoraFMS\Enterprise\Metaconsole\Node; // Begin. require_once $config['homedir'].'/include/functions_users.php'; require_once $config['homedir'].'/include/functions_inventory.php'; +enterprise_include('/include/functions_agents.php'); // Calculate new inteval for all reports. diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index 2e5f784cc0..6b98ffb55b 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -681,28 +681,6 @@ $sub['operation/users/user_edit_notifications']['id'] = 'Configure_user_notifica $sub['operation/users/user_edit_notifications']['refr'] = 0; if ($access_console_node === true) { - // Incidents. - $temp_sec2 = $sec2; - $sec2 = 'incident'; - $sec2sub = 'operation/incidents/incident_statistics'; - $sub[$sec2]['text'] = __('Incidents'); - $sub[$sec2]['id'] = 'Incidents'; - $sub[$sec2]['type'] = 'direct'; - $sub[$sec2]['subtype'] = 'nolink'; - $sub[$sec2]['refr'] = 0; - $sub[$sec2]['subsecs'] = [ - 'operation/incidents/incident_detail', - 'operation/integria_incidents', - ]; - - $sub2 = []; - $sub2[$sec2sub]['text'] = __('Integria IMS statistics'); - $sub2['operation/incidents/list_integriaims_incidents']['text'] = __('Integria IMS ticket list'); - - $sub[$sec2]['sub2'] = $sub2; - $sec2 = $temp_sec2; - - // Messages. $sub['message_list']['text'] = __('Messages'); $sub['message_list']['id'] = 'Messages'; @@ -718,6 +696,39 @@ if ($access_console_node === true) { $menu_operation['workspace']['sub'] = $sub; +if ($access_console_node === true) { + if ((bool) $config['ITSM_enabled'] === true) { + // ITSM. + $menu_operation['ITSM']['text'] = __('ITSM'); + $menu_operation['ITSM']['sec2'] = 'operation/ITSM/itsm'; + $menu_operation['ITSM']['id'] = 'oper-itsm'; + + $sub = []; + // ITSM Tickets. + $sub['manageTickets']['text'] = __('Tickets'); + $sub['manageTickets']['id'] = 'itsm-ticket'; + $sub['manageTickets']['refr'] = 0; + $sub['manageTickets']['type'] = 'direct'; + $sub['manageTickets']['subtype'] = 'nolink'; + + $sub2 = []; + $sub2['operation/ITSM/itsm&operation=list']['text'] = __('List'); + $sub2['operation/ITSM/itsm&operation=list']['id'] = 'itsm-ticket-list'; + + $sub2['operation/ITSM/itsm&operation=edit']['text'] = __('Edit'); + $sub2['operation/ITSM/itsm&operation=edit']['id'] = 'itsm-ticket-edit'; + + $sub['manageTickets']['sub2'] = $sub2; + + // ITSM Dashboard. + $sub['operation/ITSM/itsm']['text'] = __('Dashboard'); + $sub['operation/ITSM/itsm']['id'] = 'itsm-dashboard'; + $sub['operation/ITSM/itsm']['refr'] = 0; + + $menu_operation['ITSM']['sub'] = $sub; + } +} + if ($access_console_node === true) { // Rest of options, all with AR privilege (or should events be with incidents?) // ~ if (check_acl ($config['id_user'], 0, "AR")) { @@ -750,9 +761,9 @@ if ($access_console_node === true) { $extension_menu = $extension['operation_menu']; if ($extension['operation_menu']['name'] == 'Matrix' - && ( !check_acl($config['id_user'], 0, 'ER') + && (!check_acl($config['id_user'], 0, 'ER') || !check_acl($config['id_user'], 0, 'EW') - || !check_acl($config['id_user'], 0, 'EM') ) + || !check_acl($config['id_user'], 0, 'EM')) ) { continue; } diff --git a/pandora_console/operation/reporting/graph_analytics.php b/pandora_console/operation/reporting/graph_analytics.php index 9b2fa5347d..8797376070 100644 --- a/pandora_console/operation/reporting/graph_analytics.php +++ b/pandora_console/operation/reporting/graph_analytics.php @@ -636,7 +636,7 @@ $data[2] = html_print_submit_button( 'class' => 'mini w30p', 'icon' => 'next', 'style' => 'margin-left: 208px; width: 130px;', - 'onclick' => '', + 'onclick' => 'exportCustomGraph()', ], true ); @@ -937,6 +937,10 @@ const titleExport = ""; const titleExportConfirm = ""; const messageExportConfirm = ""; +const titleExportError = ""; +const messageExportError = ""; + const titleRemoveConfirm = ""; const messageRemoveConfirm = ""; + \ No newline at end of file diff --git a/pandora_console/operation/reporting/reporting_viewer.php b/pandora_console/operation/reporting/reporting_viewer.php index f84ecdb699..e3e07590ba 100755 --- a/pandora_console/operation/reporting/reporting_viewer.php +++ b/pandora_console/operation/reporting/reporting_viewer.php @@ -285,7 +285,8 @@ ui_print_standard_header( $table2 = new stdClass(); $table2->id = 'controls_table'; $table2->size[2] = '20%'; -$table2->style[3] = 'position:absolute; left: auto'; +$table2->style[3] = 'position:absolute !important; left: auto !important;'; +// $table2->style[3] = 'position:absolute !important; right: 1em !important;'; $table2->styleTable = 'border:none'; if (defined('METACONSOLE')) { @@ -311,11 +312,19 @@ if ($html_menu_export === ENTERPRISE_NOT_HOOK) { $html_menu_export = ''; } +if ((bool) is_metaconsole() === true) { + $table2->data[0][2] = html_print_label_input_block( + __('Date').' ', + html_print_select_date_range('date', true, get_parameter('date', SECONDS_1DAY), $date_init, $time_init, date('Y/m/d'), date('H:i:s'), $date_text), + ); +} else { + $table2->data[0][2] = html_print_label_input_block( + __('Date').' ', + html_print_select_date_range('date', true, get_parameter('date', SECONDS_1DAY), $date_init, $time_init, date('Y/m/d'), date('H:i:s'), $date_text), + ['label_class' => 'filter_label_position_before'] + ); +} -$table2->data[0][2] = html_print_label_input_block( - __('Date').':
', - html_print_select_date_range('date', true, get_parameter('date', SECONDS_1DAY), $date_init, $time_init, date('Y/m/d'), date('H:i:s'), $date_text) -); $table2->data[0][3] = $html_menu_export; @@ -324,16 +333,32 @@ $searchForm = '
'mini', - 'icon' => 'next', - ], - true -); +if ((bool) is_metaconsole() === true) { + $Actionbuttons .= html_print_submit_button( + __('Update'), + 'date_submit', + false, + [ + 'mode' => 'mini', + 'icon' => 'next', + 'style' => 'position: absolute; top: 60px;', + ], + true + ); +} else { + $Actionbuttons .= html_print_submit_button( + __('Update'), + 'date_submit', + false, + [ + 'mode' => 'mini', + 'icon' => 'next', + 'style' => 'position: absolute; top: 20px;', + ], + true + ); +} + $searchForm .= html_print_div( [ @@ -426,13 +451,16 @@ $(document).ready (function () { $("#string_to").show(); $('#string_from').show(); $("#string_items").hide(); + console.log($(".filter_label_position_before").html()); } else { $("#string_to").hide(); $('#string_from').hide(); $("#string_items").show(); } }); - + $('#div-report_export').addClass('div-report_export_filter'); + $('#button-export').addClass('button-export_filter '); + $('#report_export_menu').removeClass('right'); }); diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php index 79bff8ef3d..31a0463de2 100644 --- a/pandora_console/operation/users/user_edit.php +++ b/pandora_console/operation/users/user_edit.php @@ -133,9 +133,6 @@ if (isset($_GET['modified']) && !$view_mode) { $upd_info['ehorus_user_level_pass'] = get_parameter('ehorus_user_level_pass'); $upd_info['ehorus_user_level_enabled'] = get_parameter('ehorus_user_level_enabled', 0); - $upd_info['integria_user_level_user'] = get_parameter('integria_user_level_user'); - $upd_info['integria_user_level_pass'] = get_parameter('integria_user_level_pass'); - $is_admin = db_get_value('is_admin', 'tusuario', 'id_user', $id); $section = io_safe_output($upd_info['section']); @@ -889,60 +886,6 @@ $skin = ''; echo '
'; } - if ($config['integria_enabled'] && $config['integria_user_level_conf']) { - // Integria IMS user remote login. - $table_remote = new StdClass(); - $table_remote->data = []; - $table_remote->width = '100%'; - $table_remote->id = 'integria-remote-setup'; - $table_remote->class = 'white_box'; - $table_remote->size['name'] = '30%'; - $table_remote->style['name'] = 'font-weight: bold'; - - // Integria IMS user level authentication. - // Title. - $row = []; - $row['control'] = '

'.__('Integria user configuration').':

'; - $table_remote->data['integria_user_level_conf'] = $row; - - // Integria IMS user. - $row = []; - $row['name'] = __('User'); - $row['control'] = html_print_input_text('integria_user_level_user', $user_info['integria_user_level_user'], '', 30, 100, true); - $table_remote->data['integria_user_level_user'] = $row; - - // Integria IMS pass. - $row = []; - $row['name'] = __('Password'); - $row['control'] = html_print_input_password('integria_user_level_pass', io_output_password($user_info['integria_user_level_pass']), '', 30, 100, true); - $table_remote->data['integria_user_level_pass'] = $row; - - // Test. - $integria_host = db_get_value('value', 'tconfig', 'token', 'integria_hostname'); - $integria_api_pass = db_get_value('value', 'tconfig', 'token', 'integria_api_pass'); - - $row = []; - $row['name'] = __('Test'); - $row['control'] = html_print_button( - __('Start'), - 'test-integria', - false, - 'integria_connection_test("'.$integria_host.'",'.$integria_api_pass.')', - [ 'icon' => 'next' ], - true - ); - $row['control'] .= ' '; - $row['control'] .= ' '; - $row['control'] .= ' '; - $row['control'] .= ''; - $table_remote->data['integria_test'] = $row; - - echo '
'; - html_print_table($table_remote); - echo '
'; - } - - if ($is_management_allowed === true) { if ((bool) $config['user_can_update_info'] === false) { $outputButton = ''.__('You can not change your user info under the current authentication scheme').''; @@ -1074,7 +1017,6 @@ $skin = ''; diff --git a/pandora_console/pandora_console.redhat.spec b/pandora_console/pandora_console.redhat.spec index 6554c6f5c6..eb0de7ef8c 100644 --- a/pandora_console/pandora_console.redhat.spec +++ b/pandora_console/pandora_console.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.773.3 -%define release 230921 +%define release 230928 # User and Group under which Apache is running %define httpd_name httpd diff --git a/pandora_console/pandora_console.rhel7.spec b/pandora_console/pandora_console.rhel7.spec index a77ac97f5b..f1d8475905 100644 --- a/pandora_console/pandora_console.rhel7.spec +++ b/pandora_console/pandora_console.rhel7.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.773.3 -%define release 230921 +%define release 230928 # User and Group under which Apache is running %define httpd_name httpd diff --git a/pandora_console/pandora_console.spec b/pandora_console/pandora_console.spec index 1a843c42ea..e3ecb23633 100644 --- a/pandora_console/pandora_console.spec +++ b/pandora_console/pandora_console.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.773.3 -%define release 230921 +%define release 230928 %define httpd_name httpd # User and Group under which Apache is running %define httpd_name apache2 diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index b8efa4b701..b44fb54e92 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -397,7 +397,8 @@ CREATE TABLE IF NOT EXISTS `talert_commands` ( `fields_values` TEXT, `fields_hidden` TEXT, `previous_name` TEXT, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + UNIQUE (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; -- ----------------------------------------------------- @@ -405,7 +406,7 @@ CREATE TABLE IF NOT EXISTS `talert_commands` ( -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `talert_actions` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `name` TEXT, + `name` VARCHAR(500), `id_alert_command` INT UNSIGNED NULL DEFAULT 0, `field1` TEXT, `field2` TEXT, @@ -452,6 +453,7 @@ CREATE TABLE IF NOT EXISTS `talert_actions` ( `previous_name` TEXT, `create_wu_integria` TINYINT DEFAULT NULL, PRIMARY KEY (`id`), + UNIQUE (`name`), FOREIGN KEY (`id_alert_command`) REFERENCES talert_commands(`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; @@ -623,19 +625,6 @@ CREATE TABLE IF NOT EXISTS `talert_execution_queue` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; --- ----------------------------------------------------- --- Table `tattachment` --- ----------------------------------------------------- -CREATE TABLE IF NOT EXISTS `tattachment` ( - `id_attachment` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `id_incidencia` INT UNSIGNED NOT NULL DEFAULT 0, - `id_usuario` VARCHAR(255) NOT NULL DEFAULT '', - `filename` VARCHAR(255) NOT NULL DEFAULT '', - `description` VARCHAR(150) DEFAULT '', - `size` BIGINT UNSIGNED NOT NULL DEFAULT 0, - PRIMARY KEY (`id_attachment`) -) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; - -- ----------------------------------------------------- -- Table `tconfig` -- ----------------------------------------------------- @@ -797,30 +786,6 @@ CREATE TABLE IF NOT EXISTS `tcredential_store` ( PRIMARY KEY (`identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; --- --------------------------------------------------------------------- --- Table `tincidencia` --- --------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `tincidencia` ( - `id_incidencia` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - `inicio` DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00', - `cierre` DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00', - `titulo` TEXT, - `descripcion` TEXT, - `id_usuario` VARCHAR(255) NOT NULL DEFAULT '', - `origen` VARCHAR(100) NOT NULL DEFAULT '', - `estado` INT NOT NULL DEFAULT 0, - `prioridad` INT NOT NULL DEFAULT 0, - `id_grupo` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, - `actualizacion` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, - `id_creator` VARCHAR(60) DEFAULT NULL, - `id_lastupdate` VARCHAR(60) DEFAULT NULL, - `id_agente_modulo` BIGINT NOT NULL, - `notify_email` TINYINT UNSIGNED NOT NULL DEFAULT 0, - `id_agent` INT UNSIGNED NULL DEFAULT 0, - PRIMARY KEY (`id_incidencia`), - KEY `incident_index_1` (`id_usuario`,`id_incidencia`), - KEY `id_agente_modulo` (`id_agente_modulo`) -) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; -- --------------------------------------------------------------------- -- Table `tlanguage` @@ -1098,19 +1063,6 @@ CREATE TABLE IF NOT EXISTS `tnetwork_profile_pen` ( REFERENCES `tnetwork_profile` (`id_np`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; --- ---------------------------------------------------------------------- --- Table `tnota` --- ---------------------------------------------------------------------- -CREATE TABLE IF NOT EXISTS `tnota` ( - `id_nota` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - `id_incident` BIGINT UNSIGNED NOT NULL, - `id_usuario` VARCHAR(255) NOT NULL DEFAULT '0', - `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `nota` MEDIUMTEXT, - PRIMARY KEY (`id_nota`), - KEY `id_incident` (`id_incident`) -) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; - -- ---------------------------------------------------------------------- -- Table `torigen` -- ---------------------------------------------------------------------- @@ -1358,7 +1310,7 @@ CREATE TABLE IF NOT EXISTS `tusuario` ( `ehorus_user_level_pass` VARCHAR(45), `ehorus_user_level_enabled` TINYINT, `integria_user_level_user` VARCHAR(60), - `integria_user_level_pass` VARCHAR(45), + `integria_user_level_pass` TEXT, `api_token` VARCHAR(255) NOT NULL DEFAULT '', `allowed_ip_active` TINYINT UNSIGNED DEFAULT 0, `allowed_ip_list` TEXT, @@ -2916,6 +2868,7 @@ CREATE TABLE IF NOT EXISTS `tservice` ( `is_favourite` TINYINT NOT NULL DEFAULT 0, `enable_sunburst` TINYINT NOT NULL DEFAULT 0, `asynchronous` TINYINT NOT NULL DEFAULT 0, + `enable_horizontal_tree` TINYINT NOT NULL DEFAULT 0, `rca` TEXT, PRIMARY KEY (`id`) ) ENGINE=InnoDB diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index ff9df1610f..728ed3518e 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -26,6 +26,8 @@ INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (13,'Generate Notification','Internal type','This command allows you to send an internal notification to any user or group.',1,'[\"Destination user\",\"Destination group\",\"Title\",\"Message\",\"Link\",\"Criticity\",\"\",\"\",\"\",\"\",\"\"]','[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]'); INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (14,'Send report by e-mail','Internal type','This command allows you to send a report by email.',1,'[\"Report\",\"e-mail address\",\"Subject\",\"Text\",\"Report type\",\"\",\"\",\"\",\"\",\"\"]','[\"_reports_\",\"\",\"\",\"_html_editor_\",\"xml,XML;pdf,PDF;json,JSON;csv,CSV\",\"\",\"\",\"\",\"\",\"\"]'); INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (15,'Send report by e-mail (from template)','Internal type','This command allows you to send a report generated from a template by email.',1,'[\"Template\",\"Regexp agent filter\",\"e-mail address\",\"Subject\",\"Text\",\"Report type\",\"\",\"\",\"\",\"\"]','[\"_report_templates_\",\"\",\"\",\"\",\"_html_editor_\",\"xml,XML;pdf,PDF;json,JSON;csv,CSV\",\"\",\"\",\"\",\"\"]'); +INSERT INTO `talert_commands` (`id`, `name`, `command`, `description`, `internal`, `fields_descriptions`, `fields_values`) VALUES (16,'Pandora ITSM Ticket','Internal type','Create a ticket in Pandora ITSM',1,'["Ticket title","Ticket group ID","Ticket priority","Ticket owner","Ticket type","Ticket status","Ticket description","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_"]','["", "_ITSM_groups_", "_ITSM_priorities_","_ITSM_users_","_ITSM_types_","_ITSM_status_","_html_editor_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_","_custom_field_ITSM_"]'); + -- -- Dumping data for table `tconfig` -- @@ -126,12 +128,9 @@ INSERT INTO `tconfig` (`token`, `value`) VALUES ('custom_docs_logo', 'default_docs.png'), ('custom_support_logo', 'default_support.png'), ('custom_logo_white_bg_preview', 'pandora_logo_head_white_bg.png'), -('integria_enabled', 0), -('integria_user', ''), +('ITSM_enabled', 0), ('integria_pass', ''), -('integria_hostname', ''), -('integria_api_pass', ''), -('integria_req_timeout', 5), +('ITSM_hostname', ''), ('default_group', ''), ('default_criticity', ''), ('default_creator', ''), @@ -1159,7 +1158,7 @@ INSERT INTO `talert_actions` (`id`, `name`, `id_alert_command`, `field1`, `field (4,'Send Report by e-mail',14,'','yourmail@domain.es','','<div style="background-color: #eaf0f6; font-family: Arial, Helvetica, sans-serif; padding: 30px; margin: 0;"><table style="max-width: 560px; background-color: white; border-radius: 10px; padding: 10px 20px 40px;" cellspacing="0" cellpadding="0" align="center"><thead><tr><td style="padding: 0px 0px 5px;"><a href="https://pandorafms.com/en/" target="_blank"><img src="https://pandorafms.com/wp-content/uploads/2022/03/System-email-Pandora-FMS.png" width="206px"></a></td><td style="padding: 0px 0px 5px;"><p style="text-align: right; color: #223549; font-weight: bold; line-height: 36px; padding: 0px; font-size: 12px;">Automatic alert system</p></td></tr><tr><td style="padding: 0px 0px 5px;" colspan="2"><hr style="border: 1px solid #f5f5f5; width: 100%; margin: 0px;"></td></tr></thead><tbody><tr><td colspan="2"><img onerror="this.style.display=&quot;none&quot;;" src="_statusimage_" style="display: block; margin-left: auto; margin-right: auto; width: 105px; margin-top: 20px; padding: 0px;" width="105px"></td></tr><tr><td colspan="2"><p style="font-size: 24px; text-align: center; color: #223549; padding: 0px 10%; line-height: 34px; margin: 20px 0px;">We have bad news for you, something is on <span style="text-transform: uppercase; font-weight: 800;">_modulestatus_</span> status!</p><div><!--[if mso]><v:rect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="#" style="height:33px;v-text-anchor:middle;width:100px;" stroke="f" fillcolor="#D84A38"><w:anchorlock/><center><![endif]--><a style="background-color: #223549; border: none; color: white; padding: 15px 30px; text-align: center; text-decoration: none; display: block; font-size: 16px; margin-left: auto; margin-right: auto; border-radius: 100px; max-width: 50%; margin-top: 0px; font-weight: bold;" href="_homeurl_">Go to Pandora FMS Console</a><!--[if mso]></center></v:rect><![endif]--></div></td></tr><tr><td colspan="2"><div style="background-color: #f6f6f6; border-radius: 10px; padding: 10px 20px; margin-top: 40px;"><p style="font-size: 18px; line-height: 30px; color: #223549;">Monitoring details</p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Data: <span style="font-weight: 400!important;">_data_ <em>(_modulestatus_)</em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Agent: <span style="font-weight: 400!important;">_agent_ <em>_address_</em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Module: <span style="font-weight: 400!important;">_module_ <em>_moduledescription_</em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Timestamp: <span style="font-weight: 400!important;">_timestamp_</span></p></div></td></tr><tr><td style="padding: 20px 0px;" colspan="2"><p style="font-size: 18px; line-height: 30px; color: #223549;">Report details</p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Generated:&nbsp;<span style="font-weight: 400!important;">_report_generated_date_<em><br></em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Report date:&nbsp;<span style="font-weight: 400!important;">_report_date_<em><br></em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Description:&nbsp;<span style="font-weight: 400!important;">_report_description_</span></p></td></tr></tbody></table><div style="text-align: center; margin-top: 10px;"><p style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;"><a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/en/contact/">Contact Us</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/community/forums/forum/english/">Support</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/manual/en/start">Docs</a></p></div></div>','','','','','','',0,0,'','','','<div style="background-color: #eaf0f6; font-family: Arial, Helvetica, sans-serif; padding: 30px; margin: 0;"> <table style="max-width: 560px; background-color: white; border-radius: 10px; padding: 10px 20px 40px;" cellspacing="0" cellpadding="0" align="center"> <thead> <tr> <td style="padding: 0px 0px 5px;"><a href="https://pandorafms.com/en/" target="_blank"><img src="https://pandorafms.com/wp-content/uploads/2022/03/System-email-Pandora-FMS.png" width="206px"></a></td> <td style="padding: 0px 0px 5px;"> <p style="text-align: right; color: #223549; font-weight: bold; line-height: 36px; padding: 0px; font-size: 12px;">Automatic alert system</p> </td> </tr> <tr> <td style="padding: 0px 0px 5px;" colspan="2"><hr style="border: 1px solid #f5f5f5; width: 100%; margin: 0px;"></td> </tr> </thead> <tbody> <tr> <td colspan="2"><img src="https://pandorafms.com/wp-content/uploads/2022/03/System-email-Good-news.png" style="display: block; margin-left: auto; margin-right: auto; width: 105px; margin-top: 20px; padding: 0px;" width="105px"></td> </tr> <tr> <td colspan="2"> <p style="font-size: 24px; text-align: center; color: #223549; padding: 0px 10%; line-height: 34px; margin: 20px 0px;">We have good news for you, alert has been <span style="text-transform: uppercase; font-weight: 800;">recovered</span></p> <div><!--[if mso]><v:rect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="#" style="height:33px;v-text-anchor:middle;width:100px;" stroke="f" fillcolor="#D84A38"><w:anchorlock/><center><![endif]--><a style="background-color: #223549; border: none; color: white; padding: 15px 30px; text-align: center; text-decoration: none; display: block; font-size: 16px; margin-left: auto; margin-right: auto; border-radius: 100px; max-width: 50%; margin-top: 0px; font-weight: bold;" href="_homeurl_">Go to Pandora FMS Console</a><!--[if mso]></center></v:rect><![endif]--></div> </td> </tr> <tr> <td colspan="2"> <div style="background-color: #f6f6f6; border-radius: 10px; padding: 10px 20px; margin-top: 40px;"> <p style="font-size: 18px; line-height: 30px; color: #223549;">Monitoring details</p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Data: <span style="font-weight: 400!important;">_data_ <em>(_modulestatus_)</em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Agent: <span style="font-weight: 400!important;">_agent_ <em>_address_</em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Module: <span style="font-weight: 400!important;">_module_ <em>_moduledescription_</em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Timestamp: <span style="font-weight: 400!important;">_timestamp_</span></p> </div> </td> </tr> <tr> <td style="padding: 20px 0px;" colspan="2"> <p style="font-size: 18px; line-height: 30px; color: #223549;">Report details</p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Generated:&nbsp;<span style="font-weight: 400!important;">_report_generated_date_<em><br></em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Report date:&nbsp;<span style="font-weight: 400!important;">_report_date_<em><br></em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Description:&nbsp;<span style="font-weight: 400!important;">_report_description_</span></p> </td> </tr> </tbody> </table> <div style="text-align: center; margin-top: 10px;"> <p style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;"><a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/en/contact/">Contact Us</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/community/forums/forum/english/">Support</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/manual/en/start">Docs</a></p> </div> </div>','','','','','',''); INSERT INTO `talert_actions` (`id`, `name`, `id_alert_command`, `field1`, `field2`, `field3`, `field4`, `field5`, `field6`, `field7`, `field8`, `field9`, `field10`, `id_group`, `action_threshold`, `field1_recovery`, `field2_recovery`, `field3_recovery`, `field4_recovery`, `field5_recovery`, `field6_recovery`, `field7_recovery`, `field8_recovery`, `field9_recovery`, `field10_recovery`) VALUES (5,'Send Report by e-mail (from template)',15,'','','yourmail@domain.es','','<div style="background-color: #eaf0f6; font-family: Arial, Helvetica, sans-serif; padding: 30px; margin: 0;"><table style="max-width: 560px; background-color: white; border-radius: 10px; padding: 10px 20px 40px;" cellspacing="0" cellpadding="0" align="center"><thead><tr><td style="padding: 0px 0px 5px;"><a href="https://pandorafms.com/en/" target="_blank"><img src="https://pandorafms.com/wp-content/uploads/2022/03/System-email-Pandora-FMS.png" width="206px"></a></td><td style="padding: 0px 0px 5px;"><p style="text-align: right; color: #223549; font-weight: bold; line-height: 36px; padding: 0px; font-size: 12px;">Automatic alert system</p></td></tr><tr><td style="padding: 0px 0px 5px;" colspan="2"><hr style="border: 1px solid #f5f5f5; width: 100%; margin: 0px;"></td></tr></thead><tbody><tr><td colspan="2"><img onerror="this.style.display=&quot;none&quot;;" src="_statusimage_" style="display: block; margin-left: auto; margin-right: auto; width: 105px; margin-top: 20px; padding: 0px;" width="105px"></td></tr><tr><td colspan="2"><p style="font-size: 24px; text-align: center; color: #223549; padding: 0px 10%; line-height: 34px; margin: 20px 0px;">We have bad news for you, something is on <span style="text-transform: uppercase; font-weight: 800;">_modulestatus_</span> status!</p><div><!--[if mso]><v:rect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="#" style="height:33px;v-text-anchor:middle;width:100px;" stroke="f" fillcolor="#D84A38"><w:anchorlock/><center><![endif]--><a style="background-color: #223549; border: none; color: white; padding: 15px 30px; text-align: center; text-decoration: none; display: block; font-size: 16px; margin-left: auto; margin-right: auto; border-radius: 100px; max-width: 50%; margin-top: 0px; font-weight: bold;" href="_homeurl_">Go to Pandora FMS Console</a><!--[if mso]></center></v:rect><![endif]--></div></td></tr><tr><td colspan="2"><div style="background-color: #f6f6f6; border-radius: 10px; padding: 10px 20px; margin-top: 40px;"><p style="font-size: 18px; line-height: 30px; color: #223549;">Monitoring details</p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Data: <span style="font-weight: 400!important;">_data_ <em>(_modulestatus_)</em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Agent: <span style="font-weight: 400!important;">_agent_ <em>_address_</em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Module: <span style="font-weight: 400!important;">_module_ <em>_moduledescription_</em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Timestamp: <span style="font-weight: 400!important;">_timestamp_</span></p></div></td></tr><tr><td style="padding: 20px 0px;" colspan="2"><p style="font-size: 18px; line-height: 30px; color: #223549;">Report details</p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Generated:&nbsp;<span style="font-weight: 400!important;">_report_generated_date_<em><br></em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Report date:&nbsp;<span style="font-weight: 400!important;">_report_date_<em><br></em></span></p><p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Description:&nbsp;<span style="font-weight: 400!important;">_report_description_</span></p></td></tr></tbody></table><div style="text-align: center; margin-top: 10px;"><p style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;"><a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/en/contact/">Contact Us</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/community/forums/forum/english/">Support</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/manual/en/start">Docs</a></p></div></div>','','','','','',0,0,'','','','','<div style="background-color: #eaf0f6; font-family: Arial, Helvetica, sans-serif; padding: 30px; margin: 0;"> <table style="max-width: 560px; background-color: white; border-radius: 10px; padding: 10px 20px 40px;" cellspacing="0" cellpadding="0" align="center"> <thead> <tr> <td style="padding: 0px 0px 5px;"><a href="https://pandorafms.com/en/" target="_blank"><img src="https://pandorafms.com/wp-content/uploads/2022/03/System-email-Pandora-FMS.png" width="206px"></a></td> <td style="padding: 0px 0px 5px;"> <p style="text-align: right; color: #223549; font-weight: bold; line-height: 36px; padding: 0px; font-size: 12px;">Automatic alert system</p> </td> </tr> <tr> <td style="padding: 0px 0px 5px;" colspan="2"><hr style="border: 1px solid #f5f5f5; width: 100%; margin: 0px;"></td> </tr> </thead> <tbody> <tr> <td colspan="2"><img src="https://pandorafms.com/wp-content/uploads/2022/03/System-email-Good-news.png" style="display: block; margin-left: auto; margin-right: auto; width: 105px; margin-top: 20px; padding: 0px;" width="105px"></td> </tr> <tr> <td colspan="2"> <p style="font-size: 24px; text-align: center; color: #223549; padding: 0px 10%; line-height: 34px; margin: 20px 0px;">We have good news for you, alert has been <span style="text-transform: uppercase; font-weight: 800;">recovered</span></p> <div><!--[if mso]><v:rect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="#" style="height:33px;v-text-anchor:middle;width:100px;" stroke="f" fillcolor="#D84A38"><w:anchorlock/><center><![endif]--><a style="background-color: #223549; border: none; color: white; padding: 15px 30px; text-align: center; text-decoration: none; display: block; font-size: 16px; margin-left: auto; margin-right: auto; border-radius: 100px; max-width: 50%; margin-top: 0px; font-weight: bold;" href="_homeurl_">Go to Pandora FMS Console</a><!--[if mso]></center></v:rect><![endif]--></div> </td> </tr> <tr> <td colspan="2"> <div style="background-color: #f6f6f6; border-radius: 10px; padding: 10px 20px; margin-top: 40px;"> <p style="font-size: 18px; line-height: 30px; color: #223549;">Monitoring details</p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Data: <span style="font-weight: 400!important;">_data_ <em>(_modulestatus_)</em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Agent: <span style="font-weight: 400!important;">_agent_ <em>_address_</em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Module: <span style="font-weight: 400!important;">_module_ <em>_moduledescription_</em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Timestamp: <span style="font-weight: 400!important;">_timestamp_</span></p> </div> </td> </tr> <tr> <td style="padding: 20px 0px;" colspan="2"> <p style="font-size: 18px; line-height: 30px; color: #223549;">Report details</p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Generated:&nbsp;<span style="font-weight: 400!important;">_report_generated_date_<em><br></em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Report date:&nbsp;<span style="font-weight: 400!important;">_report_date_<em><br></em></span></p> <p style="font-size: 15px; color: #333333; font-weight: 800; line-height: 15px;">Description:&nbsp;<span style="font-weight: 400!important;">_report_description_</span></p> </td> </tr> </tbody> </table> <div style="text-align: center; margin-top: 10px;"> <p style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;"><a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/en/contact/">Contact Us</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/community/forums/forum/english/">Support</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a style="font-size: 12px; text-decoration: none; font-weight: 400; color: #777;" href="https://pandorafms.com/manual/en/start">Docs</a></p> </div> </div>','','','','',''); - +INSERT INTO `talert_actions` (`id`, `name`, `id_alert_command`) VALUES (6,'Create Pandora ITSM ticket',16); -- alert templates (default) INSERT INTO `talert_templates` (`id`,`name`,`description`,`id_alert_action`,`field1`,`field2`,`field3`,`field4`,`field5`,`field6`,`field7`,`field8`,`field9`,`field10`,`field11`,`field12`,`field13`,`field14`,`field15`,`field16`,`field17`,`field18`,`field19`,`field20`,`type`,`value`,`matches_value`,`max_value`,`min_value`,`time_threshold`,`max_alerts`,`min_alerts`,`time_from`,`time_to`,`monday`,`tuesday`,`wednesday`,`thursday`,`friday`,`saturday`,`sunday`,`recovery_notify`,`field1_recovery`,`field2_recovery`,`field3_recovery`,`field4_recovery`,`field5_recovery`,`field6_recovery`,`field7_recovery`,`field8_recovery`,`field9_recovery`,`field10_recovery`,`field11_recovery`,`field12_recovery`,`field13_recovery`,`field14_recovery`,`field15_recovery`,`field16_recovery`,`field17_recovery`,`field18_recovery`,`field19_recovery`,`field20_recovery`,`priority`,`id_group`,`special_day`,`wizard_level`,`min_alerts_reset_counter`,`disable_event`,`previous_name`, `schedule`) @@ -1205,7 +1204,7 @@ INSERT INTO `tagent_custom_fields` VALUES (1,'Serial Number',0,0,'',0),(2,' INSERT INTO `ttag` VALUES (1,'network','Network equipment','http://artica.es','','',''),(2,'critical','Critical modules','','','',''),(3,'dmz','DMZ Network Zone','','','',''),(4,'performance','Performance anda capacity modules','','','',''),(5,'configuration','','','','',''); -INSERT INTO `tevent_response` VALUES (1,'Ping to host','Ping to the agent host','ping -c 5 _agent_address_','command',0,620,500,0,'',0,90,0),(3,'Create incident from event','Create a incident from the event with the standard incidents system of Pandora FMS','index.php?sec=workspace&sec2=operation/incidents/incident_detail&insert_form&from_event=_event_id_','url',0,0,0,1,'',0,90,0),(5,'Restart agent','Restart the agent with using UDP protocol. To use this response is necessary to have installed Pandora FMS server and console in the same machine.','/usr/share/pandora_server/util/udp_client.pl _agent_address_ 41122 "REFRESH AGENT"','command',0,620,500,0,'',0,90,0),(6,'Ping to module agent host','Ping to the module agent host','ping -c 5 _module_address_','command',0,620,500,0,'',0,90,0); +INSERT INTO `tevent_response` VALUES (1,'Ping to host','Ping to the agent host','ping -c 5 _agent_address_','command',0,620,500,0,'',0,90,0),(3,'Create incident from event','Create a incident from the event with the standard incidents system of Pandora FMS','index.php?sec=workspace&sec2=operation/incidents/incident_detail&insert_form&from_event=_event_id_','url',0,0,0,1,'',0,90,0),(5,'Restart agent','Restart the agent with using UDP protocol. To use this response is necessary to have installed Pandora FMS server and console in the same machine.','/usr/share/pandora_server/util/udp_client.pl _agent_address_ 41122 "REFRESH AGENT"','command',0,620,500,0,'',0,90,0),(6,'Ping to module agent host','Ping to the module agent host','ping -c 5 _module_address_','command',0,620,500,0,'',0,90,0),(7,'Create ticket in Pandora ITSM from event','Create a ticket in Pandora ITSM from an event','index.php?sec=manageTickets&sec2=operation/ITSM/itsm&operation=edit&from_event=_event_id_','url',0,0,0,1,'',0,90,1); INSERT INTO `tupdate_settings` VALUES ('current_update', '412'), ('customer_key', 'PANDORA-FREE'), ('updating_binary_path', 'Path where the updated binary files will be stored'), ('updating_code_path', 'Path where the updated code is stored'), ('dbname', ''), ('dbhost', ''), ('dbpass', ''), ('dbuser', ''), ('dbport', ''), ('proxy', ''), ('proxy_port', ''), ('proxy_user', ''), ('proxy_pass', ''); diff --git a/pandora_console/update_manager_client/lib/UpdateManager/Client.php b/pandora_console/update_manager_client/lib/UpdateManager/Client.php index ae893e2fb9..42d9e6367a 100644 --- a/pandora_console/update_manager_client/lib/UpdateManager/Client.php +++ b/pandora_console/update_manager_client/lib/UpdateManager/Client.php @@ -1018,7 +1018,7 @@ class Client ); if ($sth === false) { - // IntegriaIMS. + // Pandora ITSM. $sth = $dbh->query( 'SELECT `value` FROM `tconfig` diff --git a/pandora_console/views/ITSM/ITSMCustomFields.php b/pandora_console/views/ITSM/ITSMCustomFields.php new file mode 100644 index 0000000000..efdb9c0ef3 --- /dev/null +++ b/pandora_console/views/ITSM/ITSMCustomFields.php @@ -0,0 +1,107 @@ + true, + 'message' => __('Incidence type not fields'), + ] + ); +} else { + $output = '
'; + foreach ($customFields as $field) { + $options = [ + 'name' => 'custom-fields['.$field['idIncidenceTypeField'].']', + 'required' => $field['isRequired'], + 'return' => true, + ]; + + $class = ''; + + switch ($field['type']) { + case 'COMBO': + $options['type'] = 'select'; + $fieldsValues = explode(',', $field['comboValue']); + $options['fields'] = array_combine($fieldsValues, $fieldsValues); + $options['selected'] = ($fieldsData[$field['idIncidenceTypeField']] ?? null); + break; + + case 'TEXT': + $options['value'] = ($fieldsData[$field['idIncidenceTypeField']] ?? null); + $options['type'] = 'text'; + break; + + case 'CHECKBOX': + $options['checked'] = ($fieldsData[$field['idIncidenceTypeField']] ?? null); + $options['type'] = 'checkbox'; + break; + + case 'DATE': + $options['value'] = ($fieldsData[$field['idIncidenceTypeField']] ?? null); + $options['type'] = 'text'; + break; + + case 'NUMERIC': + $options['value'] = ($fieldsData[$field['idIncidenceTypeField']] ?? null); + $options['type'] = 'number'; + break; + + case 'TEXTAREA': + $options['value'] = ($fieldsData[$field['idIncidenceTypeField']] ?? null); + $options['type'] = 'textarea'; + $options['rows'] = 4; + $options['columns'] = 0; + $class = 'incidence-type-custom-fields-textarea'; + break; + + default: + // Not posible. + break; + } + + $output .= html_print_label_input_block( + $field['label'], + html_print_input($options), + ['div_class' => $class] + ); + } + + $output .= '
'; + + echo $output; +} diff --git a/pandora_console/views/ITSM/ITSMDashboardView.php b/pandora_console/views/ITSM/ITSMDashboardView.php new file mode 100644 index 0000000000..a43fc9907e --- /dev/null +++ b/pandora_console/views/ITSM/ITSMDashboardView.php @@ -0,0 +1,118 @@ +'; + $output .= ''.$title.''; + $labels = array_keys($data); + $options = [ + 'width' => 320, + 'height' => 200, + 'waterMark' => $water_mark, + 'legend' => [ + 'display' => true, + 'position' => 'right', + 'align' => 'center', + ], + 'labels' => $labels, + ]; + + $output .= '
'; + $output .= pie_graph( + array_values($data), + $options + ); + $output .= '
'; + $output .= '
'; + + return $output; +} + + +// Header tabs. +ui_print_standard_header( + __('ITSM Dashboard'), + '', + false, + 'ITSM_tab', + false, + $headerTabs, + [ + [ + 'link' => 'index.php?sec=ITSM&sec2=operation/ITSM/itsm', + 'label' => __('ITSM'), + ], + [ + 'link' => 'index.php?sec=ITSM&sec2=operation/ITSM/itsm', + 'label' => __('ITSM Dashboard'), + ], + ] +); + +if (empty($error) === false) { + ui_print_error_message($error); +} + +if (empty($incidencesByStatus) === true) { + ui_print_info_message( + [ + 'no_close' => true, + 'message' => __('Not found incidences'), + ] + ); +} else { + $output = '
'; + $output .= draw_graph(__('Incidents by status'), $incidencesByStatus); + $output .= draw_graph(__('Incidents by priority'), $incidencesByPriorities); + $output .= draw_graph(__('Incidents by group'), $incidencesByGroups); + $output .= draw_graph(__('Incidents by user'), $incidencesByOwners); + $output .= '
'; + echo $output; +} diff --git a/pandora_console/views/ITSM/ITSMTicketDetailView.php b/pandora_console/views/ITSM/ITSMTicketDetailView.php new file mode 100644 index 0000000000..670531bfb2 --- /dev/null +++ b/pandora_console/views/ITSM/ITSMTicketDetailView.php @@ -0,0 +1,420 @@ + 'index.php?sec=ITSM&sec2=operation/ITSM/itsm', + 'label' => __('ITSM'), + ], + [ + 'link' => 'index.php?sec=ITSM&sec2=operation/ITSM/itsm&operation=list', + 'label' => __('ITSM Tickets'), + ], + [ + 'link' => 'index.php?sec=ITSM&sec2=operation/ITSM/itsm', + 'label' => __('ITSM Detailed'), + ], + ] +); + +if (empty($error) === false) { + ui_print_error_message($error); +} + +if (empty($error_upload) === false) { + ui_print_error_message($error_upload); +} + +if (empty($error_comment) === false) { + ui_print_error_message($error_comment); +} + +if (empty($error_delete_attachment) === false) { + ui_print_error_message($error_delete_attachment); +} + +if (empty($successfullyMsg) === false) { + ui_print_success_message($successfullyMsg); +} + +if (empty($incidence) === true) { + ui_print_info_message(__('Incidence not found')); +} else { + $nameIncidence = '--'; + if (empty($incidence['idIncidenceType']) === false) { + $nameIncidence = $objectTypes[$incidence['idIncidenceType']]; + } + + // Details box. + $details_box = '
'; + $details_box .= '
'.__('Status').'
'; + $details_box .= '
'.__('Resolution').'
'; + $details_box .= '
'.__('Group').'
'; + $details_box .= '
'.__('Priority').'
'; + $details_box .= '
'.__('Type').'
'; + $details_box .= '
'; + $details_box .= html_print_image('images/heart.png', true, ['class' => 'invert_filter']); + $details_box .= '
'; + $details_box .= '
'; + $details_box .= html_print_image('images/builder@svg.svg', true, ['class' => 'invert_filter']); + $details_box .= '
'; + $details_box .= '
'; + $details_box .= html_print_image('images/user_green.png', true, ['class' => 'invert_filter']); + $details_box .= '
'; + $details_box .= '
'; + $details_box .= $priorityDiv; + $details_box .= '
'; + $details_box .= '
'; + $details_box .= html_print_image('images/incidents.png', true, ['class' => 'invert_filter']); + $details_box .= '
'; + $details_box .= '
'.$status[$incidence['status']].'
'; + $details_box .= '
'; + $details_box .= ($incidence['resolution'] !== 'NOTRESOLVED') ? $resolutions[$incidence['resolution']] : '--'; + $details_box .= '
'; + $details_box .= '
'.$groups[$incidence['idGroup']].'
'; + $details_box .= '
'.$priorities[$incidence['priority']].'
'; + $details_box .= '
'; + $details_box .= $nameIncidence; + $details_box .= '
'; + $details_box .= '
'; + + // People box. + $people_box = '
'; + $people_box .= '
'; + $people_box .= html_print_image('images/header_user_green.png', true, ['width' => '21']); + $people_box .= '
'; + $people_box .= '
'; + $people_box .= html_print_image('images/header_user_green.png', true, ['width' => '21']); + $people_box .= '
'; + $people_box .= '
'; + $people_box .= html_print_image('images/header_user_green.png', true, ['width' => '21']); + $people_box .= '
'; + + $people_box .= '
'.__('Created by').':
'; + $people_box .= '
'.__('Owned by').':
'; + $people_box .= '
'.__('Closed by').':
'; + + $people_box .= '
'; + $people_box .= (empty($incidence['idCreator']) === false) ? $users[$incidence['idCreator']]['fullName'] : '--'; + $people_box .= '
'; + $people_box .= '
'; + $people_box .= (empty($incidence['owner']) === false) ? $users[$incidence['owner']]['fullName'] : '--'; + $people_box .= '
'; + $people_box .= '
'; + $people_box .= (empty($incidence['closedBy']) === false) ? $users[$incidence['closedBy']]['fullName'] : '--'; + $people_box .= '
'; + $people_box .= '
'; + + // Dates box. + $dates_box = '
'; + $dates_box .= '
'; + $dates_box .= html_print_image('images/tick.png', true, ['class' => 'invert_filter']); + $dates_box .= '
'; + $dates_box .= '
'; + $dates_box .= html_print_image('images/update.png', true, ['width' => '21', 'class' => 'invert_filter']); + $dates_box .= '
'; + $dates_box .= '
'; + $dates_box .= html_print_image('images/mul.png', true, ['class' => 'invert_filter']); + $dates_box .= '
'; + + $dates_box .= '
'.__('Created at').':
'; + $dates_box .= '
'.__('Updated at').':
'; + $dates_box .= '
'.__('Closed at').':
'; + + $dates_box .= '
'.$incidence['startDate'].'
'; + $dates_box .= '
'.$incidence['updateDate'].'
'; + $dates_box .= '
'; + $dates_box .= (($incidence['closeDate'] === '0000-00-00 00:00:00') ? '--' : $incidence['closeDate']); + $dates_box .= '
'; + $dates_box .= '
'; + + // Show details, people and dates. + echo '
'; + ui_toggle( + $details_box, + __('Details'), + '', + 'details_box', + false, + false, + '', + 'ITSM_details_content white-box-content', + 'ITSM_details_shadow box-flat white_table_graph' + ); + ui_toggle( + $people_box, + __('People'), + '', + 'people_box', + false, + false, + '', + 'ITSM_details_content white-box-content', + 'ITSM_details_shadow box-flat white_table_graph' + ); + ui_toggle( + $dates_box, + __('Dates'), + '', + 'dates_box', + false, + false, + '', + 'ITSM_details_content white-box-content', + 'ITSM_details_shadow box-flat white_table_graph' + ); + echo '
'; + + // Show description. + $description_box = '
'; + $description_box .= str_replace("\r\n", '
', $incidence['description']); + $description_box .= '
'; + ui_toggle($description_box, __('Description'), '', '', false); + + if (empty($inventories) === false) { + $inventories_box = '
'; + $inventories_box .= '
    '; + foreach ($inventories as $inventory) { + $inventories_box .= '
  • '; + if (empty($inventory['idPandora']) === true) { + $inventories_box .= $inventory['name']; + } else { + $id_agent = explode('-', $inventory['idPandora'])[1]; + $url_agent = $config['homeurl']; + $url_agent .= 'index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente='.$id_agent; + $inventories_box .= ''; + $inventories_box .= $inventory['name']; + $inventories_box .= ''; + } + + $inventories_box .= '
  • '; + } + + $inventories_box .= '
'; + $inventories_box .= '
'; + ui_toggle($inventories_box, __('Related to inventory object'), '', '', false); + } + + // Files section table. + $table_files_section = new stdClass(); + $table_files_section->width = '100%'; + $table_files_section->id = 'files_section_table'; + $table_files_section->class = 'databox filters'; + $table_files_section->head = []; + + $table_files_section->data = []; + $table_files_section->size = []; + $table_files_section->size[0] = '20%'; + $table_files_section->size[1] = '60%'; + $table_files_section->size[2] = '20%'; + + $table_files_section->data[0][0] = '
'; + $table_files_section->data[0][0] .= '

'.__('File name').':

'; + $table_files_section->data[0][0] .= html_print_input_file('userfile', true, ['required' => true]); + $table_files_section->data[0][1] = '
'; + $table_files_section->data[0][1] .= '

'; + $table_files_section->data[0][1] .= __('Attachment description'); + $table_files_section->data[0][1] .= ':

'; + $table_files_section->data[0][1] .= html_print_textarea( + 'file_description', + 3, + 20, + '', + '', + true, + 'w100p' + ); + + $table_files_section->data[0][2] = '
'; + $table_files_section->data[0][2] .= html_print_submit_button( + __('Upload'), + 'accion', + false, + [ + 'icon' => 'wand', + 'mode' => 'mini secondary', + 'class' => 'right', + ], + true + ); + $table_files_section->data[0][2] .= '
'; + + // Files list table. + $table_files = new stdClass(); + $table_files->width = '100%'; + $table_files->class = 'info_table'; + $table_files->head = []; + + $table_files->head[0] = __('Filename'); + $table_files->head[1] = __('Timestamp'); + $table_files->head[2] = __('Description'); + $table_files->head[3] = __('User'); + $table_files->head[4] = __('Size'); + $table_files->head[5] = __('Delete'); + + $table_files->data = []; + + $url = \ui_get_full_url('index.php?sec=manageTickets&sec2=operation/ITSM/itsm'); + foreach ($files['data'] as $key => $file) { + $onClick = 'downloadIncidenceAttachment('.$file['idIncidence'].','.$file['idAttachment']; + $onClick .= ',\''.ui_get_full_url('ajax.php').'\',\''.$file['filename'].'\')'; + + $table_files->data[$key][0] = ''.$file['filename'].''; + $table_files->data[$key][1] = $file['timestamp']; + $table_files->data[$key][2] = $file['description']; + $table_files->data[$key][3] = $file['idUser']; + $table_files->data[$key][4] = $file['size']; + $urlDelete = $url.'&operation=detail&idIncidence='.$file['idIncidence'].'&idAttachment='.$file['idAttachment']; + $onclickDelete = 'javascript:if (!confirm(\''.__('Are you sure?').'\')) return false;'; + $table_files->data[$key][5] .= ''; + $table_files->data[$key][5] .= html_print_image( + 'images/delete.svg', + true, + [ + 'title' => __('Delete'), + 'class' => 'invert_filter main_menu_icon', + ] + ); + $table_files->data[$key][5] .= ''; + } + + $upload_file_form = '
'; + $upload_file_form .= ''; + $upload_file_form .= '

'.__('Add attachment').'

'; + $upload_file_form .= html_print_table($table_files_section, true); + $upload_file_form .= html_print_input_hidden('upload_file', true, true); + $upload_file_form .= '

'.__('Attached files').'

'; + $upload_file_form .= html_print_table($table_files, true); + $upload_file_form .= ''; + $upload_file_form .= '
'; + + echo '
'; + ui_toggle( + $upload_file_form, + __('Attached files'), + '', + '', + true, + false, + 'white-box-content', + 'w98p' + ); + echo '
'; + + // Comments section table. + $table_comments_section = new stdClass(); + $table_comments_section->width = '100%'; + $table_comments_section->id = 'files_section_table'; + $table_comments_section->class = 'databox filters'; + $table_comments_section->head = []; + $table_comments_section->size = []; + $table_comments_section->size[0] = '80%'; + $table_comments_section->size[1] = '20%'; + + $table_comments_section->data = []; + $table_comments_section->data[0][0] = '
'; + $table_comments_section->data[0][0] .= '

'; + $table_comments_section->data[0][0] .= __('Description'); + $table_comments_section->data[0][0] .= ':

'; + $table_comments_section->data[0][0] .= html_print_textarea( + 'comment_description', + 3, + 20, + '', + '', + true, + 'w100p' + ); + + $table_comments_section->data[0][1] = '
'; + $table_comments_section->data[0][1] .= html_print_submit_button( + __('Add'), + 'accion', + false, + [ + 'icon' => 'wand', + 'mode' => 'mini secondary', + 'class' => 'right', + ], + true + ); + $table_comments_section->data[0][1] .= '
'; + + // Comments list table. + $comment_table = ''; + if (empty($wus) === false) { + foreach ($wus['data'] as $wu) { + $comment_table .= '
'; + $comment_table .= $wu['idUser']; + $comment_table .= ' said '; + $comment_table .= $wu['timestamp']; + $comment_table .= ''; + $comment_table .= $wu['duration']; + $comment_table .= ' Hours'; + $comment_table .= '
'; + $comment_table .= '
'; + $comment_table .= $wu['description']; + $comment_table .= '
'; + } + } else { + $comment_table = __('No comments found'); + } + + $upload_comment_form = '
'; + $upload_comment_form .= '
'; + $upload_comment_form .= '

'.__('Add comment').'

'; + $upload_comment_form .= html_print_table($table_comments_section, true); + $upload_comment_form .= html_print_input_hidden('addComment', 1, true); + $upload_comment_form .= '
'; + $upload_comment_form .= '

'.__('Comments').'

'; + $upload_comment_form .= $comment_table; + $upload_comment_form .= '
'; + + echo '
'; + ui_toggle( + $upload_comment_form, + __('Comments'), + '', + '', + true, + false, + 'white-box-content', + 'w98p' + ); + echo '
'; +} diff --git a/pandora_console/views/ITSM/ITSMTicketEditView.php b/pandora_console/views/ITSM/ITSMTicketEditView.php new file mode 100644 index 0000000000..16c9825a98 --- /dev/null +++ b/pandora_console/views/ITSM/ITSMTicketEditView.php @@ -0,0 +1,302 @@ + 'index.php?sec=ITSM&sec2=operation/ITSM/itsm', + 'label' => __('ITSM'), + ], + [ + 'link' => 'index.php?sec=ITSM&sec2=operation/ITSM/itsm&operation=list', + 'label' => __('ITSM Tickets'), + ], + [ + 'link' => 'index.php?sec=ITSM&sec2=operation/ITSM/itsm&operation=edit', + 'label' => __('Edit'), + ], + ] +); + +if (empty($error) === false) { + ui_print_error_message($error); +} + +if (empty($successfullyMsg) === false) { + ui_print_success_message($successfullyMsg); +} + +// Main table. +$table = new stdClass(); +$table->width = '100%'; +$table->id = 'edit-ticket-itms'; +$table->class = 'databox filter-table-adv'; +$table->data = []; +$table->colspan[0][0] = 2; +$table->colspan[2][0] = 3; +$table->colspan[5][0] = 3; +$table->colspan[6][0] = 3; + +$table->data[0][0] = html_print_label_input_block( + __('Title'), + html_print_input_text( + 'title', + ($incidence['title'] ?? ''), + __('Name'), + 30, + 100, + true, + false, + true, + '', + 'w100p' + ) +); + +$ITSM_logo = 'images/pandoraITSM_logo_gray.png'; +if ($config['style'] === 'pandora_black' && is_metaconsole() === false) { + $ITSM_logo = 'images/pandoraITSM_logo.png'; +} + +$table->data[0][2] = '
'.html_print_image( + $ITSM_logo, + true, + ['style' => 'width: -webkit-fill-available;'], + false +).'
'; +$table->data[1][0] = html_print_label_input_block( + __('Type'), + html_print_select( + $objectTypes, + 'idIncidenceType', + ($incidence['idIncidenceType'] ?? ''), + '', + __('Select'), + 0, + true, + false, + true, + '', + false, + 'width: 100%;' + ) +); + +$table->data[1][1] = html_print_label_input_block( + __('Group'), + html_print_select( + $groups, + 'idGroup', + ($incidence['idGroup'] ?? ''), + '', + '', + 0, + true, + false, + true, + '', + false, + 'width: 100%;' + ) +); + +$table->data[1][2] = html_print_label_input_block( + __('Priority'), + html_print_select( + $priorities, + 'priority', + ($incidence['priority'] ?? 0), + '', + '', + 1, + true, + false, + true, + '', + false, + 'width: 100%;' + ) +); + +$table->data[2][0] = '
WIP...
'; + +$table->data[3][0] = html_print_label_input_block( + __('Status'), + html_print_select( + $status, + 'status', + ($incidence['status'] ?? 0), + '', + '', + 1, + true, + false, + true, + '', + false, + 'width: 100%;' + ) +); + +$table->data[3][1] = html_print_label_input_block( + __('Creator').ui_print_help_tip( + __('This field corresponds to the ITSM user specified in ITSM setup'), + true + ), + html_print_input_text( + 'idCreator', + '', + '', + 0, + 100, + true, + true, + false, + '', + 'w100p' + ) +); + +$table->data[3][2] = html_print_label_input_block( + __('Owner').ui_print_help_tip(__('Type at least two characters to search the user.'), true), + html_print_autocomplete_users_from_pandora_itsm( + 'owner', + ($incidence['owner'] ?? ''), + true, + 0, + false, + true, + 'w100p', + ) +); + +$table->data[4][0] = '' +); + +$table->data[5][0] = html_print_label_input_block( + __('Description').$help_macros, + html_print_textarea( + 'description', + 3, + 20, + ($incidence['description'] ?? ''), + '', + true + ) +); + +$formName = 'create_itsm_incident_form'; +$classForm = 'max_floating_element_size'; +$enctype = 'multipart/form-data'; +echo '
'; +html_print_table($table); +$buttons = ''; +if (empty($idIncidence) === true) { + $buttons .= html_print_input_hidden('create_incidence', 1, true); + $buttons .= html_print_submit_button( + __('Create'), + 'accion', + false, + [ 'icon' => 'next' ], + true + ); +} else { + $buttons .= html_print_input_hidden('update_incidence', 1, true); + $buttons .= html_print_input_hidden('idIncidence', $idIncidence, true); + $buttons .= html_print_submit_button( + __('Update'), + 'accion', + false, + [ 'icon' => 'upd' ], + true + ); +} + +html_print_action_buttons($buttons); + +echo '
'; + +ui_require_javascript_file('tinymce', 'vendor/tinymce/tinymce/'); +?> + + \ No newline at end of file diff --git a/pandora_console/views/ITSM/ITSMTicketListView.php b/pandora_console/views/ITSM/ITSMTicketListView.php new file mode 100644 index 0000000000..38457a6693 --- /dev/null +++ b/pandora_console/views/ITSM/ITSMTicketListView.php @@ -0,0 +1,170 @@ + 'index.php?sec=ITSM&sec2=operation/ITSM/itsm', + 'label' => __('ITSM'), + ], + [ + 'link' => 'index.php?sec=ITSM&sec2=operation/ITSM/itsm&operation=list', + 'label' => __('ITSM Tickets'), + ], + ] +); + +if (empty($error) === false) { + ui_print_error_message($error); +} + +if (empty($successfullyMsg) === false) { + ui_print_success_message($successfullyMsg); +} + +try { + $columns = [ + 'idIncidence', + 'title', + 'groupCompany', + 'statusResolution', + 'priority', + 'updateDate', + 'startDate', + 'idCreator', + 'owner', + 'operation', + ]; + + $column_names = [ + __('ID'), + __('Title'), + __('Group').'/'.__('Company'), + __('Status').'/'.__('Resolution'), + __('Priority'), + __('Updated'), + __('Started'), + __('Creator'), + __('Owner'), + [ + 'text' => __('Op.'), + 'class' => 'table_action_buttons w90px', + ], + ]; + + ui_print_datatable( + [ + 'id' => 'itms_list_tickets', + 'class' => 'info_table', + 'style' => 'width: 99%', + 'columns' => $columns, + 'column_names' => $column_names, + 'ajax_url' => $ajaxController, + 'ajax_data' => ['method' => 'getListTickets'], + 'no_sortable_columns' => [ + 2, + 3, + -1, + ], + 'order' => [ + 'field' => 'updateDate', + 'direction' => 'desc', + ], + 'search_button_class' => 'sub filter float-right', + 'form' => [ + 'inputs' => [ + [ + 'label' => __('Free search'), + 'type' => 'text', + 'id' => 'string', + 'name' => 'string', + ], + [ + 'label' => __('Status'), + 'type' => 'select', + 'name' => 'status', + 'fields' => $status, + 'nothing' => __('Any'), + 'nothing_value' => null, + ], + [ + 'label' => __('Priorities'), + 'type' => 'select', + 'name' => 'priority', + 'fields' => $priorities, + 'nothing' => __('Any'), + 'nothing_value' => null, + ], + [ + 'label' => __('Group'), + 'type' => 'select', + 'name' => 'idGroup', + 'fields' => $groups, + 'nothing' => __('Any'), + 'nothing_value' => null, + ], + [ + 'label' => __('Creation date'), + 'type' => 'interval', + 'name' => 'fromDate', + 'value' => 0, + 'nothing' => __('Any'), + 'nothing_value' => 0, + ], + ], + ], + 'filter_main_class' => 'box-flat white_table_graph fixed_filter_bar ', + ] + ); +} catch (Exception $e) { + echo $e->getMessage(); +} + +$input_button = '
'; +$input_button .= html_print_submit_button( + __('Create'), + '', + false, + ['icon' => 'next'], + true +); +$input_button .= '
'; + +html_print_action_buttons($input_button); diff --git a/pandora_console/views/cluster/edit.php b/pandora_console/views/cluster/edit.php index 03c9d27bcd..2c417b0f75 100644 --- a/pandora_console/views/cluster/edit.php +++ b/pandora_console/views/cluster/edit.php @@ -126,6 +126,9 @@ if (empty($form) === false) { $submit = $form['submit-external-input']; unset($form['submit-external-input']); + unset($bc[0]); + $wizard->printSteps($bc); + HTML::printForm($form, false, ($wizard->page < 6)); $buttons_input .= HTML::printInput($submit); } diff --git a/pandora_console/views/cluster/view.php b/pandora_console/views/cluster/view.php index af33475c4a..32bcdb0736 100644 --- a/pandora_console/views/cluster/view.php +++ b/pandora_console/views/cluster/view.php @@ -115,260 +115,17 @@ if ($critical === true) { return; } - -/* - * - * All this block has been retrieved from 'estado_generalagente.php' as - * described in issue #5755. - * - */ - - - -/* - * - * - * CLUSTER AGENT DETAILS. - * - */ - -// Prepare information for view. -$alive_animation = agents_get_status_animation( - agents_get_interval_status($cluster->agent()->toArray(), false) -); - - -$agent_name = ui_print_agent_name( - $cluster->agent()->id_agente(), - true, - 500, - 'font-size: medium;font-weight:bold', - true, - '', - '', - false, - false -); -$in_planned_downtime = db_get_sql( - 'SELECT executed FROM tplanned_downtime - INNER JOIN tplanned_downtime_agents - ON tplanned_downtime.id = tplanned_downtime_agents.id_downtime - WHERE tplanned_downtime_agents.id_agent = '.$cluster->agent()->id_agente().' AND tplanned_downtime.executed = 1' -); - -if ($cluster->agent()->disabled()) { - if ($in_planned_downtime) { - $agent_name = ''.$agent_name.ui_print_help_tip(__('Disabled'), true); - } else { - $agent_name = ''.$agent_name.''.ui_print_help_tip(__('Disabled'), true); - } -} else if ($cluster->agent()->quiet()) { - if ($in_planned_downtime) { - $agent_name = "".$agent_name.' '.html_print_image('images/dot_blue.png', true, ['border' => '0', 'title' => __('Quiet'), 'alt' => '']); - } else { - $agent_name = "".$agent_name.' '.html_print_image('images/dot_blue.png', true, ['border' => '0', 'title' => __('Quiet'), 'alt' => '']).''; - } -} else { - $agent_name = $agent_name; -} - -if ($in_planned_downtime && !$cluster->agent()->disabled() && !$cluster->agent()->quiet()) { - $agent_name .= ' '.ui_print_help_tip( - __('Agent in scheduled downtime'), - true, - 'images/minireloj-16.png' - ).''; -} else if (($in_planned_downtime && !$cluster->agent()->disabled()) - || ($in_planned_downtime && !$cluster->agent()->quiet()) -) { - $agent_name .= ' '.ui_print_help_tip( - __('Agent in scheduled downtime'), - true, - 'images/clock.svg' - ).''; -} - - -$table_agent_header = '
'; -$table_agent_header .= $agent_name; -$table_agent_header .= '
'; -$table_agent_header .= '
'; -if (!$config['show_group_name']) { - $table_agent_header .= ui_print_group_icon( - $cluster->agent()->id_grupo(), - true, - 'groups_small', - 'padding-right: 6px;' - ); -} - -$table_agent_header .= '
'; - -$status_img = agents_detail_view_status_img( - $cluster->agent()->critical_count(), - $cluster->agent()->warning_count(), - $cluster->agent()->unknown_count(), - $cluster->agent()->total_count(), - $cluster->agent()->notinit_count() -); - -$table_agent_header .= '
'.$status_img.'
'; -$table_agent_header .= '  '; -$table_agent_header .= ''.html_print_image( - 'images/force@svg.svg', - true, - [ - 'title' => __('Force cluster status calculation'), - 'alt' => '', - 'class' => 'main_menu_icon invert_filter', - - ] -).''; -// Fixed width non interactive charts. -$status_chart_width = 180; -$graph_width = 180; - -$table_agent_graph = '
'; -$table_agent_graph .= graph_agent_status( - $cluster->agent()->id_agente(), - $graph_width, - $graph_width, - true, - false, - false, - true -); -$table_agent_graph .= '
'; - -$table_agent_os = '

'.ui_print_os_icon( - $cluster->agent()->id_os(), - false, - true, - true, - false, - false, - false, - ['title' => __('OS').': '.get_os_name($cluster->agent()->id_os())] -); -$table_agent_os .= (empty($cluster->agent()->os_version()) === true) ? get_os_name((int) $cluster->agent()->id_os()) : $cluster->agent()->os_version().'

'; - - - -$addresses = agents_get_addresses($cluster->agent()->id_agente()); -$address = agents_get_address($cluster->agent()->id_agente()); - -foreach ($addresses as $k => $add) { - if ($add == $address) { - unset($addresses[$k]); - } -} - -if (empty($address) === false) { - $table_agent_ip = '

'.html_print_image( - 'images/web@groups.svg', - true, - [ - 'title' => __('IP address'), - 'class' => 'main_menu_icon invert_filter', - ] - ); - $table_agent_ip .= ''; - $table_agent_ip .= empty($address) ? ''.__('N/A').'' : $address; - $table_agent_ip .= '

'; -} - -$table_agent_description = '

'.html_print_image( - 'images/logs@svg.svg', - true, - [ - 'title' => __('Description'), - 'class' => 'main_menu_icon invert_filter', - ] -); -$table_agent_description .= ''; -$table_agent_description .= empty( - $cluster->description() -) ? ''.__('N/A').'' : $cluster->description(); -$table_agent_description .= '

'; - -$table_agent_count_modules = reporting_tiny_stats( - $cluster->agent()->toArray(), - true, - 'agent', - // Useless. - ':', - true -); - -$table_agent_version = '

'.html_print_image( - 'images/version.png', - true, - [ - 'title' => __('Agent Version'), - 'class' => 'invert_filter', - ] -); -$table_agent_version .= ''; -$table_agent_version .= empty($cluster->agent()->agent_version()) ? ''.__('Cluster agent').'' : $cluster->agent()->agent_version(); -$table_agent_version .= '

'; - -/* - * - * MAP - * - */ - -$nodes = $cluster->getNodes(); - -$font_size = 20; -$width = '45%'; -$height = '500'; -$node_radius = 40; - -// Generate map. -$map_manager = new NetworkMap( - [ - 'nodes' => $nodes, - 'no_pandora_node' => 1, - 'pure' => 1, - 'map_options' => [ - 'generation_method' => LAYOUT_SPRING1, - 'font_size' => $font_size, - 'node_radius' => $node_radius, - 'height' => $height, - 'width' => '100%', - 'tooltip' => true, - 'size_image' => 50, - 'z_dash' => 0.5, - 'map_filter' => [ - 'node_sep' => 7, - 'node_radius' => 50, - 'x_offs' => 130, - 'y_offs' => -70, - ], - ], - ] -); - - -/* - * - * EVENTS 24h - * - */ - -$table_events = '
'; -$table_events .= '
'; -$table_events .= ''; +$table_events = '
'; +$table_events .= '
'; +$table_events .= ''; $table_events .= __('Events (Last 24h)'); -$table_events .= ''; +$table_events .= ''; $table_events .= '
'; $table_events .= '
'; $table_events .= graph_graphic_agentevents( $cluster->agent()->id_agente(), 95, - 70, + 50, SECONDS_1DAY, '', true, @@ -378,53 +135,89 @@ $table_events .= graph_graphic_agentevents( $table_events .= '
'; $table_events .= '
'; -?> -
-
-
-
- -
-
-
- -
- -
-
-
- -
-
-
-
- -
-
-
-
- printMap(); ?> -
-
-
+$agentCountModules = html_print_div( + [ + 'class' => 'agent_details_bullets_cluster', + 'content' => reporting_tiny_stats( + $counters_bullet, + true, + 'modules', + // Useless. + ':', + true + ), + ], + true +); -
-'; + +$output .= '
'; +$output .= '
'; +$output .= get_resume_agent_status_header($cluster->agent()->toArray()); +$output .= '
'; +$output .= '
'; +$output .= '
'; +$output .= get_status_agent_chart_pie($cluster->agent()->id_agente(), 150, $counters_chart); +$output .= $agentCountModules; +$output .= '
'; +$output .= '
'; +$output .= '
'.__('Cluster Status').'
'; +$output .= '
'; +$output .= agents_detail_view_status_div( + $cluster->agent()->critical_count(), + $cluster->agent()->warning_count(), + $cluster->agent()->unknown_count(), + $cluster->agent()->total_count(), + $cluster->agent()->notinit_count() +); +$output .= '
'; +$output .= '
'; +$output .= '
'; +$output .= '
'; +$output .= $alive_animation; +$output .= '
'; +$output .= '
'.__('Cluster Mode').' : '.$cluster->getStringTypeName().'
'; +$output .= '
'.$cluster->name().'
'; +$output .= '
'; +$output .= '
'; +$output .= '
'; + +$output .= $table_events; + +$output .= '
'; + +$output .= '
'; +$output .= get_resume_agent_concat( + $cluster->agent()->id_agente(), + $allGroups, + $cluster->agent()->toArray() +); +$output .= '
'; + +$output .= '
'; +$output .= '
'; +echo $output; + +echo '
'; $id_agente = $cluster->agent()->id_agente(); +$id_cluster = $cluster->id(); +$agent = $cluster->agent()->toArray(); require_once $config['homedir'].'/operation/agentes/estado_monitores.php'; -?> -
+echo '
'; +require_once $config['homedir'].'/operation/agentes/alerts_status.php'; -url.'&op=view&id='.$cluster->id().'" method="POST">'; +$reload .= html_print_submit_button( __('Reload'), 'submit', false, @@ -434,12 +227,14 @@ $buttons[] = html_print_submit_button( ], true ); -echo '
'; +$reload .= '
'; + +$buttons[] = $reload; + +// Print always go back button. +$buttons[] = HTML::printForm($model->getGoBackForm(), true); + html_print_action_buttons( implode('', $buttons), ['type' => 'form_action'] ); -echo ''; - -// Print always go back button. -HTML::printForm($model->getGoBackForm(), false); diff --git a/pandora_server/DEBIAN/control b/pandora_server/DEBIAN/control index 3115722123..5cd86fd5b6 100644 --- a/pandora_server/DEBIAN/control +++ b/pandora_server/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-server -Version: 7.0NG.773.3-230921 +Version: 7.0NG.773.3-230928 Architecture: all Priority: optional Section: admin diff --git a/pandora_server/DEBIAN/make_deb_package.sh b/pandora_server/DEBIAN/make_deb_package.sh index bf7661fc06..3c1b457f85 100644 --- a/pandora_server/DEBIAN/make_deb_package.sh +++ b/pandora_server/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.773.3-230921" +pandora_version="7.0NG.773.3-230928" package_cpan=0 package_pandora=1 diff --git a/pandora_server/bin/pandora_server b/pandora_server/bin/pandora_server index b161bd57bb..eaf6f48968 100755 --- a/pandora_server/bin/pandora_server +++ b/pandora_server/bin/pandora_server @@ -551,6 +551,7 @@ sub pandora_server_tasks ($) { && !is_metaconsole($pa_config) && $counter % $pa_config->{'self_monitoring_interval'} == 0) { pandora_self_monitoring ($pa_config, $dbh); + pandora_installation_monitoring($pa_config, $dbh); } }; diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 1dbd0f3c96..f1a3490fa7 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -46,7 +46,7 @@ our @EXPORT = qw( # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.773.3"; -my $pandora_build = "230921"; +my $pandora_build = "230928"; our $VERSION = $pandora_version." ".$pandora_build; # Setup hash diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index e7ac485a1d..ed4e127ade 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -102,6 +102,10 @@ Exported Functions: =item * C +=item * C + +=item * C + =back =head1 METHODS @@ -130,7 +134,7 @@ use Math::Trig; # Math functions use constant ALERTSERVER => 21; # Debugging -#use Data::Dumper; +use Data::Dumper; # Force XML::Simple to use XML::Parser instead SAX to manage XML # due a bug processing some XML with blank spaces. @@ -248,6 +252,9 @@ our @EXPORT = qw( pandora_update_agent_alert_count pandora_update_agent_module_count pandora_update_config_token + pandora_get_custom_fields + pandora_get_agent_custom_field_data + pandora_get_custom_field_for_itsm pandora_update_agent_custom_field pandora_select_id_custom_field pandora_select_combo_custom_field @@ -262,9 +269,8 @@ our @EXPORT = qw( pandora_server_statistics pandora_self_monitoring pandora_thread_monitoring + pandora_installation_monitoring pandora_process_policy_queue - pandora_sync_agents_integria - pandora_get_integria_ticket_types subst_alert_macros subst_column_macros locate_agent @@ -568,6 +574,10 @@ sub pandora_evaluate_alert ($$$$$$$;$$$$) { my $schedule; if (defined($alert->{'schedule'}) && $alert->{'schedule'} ne '') { $schedule = PandoraFMS::Tools::p_decode_json($pa_config, $alert->{'schedule'}); + if (!defined($special_day)) { + $special_day = 0; + } + if ($special_day != 0) { return $status if (!defined($schedule->{$weeks[$special_day]})); } @@ -584,6 +594,10 @@ sub pandora_evaluate_alert ($$$$$$$;$$$$) { my $time = sprintf ("%.2d:%.2d:%.2d", $hour, $min, $sec); my $schedule_day; + if (!defined($special_day)) { + $special_day = 0; + } + if ($special_day != 0 && defined($schedule->{$weeks[$special_day]})) { $schedule_day = $weeks[$special_day]; } else { @@ -1359,6 +1373,27 @@ sub pandora_execute_action ($$$$$$$$$;$$) { $field20 = defined($action->{'field20_recovery'}) && $action->{'field20_recovery'} ne "" ? $action->{'field20_recovery'} : $field20; } + if ($clean_name eq "Pandora ITSM Ticket") { + # if action not defined, get values for config setup pandora ITSM. + if ($alert_mode == RECOVERED_ALERT) { + $field1 = defined($action->{'field1_recovery'}) && $action->{'field1_recovery'} ne "" ? $action->{'field1_recovery'} : pandora_get_tconfig_token($dbh, 'incident_title', ''); + $field2 = defined($action->{'field2_recovery'}) && $action->{'field2_recovery'} ne "" ? $action->{'field2_recovery'} : pandora_get_tconfig_token($dbh, 'default_group', '2'); + $field3 = defined($action->{'field3_recovery'}) && $action->{'field3_recovery'} ne "" ? $action->{'field3_recovery'} : pandora_get_tconfig_token($dbh, 'default_criticity', 'MEDIUM'); + $field4 = defined($action->{'field4_recovery'}) && $action->{'field4_recovery'} ne "" ? $action->{'field4_recovery'} : pandora_get_tconfig_token($dbh, 'default_owner', undef); + $field5 = defined($action->{'field5_recovery'}) && $action->{'field5_recovery'} ne "" ? $action->{'field5_recovery'} : pandora_get_tconfig_token($dbh, 'incident_type', undef); + $field6 = defined($action->{'field6_recovery'}) && $action->{'field6_recovery'} ne "" ? $action->{'field6_recovery'} : pandora_get_tconfig_token($dbh, 'incident_status', 'CLOSED'); + $field7 = defined($action->{'field7_recovery'}) && $action->{'field7_recovery'} ne "" ? $action->{'field7_recovery'} : pandora_get_tconfig_token($dbh, 'incident_content', ''); + } else { + $field1 = defined($action->{'field1'}) && $action->{'field1'} ne "" ? $action->{'field1'} : pandora_get_tconfig_token($dbh, 'incident_title', ''); + $field2 = defined($action->{'field2'}) && $action->{'field2'} ne "" ? $action->{'field2'} : pandora_get_tconfig_token($dbh, 'default_group', '2'); + $field3 = defined($action->{'field3'}) && $action->{'field3'} ne "" ? $action->{'field3'} : pandora_get_tconfig_token($dbh, 'default_criticity', 'MEDIUM'); + $field4 = defined($action->{'field4'}) && $action->{'field4'} ne "" ? $action->{'field4'} : pandora_get_tconfig_token($dbh, 'default_owner', undef); + $field5 = defined($action->{'field5'}) && $action->{'field5'} ne "" ? $action->{'field5'} : pandora_get_tconfig_token($dbh, 'incident_type', undef); + $field6 = defined($action->{'field6'}) && $action->{'field6'} ne "" ? $action->{'field6'} : pandora_get_tconfig_token($dbh, 'incident_status', 'NEW'); + $field7 = defined($action->{'field7'}) && $action->{'field7'} ne "" ? $action->{'field7'} : pandora_get_tconfig_token($dbh, 'incident_content', ''); + } + } + $field1 = defined($field1) && $field1 ne "" ? decode_entities($field1) : ""; $field2 = defined($field2) && $field2 ne "" ? decode_entities($field2) : ""; $field3 = defined($field3) && $field3 ne "" ? decode_entities($field3) : ""; @@ -1896,113 +1931,106 @@ sub pandora_execute_action ($$$$$$$$$;$$) { } } - # Integria IMS Ticket - } elsif ($clean_name eq "Integria IMS Ticket") { - my $config_integria_enabled = pandora_get_tconfig_token ($dbh, 'integria_enabled', ''); - - if (!$config_integria_enabled) { + # Pandora ITSM Ticket + } elsif ($clean_name eq "Pandora ITSM Ticket") { + my $config_ITSM_enabled = pandora_get_tconfig_token ($dbh, 'ITSM_enabled', ''); + if (!$config_ITSM_enabled) { return; } - my $config_api_path = pandora_get_tconfig_token ($dbh, 'integria_hostname', ''); - my $config_api_pass = pandora_get_tconfig_token ($dbh, 'integria_api_pass', ''); - my $config_integria_user = pandora_get_tconfig_token ($dbh, 'integria_user', ''); - my $config_integria_user_pass = pandora_get_tconfig_token ($dbh, 'integria_pass', ''); - $field1 = subst_alert_macros ($field1, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field2 = subst_alert_macros ($field2, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field3 = subst_alert_macros ($field3, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field4 = subst_alert_macros ($field4, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field5 = subst_alert_macros ($field5, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field6 = subst_alert_macros ($field6, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field7 = subst_alert_macros ($field7, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field8 = subst_alert_macros ($field8, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field9 = subst_alert_macros ($field9, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field10 = subst_alert_macros ($field10, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field11 = subst_alert_macros ($field11, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field12 = subst_alert_macros ($field12, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field13 = subst_alert_macros ($field13, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field14 = subst_alert_macros ($field14, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field15 = subst_alert_macros ($field15, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field16 = subst_alert_macros ($field16, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field17 = subst_alert_macros ($field17, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field18 = subst_alert_macros ($field18, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field19 = subst_alert_macros ($field19, \%macros, $pa_config, $dbh, $agent, $module, $alert); - $field20 = subst_alert_macros ($field20, \%macros, $pa_config, $dbh, $agent, $module, $alert); + my $ITSM_path = pandora_get_tconfig_token ($dbh, 'ITSM_hostname', ''); + my $ITSM_token = pandora_get_tconfig_token ($dbh, 'ITSM_token', ''); - # Field 1 (Integria IMS API path) - my $api_path = $config_api_path . "/include/api.php"; - - # Field 2 (Integria IMS API pass) - my $api_pass = $config_api_pass; - - # Field 3 (Integria IMS user) - my $integria_user = $config_integria_user; - - # Field 4 (Integria IMS user password) - my $integria_user_pass = $config_integria_user_pass; - - # Field 1 (Ticket name) - my $ticket_name = safe_output($field1); - if ($ticket_name eq "") { - $ticket_name = $pa_config->{'rb_product_name'} . " alert action created by API"; - } - - # Field 2 (Ticket group ID) - my $ticket_group_id = $field2; - if ($ticket_group_id eq '') { - $ticket_group_id = 0; - } - - # Field 3 (Ticket priority); - my $ticket_priority = $field3; - if ($ticket_priority eq '0') { - $ticket_priority = 1; - } - - # Field 4 (Ticket owner) - my $ticket_owner = $field4; - if ($ticket_owner eq '') { - $ticket_owner = 'admin'; - } - - # Field 5 (Ticket type) - my $ticket_type = $field5; - if ($ticket_type eq '') { - $ticket_type = 0; - } - - # Field 6 (Ticket status) - my $ticket_status = $field6; - if ($ticket_status eq '0') { - $ticket_status = 1; - } - - # Field 7 (Ticket description); - my $ticket_description = safe_output($field7); - - my $create_wu_on_close_recovery = 0; - - if ($alert_mode == RECOVERED_ALERT && $action->{'create_wu_integria'} == '1') { - $create_wu_on_close_recovery = 1; - } + # Ticket info. + my %incidence = ( + 'title' => subst_alert_macros ($field1, \%macros, $pa_config, $dbh, $agent, $module, $alert), + 'idGroup' => subst_alert_macros ($field2, \%macros, $pa_config, $dbh, $agent, $module, $alert), + 'priority' => subst_alert_macros ($field3, \%macros, $pa_config, $dbh, $agent, $module, $alert), + 'owner' => subst_alert_macros ($field4, \%macros, $pa_config, $dbh, $agent, $module, $alert), + 'idIncidenceType' => subst_alert_macros ($field5, \%macros, $pa_config, $dbh, $agent, $module, $alert), + 'status' => subst_alert_macros ($field6, \%macros, $pa_config, $dbh, $agent, $module, $alert), + 'description' => subst_alert_macros ($field7, \%macros, $pa_config, $dbh, $agent, $module, $alert) + ); # Ticket type custom fields - my $ticket_custom_field1 = $field8; - my $ticket_custom_field2 = $field9; - my $ticket_custom_field3 = $field10; - my $ticket_custom_field4 = $field11; - my $ticket_custom_field5 = $field12; - my $ticket_custom_field6 = $field13; - my $ticket_custom_field7 = $field14; - my $ticket_custom_field8 = $field15; - my $ticket_custom_field9 = $field16; - my $ticket_custom_field10 = $field17; - my $ticket_custom_field11 = $field18; - my $ticket_custom_field12 = $field19; - my $ticket_custom_field13 = $field20; + my %incidence_custom_fields = ( + 'field0' => $field8 ne "" ? subst_alert_macros(safe_output($field8), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field1' => $field9 ne "" ? subst_alert_macros(safe_output($field9), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field2' => $field10 ne "" ? subst_alert_macros(safe_output($field10), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field3' => $field11 ne "" ? subst_alert_macros(safe_output($field11), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field4' => $field12 ne "" ? subst_alert_macros(safe_output($field12), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field5' => $field13 ne "" ? subst_alert_macros(safe_output($field13), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field6' => $field14 ne "" ? subst_alert_macros(safe_output($field14), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field7' => $field15 ne "" ? subst_alert_macros(safe_output($field15), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field8' => $field16 ne "" ? subst_alert_macros(safe_output($field16), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field9' => $field17 ne "" ? subst_alert_macros(safe_output($field17), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field10' => $field18 ne "" ? subst_alert_macros(safe_output($field18), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field11' => $field19 ne "" ? subst_alert_macros(safe_output($field19), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef, + 'field12' => $field20 ne "" ? subst_alert_macros(safe_output($field20), \%macros, $pa_config, $dbh, $agent, $module, $alert) : undef + ); - pandora_create_integria_ticket($pa_config, $api_path, $api_pass, $integria_user, $integria_user_pass, $agent->{'nombre'}, $agent->{'alias'}, $agent->{'id_os'}, $agent->{'direccion'}, $agent->{'id_agente'}, $agent->{'id_grupo'}, $ticket_name, $ticket_group_id, $ticket_priority, $ticket_owner, $ticket_type, $ticket_status, $ticket_description, $create_wu_on_close_recovery, $ticket_custom_field1, $ticket_custom_field2, $ticket_custom_field3, $ticket_custom_field4, $ticket_custom_field5, $ticket_custom_field6, $ticket_custom_field7, $ticket_custom_field8, $ticket_custom_field9, $ticket_custom_field10, $ticket_custom_field11, $ticket_custom_field12, $ticket_custom_field13); + my $id_node = pandora_get_tconfig_token($dbh, 'metaconsole_node_id', 0); + my $external_id = $id_node . '-' . $module->{'id_agente'} . '-' . $module->{'id_agente_modulo'}; + # Extract custom field valid with data. + my $custom_fields_data = pandora_get_custom_field_for_itsm($dbh, $agent->{'id_agente'}); + + my %OS = ( + 'data' => safe_output(get_db_value($dbh, 'select name from tconfig_os where id_os = ?', $agent->{'id_os'})), + 'type' => 'text' + ); + + my %ip_address = ( + 'data' => safe_output($agent->{'direccion'}), + 'type' => 'text' + ); + + my %url_address = ( + 'data' => '["Agent", "' . safe_output($agent->{'url_address'} . '"]'), + 'type' => 'link' + ); + + my %id_agent = ( + 'data' => $agent->{'id_agente'}, + 'type' => 'numeric' + ); + + my %group = ( + 'data' => safe_output(get_db_value($dbh, 'select nombre from tgrupo where id_grupo = ?', $agent->{'id_grupo'})), + 'type' => 'text' + ); + + my %os_version = ( + 'data' => $agent->{'os_version'}, + 'type' => 'text' + ); + + my %inventory_custom_fields = ( + 'OS' => \%OS, + 'IP Address' => \%ip_address, + 'URL Address' => \%url_address, + 'ID Agent' => \%id_agent, + 'Group' => \%group, + 'OS Version' => \%os_version + ); + + my %dataSend = ( + 'incidence' => \%incidence, + 'incidenceCustomFields' => \%incidence_custom_fields, + 'inventoryCustomFields' => \%inventory_custom_fields, + 'idAgent' => $agent->{'id_agente'}, + 'idModule' => $module->{'id_agente_modulo'}, + 'idNode' => $id_node, + 'alertMode' => $alert_mode, + 'customFieldsData' => $custom_fields_data, + 'agentAlias' => safe_output($agent->{'alias'}), + 'createWu' => $action->{'create_wu_integria'} + ); + + my $response = pandora_API_ITSM_call($pa_config, 'post', $ITSM_path . '/pandorafms/alert', $ITSM_token, \%dataSend); + if (!defined($response)){ + return; + } # Generate notification } elsif ($clean_name eq "Generate Notification") { @@ -3887,6 +3915,78 @@ sub pandora_select_combo_custom_field ($$) { return $result->{'combo_values'}; } +########################################################################## +## Select custom field id by name tagent_custom_field +########################################################################## +sub pandora_get_custom_fields ($) { + my ($dbh) = @_; + + my @result = get_db_rows($dbh, 'select tagent_custom_fields.* FROM tagent_custom_fields'); + + return \@result; +} + +########################################################################## +## Get custom field and data for agent. +########################################################################## +sub pandora_get_agent_custom_field_data ($$) { + my ($dbh, $id_agent) = @_; + + my @result = get_db_rows($dbh, 'select tagent_custom_fields.id_field, tagent_custom_fields.name, tagent_custom_data.id_agent, tagent_custom_data.description, tagent_custom_fields.is_password_type, tagent_custom_fields.is_link_enabled from tagent_custom_fields INNER JOIN tagent_custom_data ON tagent_custom_data.id_field = tagent_custom_fields.id_field where tagent_custom_data.id_agent = ?', $id_agent); + + return \@result; +} + +########################################################################## +## Get custom field and data for agent. +########################################################################## +sub pandora_get_custom_field_for_itsm ($$) { + my ($dbh, $id_agent) = @_; + my $custom_fields = pandora_get_custom_fields($dbh); + + my $agent_custom_field_data = pandora_get_agent_custom_field_data($dbh,$id_agent); + my %agent_custom_field_data_reducer = (); + + foreach my $data (@{$agent_custom_field_data}) { + my $array_data = pandora_check_type_custom_field_for_itsm($data); + $agent_custom_field_data_reducer{$data->{'name'}} = $array_data; + } + + my %result = (); + foreach my $custom_field (@{$custom_fields}) { + if($agent_custom_field_data_reducer{$custom_field->{'name'}}) { + $result{safe_output($custom_field->{'name'})} = $agent_custom_field_data_reducer{$custom_field->{'name'}}; + } else { + $result{safe_output($custom_field->{'name'})} = pandora_check_type_custom_field_for_itsm($custom_field); + } + } + + return \%result; +} + +########################################################################## +## Check type custom field and data for agent. +########################################################################## +sub pandora_check_type_custom_field_for_itsm ($) { + my ($data) = @_; + + my $type = 'text'; + if ($data->{'is_password_type'}) { + $type = 'password'; + } elsif ($data->{'is_link_enabled'}) { + $type = 'link'; + } else { + $type = 'text'; + } + + my %data_type = ( + 'data' => safe_output($data->{'description'}), + 'type' => $type + ); + + return \%data_type; +} + ########################################################################## ## Update a custom field from agent of tagent_custom_data ########################################################################## @@ -6158,6 +6258,13 @@ sub pandora_self_monitoring ($$) { my $free_disk_spool = disk_free ($pa_config->{"incomingdir"}); $free_disk_spool = '' unless defined ($free_disk_spool); my $my_data_server = get_db_value ($dbh, "SELECT id_server FROM tserver WHERE server_type = ? AND name = '".$pa_config->{"servername"}."'", DATASERVER); + my $total_mem = total_mem(); + my $free_mem_percentage; + if(defined($total_mem) && $free_mem ne '') { + $free_mem_percentage = ($free_mem / $total_mem ) * 100; + } else { + $free_mem_percentage = ''; + } # Number of unknown agents my $agents_unknown = 0; @@ -6199,9 +6306,38 @@ sub pandora_self_monitoring ($$) { $pandoradb = 1; } - my $elasticsearch_perfomance = enterprise_hook("elasticsearch_performance", [$pa_config, $dbh]); + my $num_threads = 0; + $num_threads = get_db_value ($dbh, "SELECT SUM(threads) FROM tserver WHERE name = '".$pa_config->{"servername"}."'"); + my $cpu_load = 0; + $cpu_load = cpu_load(); + + + ## Modules Networks average. + my $totalNetworkModules = get_db_value( + $dbh, + 'SELECT count(*) + FROM tagente_modulo + WHERE id_tipo_modulo + BETWEEN 6 AND 18' + ); + + my $totalModuleIntervalTime = get_db_value( + $dbh, + 'SELECT SUM(module_interval) + FROM tagente_modulo + WHERE id_tipo_modulo + BETWEEN 6 AND 18' + ); + + my $data_in_files = count_files_ext($pa_config->{"incomingdir"}, 'data'); + my $data_in_files_badxml = count_files_ext($pa_config->{"incomingdir"}, 'data_BADXML'); + my $averageTime = 0; + + if (defined($totalModuleIntervalTime) && defined($totalNetworkModules)) { + $averageTime = $totalNetworkModules / $totalModuleIntervalTime; + } + - $xml_output .= $elasticsearch_perfomance if defined($elasticsearch_perfomance); $xml_output .=" "; $xml_output .=" Database Maintenance"; @@ -6248,7 +6384,14 @@ sub pandora_self_monitoring ($$) { $xml_output .=" $free_mem"; $xml_output .=" "; } - + + $xml_output .=" "; + $xml_output .=" Free_RAM_perccentage"; + $xml_output .=" generic_data"; + $xml_output .=" $free_mem_percentage"; + $xml_output .=" %"; + $xml_output .=" "; + if (defined($free_disk_spool)) { $xml_output .=" "; $xml_output .=" FreeDisk_SpoolDir"; @@ -6257,6 +6400,43 @@ sub pandora_self_monitoring ($$) { $xml_output .=" "; } + $xml_output .=" "; + $xml_output .=" Total Threads"; + $xml_output .=" generic_data"; + $xml_output .=" $num_threads"; + $xml_output .=" "; + + $xml_output .=" "; + $xml_output .=" CPU Load"; + $xml_output .=" generic_data"; + $xml_output .=" $cpu_load"; + $xml_output .=" %"; + $xml_output .=" "; + + $xml_output .=" "; + $xml_output .=" Network Modules Int AVG"; + $xml_output .=" generic_data"; + $xml_output .=" $averageTime"; + $xml_output .=" seconds"; + $xml_output .=" "; + + if(defined($data_in_files)) { + $xml_output .=" "; + $xml_output .=" Data_in_files"; + $xml_output .=" generic_data"; + $xml_output .=" $data_in_files"; + $xml_output .=" "; + } + + if(defined($data_in_files_badxml)) { + $xml_output .=" "; + $xml_output .=" Data_in_BADXML_files"; + $xml_output .=" generic_data"; + $xml_output .=" $data_in_files_badxml"; + $xml_output .=" "; + } + + $xml_output .= ""; my $filename = $pa_config->{"incomingdir"}."/".$pa_config->{'servername'}.".self.".$utimestamp.".data"; @@ -6280,15 +6460,21 @@ sub pandora_thread_monitoring ($$$) { my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime()); my $xml_output = ""; - + my $module_parent = ""; + + # All trhead modules are "Status" module sons. + $module_parent = 'Status'; + $xml_output = "{'version'} . "' agent_name='".$pa_config->{'servername'} . "' agent_alias='".$pa_config->{'servername'} . "' interval='".$pa_config->{"self_monitoring_interval"}."' timestamp='".$timestamp."' >"; foreach my $server (@{$servers}) { - while (my ($tid, $stats) = each(%{$server->getProducerStats()})) { + my $producer_stats = $server->getProducerStats(); + while (my ($tid, $stats) = each(%{$producer_stats})) { $xml_output .=" "; $xml_output .=" " . uc($ServerTypes[$server->{'_server_type'}]) . " Producer Status"; $xml_output .=" generic_proc"; $xml_output .=" System"; $xml_output .=" " . (time() - $stats->{'tstamp'} < 2 * $pa_config->{"self_monitoring_interval"} ? 1 : 0) . ""; + $xml_output .=" " . $module_parent . ""; $xml_output .=" "; $xml_output .=" "; @@ -6297,6 +6483,16 @@ sub pandora_thread_monitoring ($$$) { $xml_output .=" Performance"; $xml_output .=" " . $stats->{'rate'} . ""; $xml_output .=" tasks/second"; + $xml_output .=" " . $module_parent . ""; + $xml_output .=" "; + + $xml_output .=" "; + $xml_output .=" " . uc($ServerTypes[$server->{'_server_type'}]) . " Producer Queued Elements"; + $xml_output .=" generic_data"; + $xml_output .=" Performance"; + $xml_output .=" " . ($#{$stats->{'task_queue'}} + 1) . ""; + $xml_output .=" tasks"; + $xml_output .=" " . $module_parent . ""; $xml_output .=" "; } @@ -6311,6 +6507,7 @@ sub pandora_thread_monitoring ($$$) { $xml_output .=" generic_proc"; $xml_output .=" System"; $xml_output .=" " . (time() - $stats->{'tstamp'} < 2 * $pa_config->{"self_monitoring_interval"} ? 1 : 0) . ""; + $xml_output .=" " . $module_parent . ""; $xml_output .=" "; $xml_output .=" "; @@ -6318,8 +6515,18 @@ sub pandora_thread_monitoring ($$$) { $xml_output .=" generic_data"; $xml_output .=" Performance"; $xml_output .=" " . $stats->{'rate'} . ""; + $xml_output .=" " . $module_parent . ""; $xml_output .=" tasks/second"; $xml_output .=" "; + + $xml_output .=" "; + $xml_output .=" " . uc($ServerTypes[$server->{'_server_type'}]) . " Producer Queued Elements"; + $xml_output .=" generic_data"; + $xml_output .=" Performance"; + $xml_output .=" " . ($#{$stats->{'task_queue'}} + 1) . ""; + $xml_output .=" tasks"; + $xml_output .=" " . $module_parent . ""; + $xml_output .=" "; } } $xml_output .= ""; @@ -6330,6 +6537,358 @@ sub pandora_thread_monitoring ($$$) { close (XMLFILE); } +########################################################################## +=head2 C<< pandora_installation_monitoring (I<$pa_config>, I<$dbh>, I<$servers>) >> + +Generate stats for Pandora FMS threads. + +=cut +########################################################################## +sub pandora_installation_monitoring($$) { + my ($pa_config, $dbh) = @_; + + my $utimestamp = time (); + my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime()); + my @modules; + + my $xml_output = ""; + $xml_output = "{'version'} . "' agent_name='pandora.internals' agent_alias='pandora.internals' interval='".$pa_config->{"self_monitoring_interval"}."' timestamp='".$timestamp."' >"; + + # Total amount of agents + my $module; + $module->{'name'} = "total_agents"; + $module->{'description'} = 'Total amount of agents'; + $module->{'data'} = get_db_value($dbh, 'SELECT COUNT(DISTINCT(id_agente)) FROM tagente'); + push(@modules, $module); + undef $module; + + # Total amount of modules + $module->{'name'} = "total_modules"; + $module->{'description'} = 'Total modules'; + $module->{'data'} = get_db_value($dbh, 'SELECT COUNT(DISTINCT(id_agente_modulo)) FROM tagente_modulo'); + push(@modules, $module); + undef $module; + + # Total groups + $module->{'name'} = "total_groups"; + $module->{'description'} = 'Total groups'; + $module->{'data'} = get_db_value($dbh, 'SELECT COUNT(DISTINCT(id_grupo)) FROM tgrupo'); + push(@modules, $module); + undef $module; + + # Total module data records + $module->{'name'} = "total_data"; + $module->{'description'} = 'Total module data records'; + $module->{'data'} = get_db_value($dbh, 'SELECT COUNT(id_agente_modulo) FROM tagente_datos'); + $module->{'module_interval'} = '288'; + push(@modules, $module); + undef $module; + + # Total module strimg data records + $module->{'name'} = "total_string_data"; + $module->{'description'} = 'Total module string data records'; + $module->{'data'} = get_db_value($dbh, 'SELECT COUNT(id_agente_modulo) FROM tagente_datos_string'); + $module->{'module_interval'} = '288'; + push(@modules, $module); + undef $module; + + # Total agent access record + $module->{'name'} = "total_access_data"; + $module->{'description'} = 'Total agent access records'; + $module->{'data'} = get_db_value($dbh, 'SELECT COUNT(id_agent) FROM tagent_access'); + push(@modules, $module); + undef $module; + + # Total users + $module->{'name'} = "total_users"; + $module->{'description'} = 'Total users'; + $module->{'data'} = get_db_value($dbh, 'SELECT COUNT(id_user) FROM tusuario'); + push(@modules, $module); + undef $module; + + # Total sessions + $module->{'name'} = "total_sessions"; + $module->{'description'} = 'Total sessions'; + $module->{'data'} = get_db_value($dbh, 'SELECT COUNT(id_session) FROM tsessions_php'); + push(@modules, $module); + undef $module; + + # Total unknown agents + $module->{'name'} = "total_unknown"; + $module->{'description'} = 'Total unknown agents'; + $module->{'data'} = get_db_value ( + $dbh, + "SELECT COUNT(DISTINCT tagente_estado.id_agente) + FROM tagente_estado, tagente, tagente_modulo + WHERE tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente + AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo + AND tagente_modulo.disabled = 0 + AND estado = 3" + ); + push(@modules, $module); + undef $module; + + # Total notinit modules + $module->{'name'} = "total_notinit"; + $module->{'description'} = 'Total not init modules'; + $module->{'data'} = get_db_value($dbh, "SELECT COUNT(DISTINCT(id_agente_modulo)) FROM tagente_estado WHERE estado = 4"); + push(@modules, $module); + undef $module; + + # Tables fragmentation + $module->{'name'} = "table_fragmentation"; + $module->{'description'} = 'Tables fragmentation'; + $module->{'data'} = get_db_value( + $dbh, + "SELECT + MAX( (data_free / data_length) / 100) AS frag_percent_max + FROM + information_schema.tables + WHERE + table_schema not in ('information_schema', 'mysql') + AND table_name NOT IN ('tagent_access, tevento')" + ); + $module->{'unit'} = '%'; + push(@modules, $module); + undef $module; + + # License Usage + $module->{'name'} = "license_usage"; + $module->{'description'} = 'License Usage'; + $module->{'unit'} = '%'; + my $license_usage = enterprise_hook('get_license_usage',[$dbh]); + if(! defined($license_usage)) { + $module->{'data'} = 0; + } else { + $module->{'data'} = $license_usage; + } + push(@modules, $module); + undef $module; + + # General info about queries + my $select = get_db_single_row($dbh, 'SHOW /*!50000 GLOBAL */ STATUS WHERE Variable_name= ?', 'Com_select'); + my $insert = get_db_single_row($dbh, 'SHOW /*!50000 GLOBAL */ STATUS WHERE Variable_name= ?', 'Com_insert'); + my $update = get_db_single_row($dbh, 'SHOW /*!50000 GLOBAL */ STATUS WHERE Variable_name= ?', 'Com_update'); + my $replace = get_db_single_row($dbh, 'SHOW /*!50000 GLOBAL */ STATUS WHERE Variable_name= ?', 'Com_replace'); + my $delete = get_db_single_row($dbh, 'SHOW /*!50000 GLOBAL */ STATUS WHERE Variable_name= ?', 'Com_delete'); + my $data_size = get_db_value($dbh, 'SELECT SUM(data_length)/(1024*1024) FROM information_schema.TABLES'); + my $index_size = get_db_value($dbh, 'SELECT SUM(index_length)/(1024*1024) FROM information_schema.TABLES'); + my $writes = $insert->{'Value'} + $update->{'Value'} + $replace->{'Value'} + $delete->{'Value'} ; + + # Mysql Questions - Reads + $module->{'name'} = "mysql_questions_reads"; + $module->{'description'} = 'MySQL: Questions - Reads (#): Number of read questions'; + $module->{'data'} = $select->{'Value'}; + $module->{'unit'} = 'qu'; + push(@modules, $module); + undef $module; + + # Mysql Questions - Writes + my $question_writes = 0; + if(($writes + $select) > 0) { + $question_writes = (($writes * 10000) / ($select + $writes)) / 100; + } + $module->{'name'} = "mysql_questions_writes"; + $module->{'description'} = 'MySQL: Questions - Writes (#): Number of writed questions'; + $module->{'data'} = $question_writes; + $module->{'unit'} = 'qu'; + push(@modules, $module); + undef $module; + + # Mysql Size of data + $module->{'name'} = "mysql_size_of_data"; + $module->{'description'} = 'MySQL: Size of data (MB): Size of stored data in megabytes'; + $module->{'data'} = $data_size; + $module->{'unit'} = 'MB'; + push(@modules, $module); + undef $module; + + # Mysql Size of indexed + $module->{'name'} = "mysql_size_of_indexes"; + $module->{'description'} = 'Size of indexes (MB): Size of stored indexes in megabytes'; + $module->{'data'} = $index_size; + $module->{'unit'} = 'MB'; + push(@modules, $module); + undef $module; + + # Mysql process list + my $command = 'mysql -u '.$pa_config->{'dbuser'}.' -p"'.$pa_config->{'dbpass'}.'" -e "show processlist"'; + my $process_list = `$command 2>$DEVNULL`; + $module->{'name'} = 'mysql_transactions_list'; + $module->{'description'} = 'MySQL: Transactions list'; + $module->{'data'} = ''; + $module->{'type'} = 'generic_data_string'; + push(@modules, $module); + undef $module; + + # Log monitoring + my $log_files = { + 'server_log' => $pa_config->{'log_file'}, + 'server_error' => $pa_config->{'errorlog_file'}, + }; + + if(pandora_get_tconfig_token($dbh,'console_log_enabled', 0) == 1) { + $log_files->{'console_log'} = '/var/www/html/pandora_consle/log/console.log'; + } + + if(pandora_get_tconfig_token($dbh,'audit_log_enabled', 0) == 1) { + $log_files->{'audit_log'} = '/var/www/html/pandora_consle/log/audit.log'; + } + + foreach my $log_source (keys %{$log_files}) { + my $log_name = $log_source ; + my $size = -s $log_files->{$log_source}; + my $size_in_mb; + + if(defined($size) && $size != 0) { + $size_in_mb = $size / (1024 * 1024); + } else { + $size_in_mb = 0; + } + + $module->{'name'} = $log_name.'_size'; + $module->{'description'} = 'Size of '.$log_name.' (MB): Size of '.$log_name.' in megabytes'; + $module->{'data'} = $size_in_mb; + $module->{'unit'} = 'MB'; + $module->{'min_critical'} = 1024; + $module->{'max_critical'} = 0; + push(@modules, $module); + undef $module; + + # Alert monitoring + # Defined alerts + my $total_alerts = get_db_value( + $dbh, + 'SELECT COUNT(id) FROM talert_template_modules WHERE disabled = 0 AND standby = 0 AND disabled_by_downtime = 0' + ); + $module->{'name'} = "defined_alerts"; + $module->{'description'} = 'Number of defined (and active) alerts'; + $module->{'data'} = $total_alerts; + push(@modules, $module); + undef $module; + + # Defined correlative alerts + my $total_correlative_alerts = get_db_value( + $dbh, + 'SELECT COUNT(id) FROM tevent_alert WHERE disabled = 0 AND standby = 0' + ); + $module->{'name'} = "defined_correlative_alerts"; + $module->{'description'} = 'Number of defined correlative alerts'; + $module->{'data'} = $total_alerts; + push(@modules, $module); + undef $module; + + # Alertas disparadas actualmente. + my $triggered_alerts = get_db_value( + $dbh, + 'SELECT COUNT(id) FROM talert_template_modules WHERE times_fired != 0 AND disabled = 0 AND standby = 0 AND disabled_by_downtime = 0' + ); + $module->{'name'} = "triggered_alerts"; + $module->{'description'} = 'Number of active alerts'; + $module->{'data'} = $triggered_alerts; + push(@modules, $module); + undef $module; + + # Alertas correladivas activas + my $triggered_correlative_alerts = get_db_value( + $dbh, + 'SELECT COUNT(id) FROM tevent_alert WHERE times_fired != 0 AND disabled = 0 AND standby = 0' + ); + $module->{'name'} = "triggered_correlative_alerts"; + $module->{'description'} = 'Number of active correlative alerts'; + $module->{'data'} = $triggered_correlative_alerts; + push(@modules, $module); + undef $module; + + + # Last 24 hours triggered alerts. + my $triggered_alerts_24h = get_db_value( + $dbh, + 'SELECT COUNT(id) + FROM talert_template_modules + WHERE last_fired >=UNIX_TIMESTAMP(NOW() - INTERVAL 1 DAY)' + ); + $module->{'name'} = "triggered_alerts_24h"; + $module->{'description'} = 'Last 24h triggered alerts'; + $module->{'data'} = $triggered_alerts_24h; + push(@modules, $module); + undef $module; + + my $triggered_correlative_alerts_24h = get_db_value( + $dbh, + 'SELECT COUNT(id) + FROM tevent_alert + WHERE last_fired >=UNIX_TIMESTAMP(NOW() - INTERVAL 1 DAY)' + ); + $module->{'name'} = "triggered_correlative_alerts_24h"; + $module->{'description'} = 'Last 24h triggered correlative alerts'; + $module->{'data'} = $triggered_correlative_alerts_24h; + push(@modules, $module); + undef $module; + + } + + foreach my $module_data (@modules) { + $xml_output .=" "; + $xml_output .=" " .$module_data->{'name'}. ""; + $xml_output .=" " . $module_data->{'data'} . ""; + + if(defined($module_data->{'description'})) { + $xml_output .=" " .$module_data->{'description'}. ""; + } + if(defined($module_data->{'type'})) { + $xml_output .=" " .$module_data->{'type'}. ""; + } else { + $xml_output .=" generic_data"; + } + if(defined($module_data->{'unit'})) { + $xml_output .=" " .$module_data->{'unit'}. ""; + } + if(defined($module_data->{'module_parent'})) { + $xml_output .=" " .$module_data->{'module_parent'}. ""; + } + if(defined($module_data->{'module_interval'})) { + $xml_output .=" " .$module_data->{'module_interval'}. ""; + } + if(defined($module_data->{'max_critical'})) { + $xml_output .=" " .$module_data->{'max_critical'}. ""; + } + if(defined($module_data->{'min_critical'})) { + $xml_output .=" " .$module_data->{'min_critical'}. ""; + } + if(defined($module_data->{'max_warning'})) { + $xml_output .=" " .$module_data->{'max_warning'}. ""; + } + if(defined($module_data->{'min_warning'})) { + $xml_output .=" " .$module_data->{'min_warning'}. ""; + } + if(defined($module_data->{'module_group'})) { + $xml_output .=" " .$module_data->{'module_group'}. ""; + } + + $xml_output .=" "; + } + + # Opensearch monitoring + my $elasticsearch_perfomance = enterprise_hook("elasticsearch_performance", [$pa_config, $dbh]); + $xml_output .= $elasticsearch_perfomance if defined($elasticsearch_perfomance); + + # SNMPTrapd monitoting + my $snmp_traps_monitoring = snmp_traps_monitoring($pa_config, $dbh); + $xml_output .= $snmp_traps_monitoring if defined($snmp_traps_monitoring); + + # Wux nobitoring + my $wux_performance = enterprise_hook("wux_performance", [$pa_config, $dbh]); + $xml_output .= $wux_performance if defined($wux_performance); + + $xml_output .= ""; + + my $filename = $pa_config->{"incomingdir"}."/pandora.internals.".$utimestamp.".data"; + open (XMLFILE, ">", $filename) or die "[FATAL] Could not write to the thread monitoring XML file '$filename'"; + print XMLFILE $xml_output; + close (XMLFILE); +} + ########################################################################## =head2 C<< set_master (I<$pa_config>, I<$dbh>) >> @@ -7038,152 +7597,18 @@ sub pandora_edit_custom_graph ($$$$$$$$$$$) { return $res; } -sub pandora_create_integria_ticket ($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$) { - my ($pa_config,$api_path,$api_pass,$integria_user,$user_pass,$agent_name,$agent_alias,$agent_os,$agent_addr,$agent_id,$agent_group,$ticket_name,$ticket_group_id,$ticket_priority,$ticket_owner,$ticket_type,$ticket_status,$ticket_description, $create_wu_on_close_recovery, $ticket_custom_field1, $ticket_custom_field2, $ticket_custom_field3, $ticket_custom_field4, $ticket_custom_field5, $ticket_custom_field6, $ticket_custom_field7, $ticket_custom_field8, $ticket_custom_field9, $ticket_custom_field10, $ticket_custom_field11, $ticket_custom_field12, $ticket_custom_field13) = @_; - - use URI::URL; - use URI::Escape; - use HTML::Entities; - - my $data_ticket; - my $call_api; - - my $uri = URI->new($api_path); - - if ($uri->scheme eq "") { - $api_path = "http://" . $api_path; +sub pandora_API_ITSM_call ($$$$$) { + my ($pa_config, $method, $ITSM_path, $ITSM_token, $data) = @_; + my @headers = ( + 'accept' => 'application/json', + 'Content-Type' => 'application/json; charset=utf-8', + 'Authorization' => 'Bearer ' . $ITSM_token, + ); + if($method =~/put/i) { + return api_call($pa_config, $method, $ITSM_path, encode_utf8(p_encode_json($pa_config, $data)), @headers); + } else { + return api_call($pa_config, $method, $ITSM_path, Content => encode_utf8(p_encode_json($pa_config, $data)), @headers); } - - my $ticket_create_wu = 0; - - if ($create_wu_on_close_recovery == 1 && $ticket_status eq '7') { - $ticket_create_wu = 1; - } - - $data_ticket = $agent_name . - "|;|" . uri_escape(decode_entities($agent_alias)) . - "|;|" . $agent_os . - "|;|" . $agent_addr . - "|;|" . $agent_id . - "|;|" . $agent_group . - "|;|" . $ticket_name . - "|;|" . $ticket_group_id . - "|;|" . $ticket_priority . - "|;|" . $ticket_description . - "|;|" . $ticket_type . - "|;|" . $ticket_owner . - "|;|" . $ticket_status . - "|;|" . $ticket_create_wu . - "|;|" . $ticket_custom_field1 . - "|;|" . $ticket_custom_field2 . - "|;|" . $ticket_custom_field3 . - "|;|" . $ticket_custom_field4 . - "|;|" . $ticket_custom_field5 . - "|;|" . $ticket_custom_field6 . - "|;|" . $ticket_custom_field7 . - "|;|" . $ticket_custom_field8 . - "|;|" . $ticket_custom_field9 . - "|;|" . $ticket_custom_field10 . - "|;|" . $ticket_custom_field11 . - "|;|" . $ticket_custom_field12 . - "|;|" . $ticket_custom_field13; - - $call_api = $api_path . '?' . - 'user=' . $integria_user . '&' . - 'user_pass=' . $user_pass . '&' . - 'pass=' . $api_pass . '&' . - 'op=create_pandora_ticket&' . - 'params=' . $data_ticket .'&' . - 'token=|;|'; - - my $content = get($call_api); - - if (is_numeric($content) && $content ne "-1") { - return $content; - } - else { - return 0; - } -} - -sub pandora_sync_agents_integria ($) { - my ($dbh) = @_; - - my $config_integria_enabled = pandora_get_tconfig_token ($dbh, 'integria_enabled', ''); - - if (!$config_integria_enabled) { - return; - } - - my $config_api_path = pandora_get_tconfig_token ($dbh, 'integria_hostname', ''); - my $config_api_pass = pandora_get_tconfig_token ($dbh, 'integria_api_pass', ''); - my $config_integria_user = pandora_get_tconfig_token ($dbh, 'integria_user', ''); - my $config_integria_user_pass = pandora_get_tconfig_token ($dbh, 'integria_pass', ''); - - my $api_path = $config_api_path . "/include/api.php"; - - my @agents_string = ''; - my @agents = get_db_rows ($dbh, 'SELECT * FROM tagente'); - - my @agents_array = (); - my $agents_string = ''; - - foreach my $agent (@agents) { - push @agents_array, $agent->{'nombre'} . - "|;|" . - $agent->{'alias'} . - "|;|" . - $agent->{'id_os'} . - "|;|" . - $agent->{'direccion'} . - "|;|" . - $agent->{'id_grupo'}; - } - - my $ua = LWP::UserAgent->new(); - my $response = $ua->post( $api_path, { - 'user' => $config_integria_user, - 'user_pass' => $config_integria_user_pass, - 'pass' => $config_api_pass, - 'op' => 'sync_pandora_agents_inventory', - 'params[]' => [@agents_array], - 'token' => '|;|' - }); - - my $content = $response->decoded_content(); - - if (defined $content && is_numeric($content) && $content ne "-1") { - return $content; - } - else { - return 0; - } -} - -sub pandora_get_integria_ticket_types($) { - my ($dbh) = @_; - - my $config_api_path = pandora_get_tconfig_token ($dbh, 'integria_hostname', ''); - my $config_api_pass = pandora_get_tconfig_token ($dbh, 'integria_api_pass', ''); - my $config_integria_user = pandora_get_tconfig_token ($dbh, 'integria_user', ''); - my $config_integria_user_pass = pandora_get_tconfig_token ($dbh, 'integria_pass', ''); - - my $api_path = $config_api_path . "/include/api.php"; - - my $call_api = $api_path . '?' . - 'user=' . $config_integria_user . '&' . - 'user_pass=' . $config_integria_user_pass . '&' . - 'pass=' . $config_api_pass . '&' . - 'op=get_types&' . - 'return_type=json'; - - my $content = get($call_api); - - my @decoded_json; - @decoded_json = @{decode_json($content)} if (defined $content && $content ne ""); - - return @decoded_json; - } ########################################################################## @@ -7911,6 +8336,91 @@ sub exec_cluster_ap_module ($$$$) { pandora_update_agent ($pa_config, $timestamp, $module->{'id_agente'}, undef, undef, -1, $dbh); } + +################################################################################ +# SNMP Log Monitoring +################################################################################ +sub snmp_traps_monitoring ($$) { + my ($pa_config, $dbh) = @_; + + return undef unless $pa_config->{'snmpconsole'} == 1; + my $xml_output = ''; + + my $filename = $pa_config->{'snmp_logfile'}; + my $size = -s $filename; + my $size_in_mb; + + if(defined($size) && $size != 0) { + $size_in_mb = $size / (1024 * 1024); + } else { + $size_in_mb = 0; + } + + my @modules; + my $module; + + # SNMP Trap log size + $module->{'name'} = "snmp_trap_queue"; + $module->{'description'} = 'Size of snmp_logfile (MB): Size of snmp trap log in megabytes'; + $module->{'data'} = $size_in_mb; + $module->{'unit'} = 'MB'; + $module->{'min_critical'} = 1024; + $module->{'max_critical'} = 0; + push(@modules, $module); + undef $module; + + # Total traps + my $count = get_db_value($dbh, 'SELECT COUNT(id_trap) FROM ttrap'); + $count = 0 unless defined($count); + + $module->{'name'} = "total_traps"; + $module->{'description'} = 'Total number of traps'; + $module->{'data'} = $count; + $module->{'module_interval'} = 288; + push(@modules, $module); + undef $module; + + foreach my $module_data (@modules) { + $xml_output .=" "; + $xml_output .=" " .$module_data->{'name'}. ""; + $xml_output .=" " . $module_data->{'data'} . ""; + + if(defined($module_data->{'description'})) { + $xml_output .=" " .$module_data->{'description'}. ""; + } + if(defined($module_data->{'type'})) { + $xml_output .=" " .$module_data->{'type'}. ""; + } else { + $xml_output .=" generic_data"; + } + if(defined($module_data->{'unit'})) { + $xml_output .=" " .$module_data->{'unit'}. ""; + } + if(defined($module_data->{'module_parent'})) { + $xml_output .=" " .$module_data->{'module_parent'}. ""; + } + if(defined($module_data->{'module_interval'})) { + $xml_output .=" " .$module_data->{'module_interval'}. ""; + } + if(defined($module_data->{'max_critical'})) { + $xml_output .=" " .$module_data->{'max_critical'}. ""; + } + if(defined($module_data->{'min_critical'})) { + $xml_output .=" " .$module_data->{'min_critical'}. ""; + } + if(defined($module_data->{'max_warning'})) { + $xml_output .=" " .$module_data->{'max_warning'}. ""; + } + if(defined($module_data->{'min_warning'})) { + $xml_output .=" " .$module_data->{'min_warning'}. ""; + } + + $xml_output .=" "; + } + + return $xml_output; +} + # End of function declaration # End of defined Code diff --git a/pandora_server/lib/PandoraFMS/DB.pm b/pandora_server/lib/PandoraFMS/DB.pm index f9be30bd41..22ee1611fa 100644 --- a/pandora_server/lib/PandoraFMS/DB.pm +++ b/pandora_server/lib/PandoraFMS/DB.pm @@ -72,6 +72,7 @@ our @EXPORT = qw( get_agent_group get_agent_name get_agent_module_id + get_agent_module_id_by_name get_alert_template_module_id get_alert_template_name get_command_id @@ -737,6 +738,20 @@ sub get_agent_module_id ($$$) { return defined ($rc) ? $rc : -1; } +######################################################################## +## Return module id given the module name and agent name. +######################################################################## +sub get_agent_module_id_by_name ($$$) { + my ($dbh, $module_name, $agent_name) = @_; + + my $rc = get_db_value ( + $dbh, + 'SELECT id_agente_modulo + FROM tagente_modulo tam LEFT JOIN tagente ta ON tam.id_agente = ta.id_agente + WHERE tam.nombre = ? AND ta.nombre = ?', safe_input($module_name), $agent_name); + return defined ($rc) ? $rc : -1; +} + ########################################################################## ## Return the module template id given the module id and the template id. ########################################################################## diff --git a/pandora_server/lib/PandoraFMS/PluginTools.pm b/pandora_server/lib/PandoraFMS/PluginTools.pm index 4a090a3a41..fd3b4da7fc 100644 --- a/pandora_server/lib/PandoraFMS/PluginTools.pm +++ b/pandora_server/lib/PandoraFMS/PluginTools.pm @@ -34,7 +34,7 @@ our @ISA = qw(Exporter); # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.773.3"; -my $pandora_build = "230921"; +my $pandora_build = "230928"; our $VERSION = $pandora_version." ".$pandora_build; our %EXPORT_TAGS = ( 'all' => [ qw() ] ); diff --git a/pandora_server/lib/PandoraFMS/ProducerConsumerServer.pm b/pandora_server/lib/PandoraFMS/ProducerConsumerServer.pm index 4ffa4858d5..24598291a3 100644 --- a/pandora_server/lib/PandoraFMS/ProducerConsumerServer.pm +++ b/pandora_server/lib/PandoraFMS/ProducerConsumerServer.pm @@ -95,7 +95,8 @@ sub run ($$$$$) { 'tstamp' => time(), 'rate' => 0, 'rate_count' => 0, - 'rate_tstamp' => time() + 'rate_tstamp' => time(), + 'task_queue' => $task_queue, }); my $thr = threads->create ({'exit' => 'thread_only'}, @@ -127,7 +128,8 @@ sub run ($$$$$) { 'tstamp' => time(), 'rate' => 0, 'rate_count' => 0, - 'rate_tstamp' => time() + 'rate_tstamp' => time(), + 'task_queue' => $task_queue, }); # Launch producer thread diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index 326e4692ad..c9a89938d7 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -108,6 +108,7 @@ our @EXPORT = qw( MODULE_UNKNOWN MODULE_NOTINIT $THRRUN + api_call api_call_url cron_get_closest_in_range cron_next_execution @@ -140,6 +141,9 @@ our @EXPORT = qw( disk_free load_average free_mem + total_mem + cpu_load + count_files_ext md5 md5_init pandora_ping @@ -1412,6 +1416,83 @@ sub free_mem { return $free_mem; } +sub total_mem { + my $total_mem; + + my $OSNAME = $^O; + + if ($OSNAME eq "freebsd"){ + $total_mem = `/sbin/sysctl sysctl -b hw.physmem`; + # in kilobytes + $total_mem = $total_mem / 1024; + + } + elsif ($OSNAME eq "netbsd"){ + $total_mem = `cat /proc/meminfo | grep MemTotal | awk '{ print \$2 }'`; + } + elsif ($OSNAME eq "MSWin32"){ + $total_mem = `wmic ComputerSystem get TotalPhysicalMemory /Value`; + if ($total_mem =~ m/=(.*)$/gm) { + $total_mem = $1; + } else { + $total_mem = undef; + } + } + # by default LINUX calls + else { + $total_mem = `free | grep Mem | awk '{ print \$2 }'`; + } + return $total_mem; +} + + +################################################################################ +## SUB CPU load + # Get CPU load (%) +################################################################################ +sub cpu_load { + my $cpu_load; + + my $OSNAME = $^O; + + if ($OSNAME eq "MSWin32"){ + $cpu_load = `wmic cpu get loadpercentage|find /I /V "Loadpercentage" | findstr /r "[0-9]" `; + } + # by default LINUX calls + else { + $cpu_load = `top -bn 2 -d 0.01 | grep 'Cpu' | tail -n 1 | awk '{ print \$2+\$4+\$6 }'`; + } + + return $cpu_load; +} + +################################################################################ +## SUB count_files + # Count files in an specific folder by extension +################################################################################ +sub count_files_ext($$) { + my($path, $ext) = @_; + + my $count=0; + my $OSNAME = $^O; + + if ($OSNAME eq "MSWin32"){ + $path =~ '/^([a-zA-Z]:)?(\\\\[^\\/:*?\"<>|]+)*\\\\?/'; + my $drive = $1; + my $folder = $2; + + $count = `wmic datafile where "drive=\'$drive\' and path=\'$folder\' and extension=\'$ext\'" get /value | find /c "="`; + if ($count =~ m/=(.*)$/gm) { + $count = $1; + } + $count = undef; + + } else { + $count = `find $path -type f -name "*.$ext" | wc -l` + } + + return $count; +} ################################################################################ ## SUB ticks_totime # Transform a snmp timeticks count in a date @@ -2323,6 +2404,44 @@ sub uri_encode_literal_percent { return $return_char; } ## end sub uri_encode_literal_percent +sub api_call { + my ($pa_config, $method, $server_url, $api_params, @options) = @_; + + my $ua = LWP::UserAgent->new(); + $ua->timeout($pa_config->{'tcp_timeout'}); + # Enable environmental proxy settings + $ua->env_proxy; + # Enable in-memory cookie management + $ua->cookie_jar( {} ); + + # Disable verify host certificate (only needed for self-signed cert) + $ua->ssl_opts( 'verify_hostname' => 0 ); + $ua->ssl_opts( 'SSL_verify_mode' => 0x00 ); + + my $response; + + eval { + if ($method =~/get/i) { + $response = $ua->get($server_url, $api_params, @options); + } elsif ($method =~/put/i) { + my $req = HTTP::Request->new('PUT' => $server_url); + $req->header(@options); + $req->content($api_params); + $response = $ua->request($req); + } else { + $response = $ua->post($server_url, $api_params, @options); + } + }; + if ((!$@) && $response->is_success) { + return $response->decoded_content; + } + + logger($pa_config, 'Api response failure: ' . $response->{'_rc'} . '. Description error: ' . $response->{'_content'}, 3); + logger($pa_config, $response->{'_request'}, 3); + + return undef; +} + ################################################################################ # Launch API call diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 642d722b04..d9274cb126 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.773.3 -%define release 230921 +%define release 230928 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 6bc612d9c5..ba7c1d7fca 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -4,7 +4,7 @@ %global __os_install_post %{nil} %define name pandorafms_server %define version 7.0NG.773.3 -%define release 230921 +%define release 230928 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index 2c36327c78..e20b5fb78e 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.773.3" -PI_BUILD="230921" +PI_BUILD="230928" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 89fcc1ac10..db6b4f2860 100755 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -35,7 +35,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.773.3 Build 230921"; +my $version = "7.0NG.773.3 Build 230928"; # Pandora server configuration my %conf; @@ -1401,24 +1401,6 @@ if (defined($history_dbh)) { } -# Keep integrity between PandoraFMS agents and IntegriaIMS inventory objects. -pandora_sync_agents_integria($dbh); - -# Get Integria IMS ticket types for alert commands. -my @types = pandora_get_integria_ticket_types($dbh); - -if (scalar(@types) != 0) { - my $query_string = ''; - foreach my $type (@types) { - $query_string .= $type->{'id'} . ',' . $type->{'name'} . ';'; - } - - $query_string = substr $query_string, 0, -1; - - db_do($dbh, "UPDATE talert_commands SET fields_descriptions='[\"Ticket title\",\"Ticket group ID\",\"Ticket priority\",\"Ticket owner\",\"Ticket type\",\"Ticket status\",\"Ticket description\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\"]' WHERE name=\"Integria IMS Ticket\""); - db_do($dbh, "UPDATE talert_commands SET fields_values='[\"\", \"\", \"\",\"\",\"" . $query_string . "\",\"\",\"\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\",\"_integria_type_custom_field_\"]' WHERE name=\"Integria IMS Ticket\""); -} - # Cleanup and exit db_disconnect ($history_dbh) if defined ($history_dbh); db_disconnect ($dbh); diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 0f057bb948..09dcd450f9 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.773.3 Build 230921"; +my $version = "7.0NG.773.3 Build 230928"; # save program name for logging my $progname = basename($0);