';
+
+ // Left box.
+ $output .= '
';
+ $disable_filters = '';
+
+ // Filtering.
+ if (isset($sections['filters']) === true
+ && $sections['filters'] === 1
+ ) {
+ // Filtering.
+ if (isset($sections['group-filter']) === true
+ && $sections['group-filter'] === 1
+ ) {
+ $output .= '
';
+
+ $output .= '
';
+
+ $reload_content = "reloadContent('".$rid."'";
+ $reload_content .= ", '".ui_get_full_url('ajax.php')."'";
+ $reload_content .= ", '".base64_encode(
+ json_encode($group_filter)
+ )."'";
+ $reload_content .= ", 'left'";
+ $reload_content .= ", '".__('None')."')";
+
+ $output .= html_print_input(
+ [
+ 'label' => __('Filter group'),
+ 'name' => 'id-group-available-select-'.$rid,
+ 'returnAllGroup' => true,
+ 'privilege' => 'AR',
+ 'type' => 'select_groups',
+ 'return' => true,
+ 'script' => $reload_content,
+ ]
+ );
+
+ $output .= html_print_input(
+ [
+ 'label' => __('Group recursion'),
+ 'name' => 'id-group-recursion-available-select-'.$rid,
+ 'type' => 'checkbox',
+ 'script' => $reload_content,
+ 'return' => true,
+ ]
+ );
+
+ $output .= '
';
+
+ $output .= '
';
+ $disable_filters = "disableFilters('".$rid."')";
+ }
+
+ if (isset($sections['item-available-filter']) === true
+ && $sections['item-available-filter'] === 1
+ ) {
+ $output .= '
';
+
+ $output .= html_print_input(
+ [
+ 'style' => 'display:none;',
+ 'name' => 'tmp-available-select-'.$rid,
+ 'type' => 'select',
+ 'nothing' => false,
+ 'return' => true,
+ ]
+ );
+
+ $f = "filterAvailableItems(this.value,'".$rid."','".__('None')."')";
+ $output .= html_print_input(
+ [
+ 'label' => __($texts['filter-item']),
+ 'name' => 'filter-item-available-'.$rid,
+ 'onKeyUp' => $f,
+ 'input_class' => 'filter w100p',
+ 'size' => 20,
+ 'type' => 'text',
+ 'return' => true,
+ ]
+ );
+
+ $output .= '
';
+ }
+ }
+
+ $output .= '
'.$texts['title-left'].'';
+
+ // Selector boxes.
+ $output .= html_print_input(
+ [
+ 'type' => 'select',
+ 'fields' => $available,
+ 'name' => 'available-select-'.$rid.'[]',
+ 'selected' => '',
+ 'script' => $disable_filters,
+ 'nothing' => '',
+ 'nothing_value' => 0,
+ 'return' => true,
+ 'multiple' => true,
+ 'sort' => true,
+ 'class' => 'select-multiple',
+ 'disabled' => false,
+ 'style' => false,
+ 'option_style' => false,
+ 'size' => false,
+ 'modal' => false,
+ 'message' => '',
+ 'select_all' => false,
+ 'simple_multiple_options' => false,
+ ]
+ );
+
+ $output .= '
';
+
+ // Middle buttons actions.
+ $add = "addItems('".$rid."','".__('None')."'); return false";
+ $del = "removeItems('".$rid."','".__('None')."'); return false";
+
+ $output .= '
';
+
+ $output .= html_print_input(
+ [
+ 'type' => 'image',
+ 'src' => 'images/darrowright.png',
+ 'return' => true,
+ 'options' => [
+ 'title' => $texts['title-add'],
+ 'onclick' => $add,
+ ],
+ ]
+ );
+
+ $output .= html_print_input(
+ [
+ 'type' => 'image',
+ 'src' => 'images/darrowleft.png',
+ 'return' => true,
+ 'options' => [
+ 'title' => $texts['title-del'],
+ 'onclick' => $del,
+ ],
+ ]
+ );
+
+ $output .= '
';
+
+ // Left box.
+ $output .= '
';
+
+ // Filtering.
+ if (isset($sections['filters']) === true
+ && $sections['filters'] === 1
+ ) {
+ if (isset($sections['group-filter']) === true
+ && $sections['group-filter'] === 1
+ ) {
+ $output .= '
';
+
+ $output .= '
';
+
+ $reload_content = "reloadContent('".$rid."'";
+ $reload_content .= ", '".ui_get_full_url('ajax.php')."'";
+ $reload_content .= ", '".base64_encode(
+ json_encode($group_filter)
+ )."'";
+ $reload_content .= ", 'right'";
+ $reload_content .= ", '".__('None')."')";
+
+ $output .= html_print_input(
+ [
+ 'label' => __('Filter group'),
+ 'name' => 'id-group-selected-select-'.$rid,
+ 'returnAllGroup' => true,
+ 'privilege' => 'AR',
+ 'type' => 'select_groups',
+ 'return' => true,
+ 'script' => $reload_content,
+ ]
+ );
+
+ $output .= html_print_input(
+ [
+ 'label' => __('Group recursion'),
+ 'name' => 'id-group-recursion-selected-select-'.$rid,
+ 'type' => 'checkbox',
+ 'script' => $reload_content,
+ 'return' => true,
+ ]
+ );
+
+ $output .= '
';
+
+ $output .= '
';
+ }
+
+ // Filtering.
+ if (isset($sections['item-selected-filter']) === true
+ && $sections['item-selected-filter'] === 1
+ ) {
+ $output .= '
';
+
+ $output .= html_print_input(
+ [
+ 'style' => 'display:none;',
+ 'name' => 'tmp-selected-select-'.$rid,
+ 'type' => 'select',
+ 'nothing' => false,
+ 'return' => true,
+ ]
+ );
+
+ $f = "filterSelectedItems(this.value,'".$rid."','".__('None')."')";
+ $output .= html_print_input(
+ [
+ 'label' => __($texts['filter-item']),
+ 'name' => 'filter-item-selected-'.$rid,
+ 'onKeyUp' => $f,
+ 'input_class' => 'filter w100p',
+ 'size' => 20,
+ 'type' => 'text',
+ 'return' => true,
+ ]
+ );
+
+ $output .= '
';
+ }
+ }
+
+ $output .= '
'.$texts['title-right'].'';
+
+ $output .= html_print_input(
+ [
+ 'type' => 'select',
+ 'fields' => $selected,
+ 'name' => 'selected-select-'.$rid.'[]',
+ 'selected' => '',
+ 'script' => '',
+ 'nothing' => '',
+ 'nothing_value' => 0,
+ 'return' => true,
+ 'multiple' => true,
+ 'sort' => true,
+ 'class' => 'select-multiple',
+ 'disabled' => false,
+ 'style' => false,
+ 'option_style' => false,
+ 'size' => false,
+ 'modal' => false,
+ 'message' => '',
+ 'select_all' => true,
+ 'simple_multiple_options' => false,
+ ]
+ );
+
+ $output .= '
';
+
+ // Close main.
+ $output .= '
';
+
+ if ($return === false) {
+ echo $output;
+ }
+
+ return $output;
+}
+
+
/**
* Prints an array of fields in a popup menu of a form based on a SQL query.
* The first and second columns of the query will be used.
@@ -1555,7 +1915,8 @@ function html_print_input_text(
$autocomplete='',
$autofocus=false,
$onKeyDown='',
- $formTo=''
+ $formTo='',
+ $onKeyUp=''
) {
if ($maxlength == 0) {
$maxlength = 255;
@@ -1584,6 +1945,10 @@ function html_print_input_text(
$attr['onkeydown'] = $onKeyDown;
}
+ if ($onKeyUp != '') {
+ $attr['onkeyup'] = $onKeyUp;
+ }
+
if ($autocomplete !== '') {
$attr['autocomplete'] = $autocomplete;
}
@@ -3477,9 +3842,10 @@ function html_print_input($data, $wrapper='div', $input_only=false)
((isset($data['class']) === true) ? $data['class'] : ''),
((isset($data['onChange']) === true) ? $data['onChange'] : ''),
((isset($data['autocomplete']) === true) ? $data['autocomplete'] : ''),
- false,
+ ((isset($data['autofocus']) === true) ? $data['autofocus'] : false),
((isset($data['onKeyDown']) === true) ? $data['onKeyDown'] : ''),
- ((isset($data['form']) === true) ? $data['form'] : '')
+ ((isset($data['form']) === true) ? $data['form'] : ''),
+ ((isset($data['onKeyUp']) === true) ? $data['onKeyUp'] : '')
);
break;
@@ -3901,6 +4267,19 @@ function html_print_input($data, $wrapper='div', $input_only=false)
);
break;
+ case 'select_multiple_filtered':
+ $output .= html_print_select_multiple_filtered(
+ $data['available'],
+ $data['selected'],
+ ((isset($data['name']) === true) ? $data['name'] : null),
+ ((isset($data['class']) === true) ? $data['class'] : ''),
+ ((isset($data['return']) === true) ? $data['return'] : true),
+ ((isset($data['group_filter']) === true) ? $data['group_filter'] : []),
+ ((isset($data['texts']) === true) ? $data['texts'] : []),
+ ((isset($data['sections']) === true) ? $data['sections'] : [])
+ );
+ break;
+
default:
// Ignore.
break;
diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php
index 9d3f1a2a4c..cfccfe9b1c 100755
--- a/pandora_console/include/functions_modules.php
+++ b/pandora_console/include/functions_modules.php
@@ -2427,16 +2427,45 @@ function modules_get_modulegroup_name($modulegroup_id)
/**
* Returns target color to be used based on the status received.
*
- * @param integer $status Source information.
+ * @param integer $status Source information.
+ * @param boolean $force_module Use module constants only.
*
* @return string HTML tag for color.
*/
-function modules_get_color_status($status)
+function modules_get_color_status($status, $force_module=false)
{
if (isset($status) === false) {
return COL_UNKNOWN;
}
+ if ($force_module === true) {
+ switch ($status) {
+ case AGENT_MODULE_STATUS_CRITICAL_BAD:
+ case AGENT_MODULE_STATUS_NOT_NORMAL:
+ return COL_CRITICAL;
+
+ case AGENT_MODULE_STATUS_CRITICAL_ALERT:
+ case AGENT_MODULE_STATUS_WARNING_ALERT:
+ case AGENT_MODULE_STATUS_NORMAL_ALERT:
+ return COL_ALERTFIRED;
+
+ case AGENT_MODULE_STATUS_NO_DATA:
+ case AGENT_MODULE_STATUS_NOT_INIT:
+ return COL_NOTINIT;
+
+ case AGENT_MODULE_STATUS_NORMAL:
+ return COL_NORMAL;
+
+ case AGENT_MODULE_STATUS_WARNING:
+ return COL_WARNING;
+
+ case AGENT_MODULE_STATUS_ALL:
+ case AGENT_MODULE_STATUS_UNKNOWN:
+ default:
+ return COL_UNKNOWN;
+ }
+ }
+
switch ((string) $status) {
case (string) AGENT_MODULE_STATUS_NORMAL:
case (string) AGENT_STATUS_NORMAL:
diff --git a/pandora_console/include/functions_treeview.php b/pandora_console/include/functions_treeview.php
index 32688a25ea..e067220eb0 100755
--- a/pandora_console/include/functions_treeview.php
+++ b/pandora_console/include/functions_treeview.php
@@ -667,13 +667,22 @@ function treeview_printTable($id_agente, $server_data=[], $no_head=false)
if ($user_access_node && check_acl($config['id_user'], $agent['id_grupo'], 'AW')) {
$go_to_agent = '';
- if ($agent['id_os'] != 100) {
+ if ($agent['id_os'] == CLUSTER_OS_ID) {
+ if (enterprise_installed()) {
+ $cluster = PandoraFMS\Enterprise\Cluster::loadFromAgentId(
+ $agent['id_agente']
+ );
+ $url = 'index.php?sec=reporting&sec2='.ENTERPRISE_DIR;
+ $url .= '/operation/cluster/cluster';
+ $url = ui_get_full_url(
+ $url.'&op=update&id='.$cluster->id()
+ );
+ $go_to_agent .= '
';
+ $go_to_agent .= html_print_submit_button(__('Edit cluster'), 'upd_button', false, 'class="sub config"', true);
+ }
+ } else {
$go_to_agent .= '';
$go_to_agent .= html_print_submit_button(__('Go to agent edition'), 'upd_button', false, 'class="sub config"', true);
- } else {
- $cluster = db_get_row_sql('select id from tcluster where id_agent = '.$id_agente);
- $go_to_agent .= '';
- $go_to_agent .= html_print_submit_button(__('Edit cluster'), 'upd_button', false, 'class="sub config"', true);
}
$go_to_agent .= '';
diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php
index c5525347e4..c67091f47f 100755
--- a/pandora_console/include/functions_ui.php
+++ b/pandora_console/include/functions_ui.php
@@ -2698,6 +2698,35 @@ function ui_print_status_image(
}
+/**
+ * Returns html code to print a shape for a module.
+ *
+ * @param integer $status Module status.
+ * @param boolean $return True or false.
+ * @param string $class Custom class or use defined.
+ *
+ * @return string HTML code for shape.
+ */
+function ui_print_module_status(
+ $status,
+ $return=false,
+ $class='status_rounded_rectangles'
+) {
+ $color = modules_get_color_status($status, true);
+ $title = modules_get_modules_status($status);
+
+ $output = '
';
+
+ if ($return === false) {
+ echo $output;
+ }
+
+ return $output;
+}
+
+
/**
* Get the shape of an image by assigning it a CSS class. Prints an image with CSS representing a status.
*
@@ -3157,6 +3186,13 @@ function ui_print_datatable(array $parameters)
throw new Exception('[ui_print_datatable]: You must define columns for datatable');
}
+ if (isset($parameters['column_names'])
+ && is_array($parameters['column_names'])
+ && count($parameters['columns']) != count($parameters['column_names'])
+ ) {
+ throw new Exception('[ui_print_datatable]: Columns and columns names must have same length');
+ }
+
if (!isset($parameters['ajax_url'])) {
throw new Exception('[ui_print_datatable]: Parameter ajax_url is required');
}
diff --git a/pandora_console/include/javascript/multiselect_filtered.js b/pandora_console/include/javascript/multiselect_filtered.js
new file mode 100644
index 0000000000..0366f870a4
--- /dev/null
+++ b/pandora_console/include/javascript/multiselect_filtered.js
@@ -0,0 +1,157 @@
+/* global $ */
+
+/**
+ * Add modules from available to selected.
+ */
+function addItems(id, noneStr) {
+ $("#available-select-" + id + " :selected")
+ .toArray()
+ .forEach(function(item) {
+ $("#selected-select-" + id).append(item);
+ });
+
+ keepSelectClean("available-select-" + id, noneStr);
+ keepSelectClean("selected-select-" + id, noneStr);
+}
+
+/**
+ * Mark all options for given id.
+ */
+function markAll(id) {
+ $("#" + id + " option").prop("selected", true);
+}
+
+/**
+ * Remove modules from selected back to available.
+ */
+function removeItems(id, noneStr) {
+ $("#selected-select-" + id + " :selected")
+ .toArray()
+ .forEach(function(item) {
+ $("#available-select-" + id).append(item);
+ });
+
+ keepSelectClean("available-select-" + id, noneStr);
+ keepSelectClean("selected-select-" + id, noneStr);
+}
+
+/**
+ * 'None' option, if needed.
+ */
+function keepSelectClean(id, noneStr) {
+ $("#" + id + " option[value=0]").remove();
+
+ if ($("#" + id + " option").length == 0) {
+ $("#" + id).append(new Option(noneStr, 0));
+ }
+
+ $("#" + id + " option").each(function() {
+ $(this).prop("selected", false);
+ });
+}
+
+function filterItems(id, str) {
+ // Remove option 0 - None.
+ $("#" + id + " option[value=0]").remove();
+
+ // Move not matching elements filtered to tmp-id.
+ var tmp = $("#" + id + " option:not(:contains(" + str + "))").toArray();
+ tmp.forEach(function(item) {
+ $("#tmp-" + id).append(item);
+ $(this).remove();
+ });
+
+ // Move matching filter back to id.
+ tmp = $("#tmp-" + id + " option:contains(" + str + ")").toArray();
+ tmp.forEach(function(item) {
+ $("#" + id).append(item);
+ $(this).remove();
+ });
+}
+
+function filterAvailableItems(txt, id, noneStr) {
+ filterItems("available-select-" + id, txt);
+ keepSelectClean("available-select-" + id, noneStr);
+}
+
+function filterSelectedItems(txt, id, noneStr) {
+ filterItems("selected-select-" + id, txt);
+ keepSelectClean("selected-select-" + id, noneStr);
+}
+
+function disableFilters(id) {
+ $("#id-group-selected-select-" + id).prop("disabled", true);
+ $("#checkbox-id-group-recursion-selected-select-" + id).prop(
+ "disabled",
+ true
+ );
+}
+
+function reloadContent(id, url, options, side, noneStr) {
+ var current;
+ var opposite;
+
+ if (side == "right") {
+ current = "selected-select-" + id;
+ opposite = "available-select-" + id;
+ } else if (side == "left") {
+ current = "available-select-" + id;
+ opposite = "selected-select-" + id;
+ } else {
+ console.error("reloadContent bad usage.");
+ return;
+ }
+
+ var data = JSON.parse(atob(options));
+ data.side = side;
+ data.group_recursion = $("#checkbox-id-group-recursion-" + current).prop(
+ "checked"
+ );
+ data.group_id = $("#id-group-" + current).val();
+
+ $.ajax({
+ method: "post",
+ url: url,
+ dataType: "json",
+ data: data,
+ success: function(data) {
+ // Cleanup previous content.
+ $("#" + current).empty();
+
+ let items = Object.entries(data).sort(function(a, b) {
+ if (a[1] == b[1]) return 0;
+
+ var int_a = parseInt(a[1]);
+ var int_b = parseInt(b[1]);
+
+ if (!isNaN(int_a) && !isNaN(int_b)) {
+ return int_a > int_b ? 1 : -1;
+ }
+ return a[1] > b[1] ? 1 : -1;
+ });
+
+ for (var [value, label] of items) {
+ if (
+ $("#" + opposite + " option[value=" + value + "]").length == 0 &&
+ $("#tmp-" + current + " option[value=" + value + "]").length == 0
+ ) {
+ // Does not exist in opposite box nor is filtered.
+ $("#" + current).append(new Option(label, value));
+ }
+ }
+
+ keepSelectClean(current, noneStr);
+ },
+ error: function(data) {
+ console.error(data.responseText);
+ }
+ });
+}
+
+$(document).submit(function() {
+ // Force select all 'selected' items to send them on submit.
+ $("[id*=text-filter-item-selected-")
+ .val("")
+ .keyup();
+ $("[id^=selected-select-] option").prop("selected", true);
+});
diff --git a/pandora_console/include/lib/Agent.php b/pandora_console/include/lib/Agent.php
new file mode 100644
index 0000000000..b599f6daed
--- /dev/null
+++ b/pandora_console/include/lib/Agent.php
@@ -0,0 +1,286 @@
+ $id_agent]);
+ if ($load_modules === true) {
+ $rows = \db_get_all_rows_filter(
+ 'tagente_modulo',
+ ['id_agente' => $id_agent]
+ );
+
+ if (is_array($rows) === true) {
+ foreach ($rows as $row) {
+ $this->modules[] = Module::build($row);
+ }
+ }
+
+ $this->modulesLoaded = true;
+ }
+ } else {
+ // Create empty skel.
+ parent::__construct('tagente');
+
+ // New agent has no modules.
+ $this->modulesLoaded = true;
+ }
+
+ // Customize certain fields.
+ $this->fields['group'] = new Group($this->fields['id_grupo']);
+ }
+
+
+ /**
+ * Overrides Entity method.
+ *
+ * @param integer $id_group Target group Id.
+ *
+ * @return integer|null Group Id or null.
+ */
+ public function id_grupo(?int $id_group=null)
+ {
+ if ($id_group === null) {
+ return $this->fields['id_grupo'];
+ } else {
+ $this->fields['id_grupo'] = $id_group;
+ $this->fields['group'] = new Group($this->fields['id_grupo']);
+ }
+ }
+
+
+ /**
+ * Saves current definition to database.
+ *
+ * @param boolean $alias_as_name Use alias as agent name.
+ *
+ * @return mixed Affected rows of false in case of error.
+ * @throws \Exception On error.
+ */
+ public function save(bool $alias_as_name=false)
+ {
+ if (empty($this->fields['nombre']) === true) {
+ if ($alias_as_name === true
+ && (empty($this->fields['alias']) === true)
+ ) {
+ throw new \Exception(
+ get_class($this).' error, nor "alias" nor "nombre" are set'
+ );
+ } else {
+ // Use alias instead.
+ $this->fields['nombre'] = $this->fields['alias'];
+ }
+ }
+
+ if ($this->fields['id_agente'] > 0) {
+ // Agent update.
+ $updates = $this->fields;
+
+ // Remove shortcuts from values.
+ unset($updates['group']);
+
+ $rs = \db_process_sql_update(
+ 'tagente',
+ $updates,
+ ['id_agente' => $this->fields['id_agente']]
+ );
+
+ if ($rs === false) {
+ global $config;
+ throw new \Exception(
+ __METHOD__.' error: '.$config['dbconnection']->error
+ );
+ }
+ } else {
+ // Agent creation.
+ $updates = $this->fields;
+
+ // Remove shortcuts from values.
+ unset($updates['group']);
+
+ // Clean null fields.
+ foreach ($updates as $k => $v) {
+ if ($v === null) {
+ unset($updates[$k]);
+ }
+ }
+
+ $rs = \agents_create_agent(
+ $updates['nombre'],
+ $updates['id_grupo'],
+ $updates['intervalo'],
+ $updates['direccion'],
+ $updates,
+ $alias_as_name
+ );
+
+ if ($rs === false) {
+ global $config;
+ throw new \Exception(
+ __METHOD__.' error: '.$config['dbconnection']->error
+ );
+ }
+
+ $this->fields['id_agente'] = $rs;
+ }
+
+ if ($this->fields['group']->id_grupo() === null) {
+ // Customize certain fields.
+ $this->fields['group'] = new Group($this->fields['id_grupo']);
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Creates a module in current agent.
+ *
+ * @param array $params Module definition (each db field).
+ *
+ * @return integer Id of new module.
+ * @throws \Exception On error.
+ */
+ public function addModule(array $params)
+ {
+ $err = __METHOD__.' error: ';
+
+ if (empty($params['nombre']) === true) {
+ throw new \Exception(
+ $err.' module name is mandatory'
+ );
+ }
+
+ $params['id_agente'] = $this->fields['id_agente'];
+
+ $id_module = modules_create_agent_module(
+ $this->fields['id_agente'],
+ $params['nombre'],
+ $params
+ );
+
+ if ($id_module === false) {
+ global $config;
+ throw new \Exception(
+ $err.$config['dbconnection']->error
+ );
+ }
+
+ return $id_module;
+
+ }
+
+
+ /**
+ * Search for modules into this agent.
+ *
+ * @param array $filter Filters.
+ *
+ * @return PandoraFMS\Module Module found.
+ */
+ public function searchModules(array $filter)
+ {
+ $filter['id_agente'] = $this->id_agente();
+
+ if ($this->modulesLoaded === true) {
+ // Search in $this->modules.
+ $results = [];
+
+ foreach ($this->modules as $module) {
+ $found = true;
+ foreach ($filter as $field => $value) {
+ if ($module->{$field}() !== $value) {
+ $found = false;
+ break;
+ }
+ }
+
+ if ($found === true) {
+ $results[] = $module;
+ }
+ }
+
+ return $results;
+ } else {
+ // Search in db.
+ return Module::search($filter);
+ }
+
+ }
+
+
+ /**
+ * Delete agent from db.
+ *
+ * @return void
+ */
+ public function delete()
+ {
+ // This function also mark modules for deletion.
+ \agents_delete_agent(
+ $this->fields['id_agente']
+ );
+
+ unset($this->fields);
+ unset($this->modules);
+ }
+
+
+}
diff --git a/pandora_console/include/lib/Entity.php b/pandora_console/include/lib/Entity.php
new file mode 100644
index 0000000000..3031a1336f
--- /dev/null
+++ b/pandora_console/include/lib/Entity.php
@@ -0,0 +1,153 @@
+ $id].
+ *
+ * @throws \Exception On error.
+ */
+ public function __construct(string $table, ?array $filters=null)
+ {
+ if (empty($table) === true) {
+ throw new \Exception(
+ get_class($this).' error, table name is not defined'
+ );
+ }
+
+ $this->table = $table;
+
+ if (is_array($filters) === true) {
+ // New one.
+ $data = \db_get_row_filter($this->table, $filters);
+
+ if ($data === false) {
+ throw new \Exception(
+ get_class($this).' error, entity not found'
+ );
+ }
+
+ // Map fields.
+ foreach ($data as $k => $v) {
+ $this->fields[$k] = $v;
+ }
+ } else {
+ // Empty one.
+ $data = \db_get_all_rows_sql(
+ sprintf(
+ 'SHOW COLUMNS FROM %s',
+ $this->table
+ )
+ );
+
+ foreach ($data as $row) {
+ $this->fields[$row['Field']] = null;
+ }
+ }
+ }
+
+
+ /**
+ * Dynamically call methods in this object.
+ *
+ * @param string $methodName Name of target method or attribute.
+ * @param array $params Arguments for target method.
+ *
+ * @return mixed Return of method.
+ * @throws \Exception On error.
+ */
+ public function __call(string $methodName, ?array $params=null)
+ {
+ // Prioritize written methods over dynamic ones.
+ if (method_exists($this, $methodName) === true) {
+ return $this->{$methodName}($params);
+ }
+
+ if (array_key_exists($methodName, $this->fields) === true) {
+ if (empty($params) === true) {
+ return $this->fields[$methodName];
+ } else {
+ $this->fields[$methodName] = $params[0];
+ }
+
+ return null;
+ }
+
+ throw new \Exception(
+ get_class($this).' error, method '.$methodName.' does not exist'
+ );
+ }
+
+
+ /**
+ * Returns current object as array.
+ *
+ * @return array Of fields.
+ */
+ public function toArray()
+ {
+ return $this->fields;
+ }
+
+
+ /**
+ * Saves current object definition to database.
+ *
+ * @return boolean Success or not.
+ */
+ public abstract function save();
+
+
+}
diff --git a/pandora_console/include/lib/Group.php b/pandora_console/include/lib/Group.php
new file mode 100644
index 0000000000..c7023820ed
--- /dev/null
+++ b/pandora_console/include/lib/Group.php
@@ -0,0 +1,100 @@
+fields['id'] = 0;
+ $this->fields['nombre'] = 'All';
+ } else if (is_numeric($id_group) === true) {
+ parent::__construct('tgrupo', ['id_grupo' => $id_group]);
+ if ($recursive === true) {
+ // Customize certain fields.
+ $this->fields['parent'] = new Group($this->fields['parent']);
+ }
+ } else {
+ // Empty skel.
+ parent::__construct('tgrupo');
+ }
+
+ }
+
+
+ /**
+ * Saves current group definition to database.
+ *
+ * @return mixed Affected rows of false in case of error.
+ */
+ public function save()
+ {
+ global $config;
+
+ if (isset($config['centralized_management'])
+ && $config['centralized_management'] > 0
+ ) {
+ throw new \Exception(
+ get_class($this).' error, cannot be modified in a centralized management environment.'
+ );
+ }
+
+ if ($this->fields['id_grupo'] > 0) {
+ $updates = $this->fields;
+ if (is_numeric($updates['parent']) === false) {
+ $updates['parent'] = $this->parent()->id_grupo();
+ }
+
+ return db_process_sql_update(
+ 'tgrupo',
+ $this->fields,
+ ['id_grupo' => $this->fields['id_grupo']]
+ );
+ }
+
+ return false;
+ }
+
+
+}
diff --git a/pandora_console/include/lib/Module.php b/pandora_console/include/lib/Module.php
new file mode 100644
index 0000000000..60b75580ce
--- /dev/null
+++ b/pandora_console/include/lib/Module.php
@@ -0,0 +1,253 @@
+ 1 && (++$i) > $limit) {
+ break;
+ }
+
+ $modules[] = self::build($row);
+ }
+
+ return $modules;
+ } else {
+ return self::build($rs[0]);
+ }
+ }
+
+
+ /**
+ * Returns current object as array.
+ *
+ * @return array Of fields.
+ */
+ public function toArray()
+ {
+ return $this->fields;
+ }
+
+
+ /**
+ * Creates a module object from given data. Avoid query duplication.
+ *
+ * @param array $data Module information.
+ *
+ * @return PandoraFMS\Module Object.
+ */
+ public static function build(array $data=[])
+ {
+ $obj = new Module();
+
+ // Set values.
+ foreach ($data as $k => $v) {
+ $obj->{$k}($v);
+ }
+
+ if ($obj->nombre() === 'delete_pending') {
+ return null;
+ }
+
+ // Customize certain fields.
+ $obj->status = new ModuleStatus($obj->id_agente_modulo());
+
+ return $obj;
+ }
+
+
+ /**
+ * Builds a PandoraFMS\Module object from given id.
+ *
+ * @param integer $id_agent_module Module id.
+ */
+ public function __construct(?int $id_agent_module=null)
+ {
+ if (is_numeric($id_agent_module) === true
+ && $id_agent_module > 0
+ ) {
+ parent::__construct(
+ 'tagente_modulo',
+ ['id_agente_modulo' => $id_agent_module]
+ );
+ } else {
+ // Create empty skel.
+ parent::__construct('tagente_modulo');
+ }
+
+ if ($this->nombre() === 'delete_pending') {
+ return null;
+ }
+
+ // Customize certain fields.
+ $this->status = new ModuleStatus($this->fields['id_agente_modulo']);
+ }
+
+
+ /**
+ * Returns current status.
+ *
+ * @return PandoraFMS\ModuleStatus Status of the module.
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+
+ /**
+ * Saves current definition to database.
+ *
+ * @return mixed Affected rows of false in case of error.
+ * @throws \Exception On error.
+ */
+ public function save()
+ {
+ if (empty($this->fields['nombre']) === true) {
+ throw new \Exception(
+ get_class($this).' error, "nombre" is not set'
+ );
+ }
+
+ if (empty($this->fields['id_agente']) === true) {
+ throw new \Exception(
+ get_class($this).' error, "id_agente" is not set'
+ );
+ }
+
+ if ($this->fields['id_agente_modulo'] > 0) {
+ // Update.
+ $updates = $this->fields;
+
+ $rs = \db_process_sql_update(
+ 'tagente_modulo',
+ $updates,
+ ['id_agente_modulo' => $this->fields['id_agente_modulo']]
+ );
+
+ if ($rs === false) {
+ global $config;
+ throw new \Exception(
+ __METHOD__.' error: '.$config['dbconnection']->error
+ );
+ }
+ } else {
+ // Creation.
+ $updates = $this->fields;
+
+ // Clean null fields.
+ foreach ($updates as $k => $v) {
+ if ($v === null) {
+ unset($updates[$k]);
+ }
+ }
+
+ $rs = \modules_create_agent_module(
+ $this->fields['id_agente'],
+ $updates['nombre'],
+ $updates
+ );
+
+ if ($rs === false) {
+ global $config;
+ throw new \Exception(
+ __METHOD__.' error: '.$config['dbconnection']->error
+ );
+ }
+
+ $this->fields['id_agente_modulo'] = $rs;
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Erases this module.
+ *
+ * @return void
+ */
+ public function delete()
+ {
+ \modules_delete_agent_module(
+ $this->id_agente_modulo()
+ );
+
+ unset($this->fields);
+ unset($this->status);
+ }
+
+
+}
diff --git a/pandora_console/include/lib/ModuleStatus.php b/pandora_console/include/lib/ModuleStatus.php
new file mode 100644
index 0000000000..cf7cda571f
--- /dev/null
+++ b/pandora_console/include/lib/ModuleStatus.php
@@ -0,0 +1,123 @@
+ 0
+ ) {
+ try {
+ parent::__construct(
+ 'tagente_estado',
+ ['id_agente_modulo' => $id_agent_module]
+ );
+ } catch (\Exception $e) {
+ throw new \Exception(
+ __METHOD__.' error: Status not found for module '.$id_agent_module
+ );
+ }
+ } else {
+ // Create empty skel.
+ parent::__construct('tagente_estado');
+ }
+
+ }
+
+
+ /**
+ * Saves current definition to database.
+ *
+ * @return mixed Affected rows of false in case of error.
+ * @throws \Exception On error.
+ */
+ public function save()
+ {
+ if ($this->fields['id_agente_modulo'] > 0) {
+ // Update.
+ $updates = $this->fields;
+
+ $rs = \db_process_sql_update(
+ 'tagente_estado',
+ $updates,
+ ['id_agente_modulo' => $this->fields['id_agente_modulo']]
+ );
+
+ if ($rs === false) {
+ global $config;
+ throw new \Exception(
+ __METHOD__.' error: '.$config['dbconnection']->error
+ );
+ }
+ } else {
+ // Creation.
+ $updates = $this->fields;
+
+ // Clean null fields.
+ foreach ($updates as $k => $v) {
+ if ($v === null) {
+ unset($updates[$k]);
+ }
+ }
+
+ $rs = \db_process_sql_insert(
+ 'tagente_estado',
+ $updates
+ );
+
+ if ($rs === false) {
+ global $config;
+ throw new \Exception(
+ __METHOD__.' error: '.$config['dbconnection']->error
+ );
+ }
+
+ $this->fields['id_agente_modulo'] = $rs;
+ }
+
+ return true;
+ }
+
+
+}
diff --git a/pandora_console/include/lib/View.php b/pandora_console/include/lib/View.php
index facdb8f262..becb9ba063 100644
--- a/pandora_console/include/lib/View.php
+++ b/pandora_console/include/lib/View.php
@@ -1,8 +1,39 @@
label:not(.p-switch) {
+ width: auto;
+ margin: 0 0.2em;
+ font-weight: normal;
+}
+
+.wizard .flex-row.line.w100p > input {
+ max-width: 100px;
+ margin: 0 1em;
+}
+
+b.state {
+ font-weight: bolder;
+ font-size: 1.1em;
+}
diff --git a/pandora_console/include/styles/multiselect_filtered.css b/pandora_console/include/styles/multiselect_filtered.css
new file mode 100644
index 0000000000..5c36df522d
--- /dev/null
+++ b/pandora_console/include/styles/multiselect_filtered.css
@@ -0,0 +1,54 @@
+.multi-select .multi-select-container {
+ flex: 1 1 200px;
+ min-width: 200px;
+}
+.multi-select-container * {
+ flex: 1 1 auto;
+}
+
+.multi-select.flex-column {
+ justify-content: space-between;
+}
+
+.multi-select-container.flex-column * {
+ margin: 0.2em 0;
+}
+
+.multi-select-container.flex-column {
+ flex-wrap: nowrap;
+}
+
+.arrows-container {
+ width: 50px;
+}
+
+.multi-select-container .filter input,
+.multi-select-container .filter select {
+ float: right;
+ width: 50%;
+ text-align: left;
+}
+.multi-select-container .filter input[type="checkbox"] {
+ width: auto;
+}
+
+.group-filter.flex-row-vcenter div,
+.item-filter.flex-row-vcenter div {
+ flex: 1 1 auto;
+ width: 100%;
+}
+
+.multi-select-container .title {
+ text-align: center;
+ font-style: italic;
+ margin-top: 1em;
+ color: #424242;
+}
+
+.multi-select-container.flex-column div {
+ text-align: left;
+}
+
+.multi-select-container.flex-column div input {
+ margin-left: 1em;
+}
diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css
index 3ab99bb7e6..eabdea9ecf 100644
--- a/pandora_console/include/styles/pandora.css
+++ b/pandora_console/include/styles/pandora.css
@@ -462,29 +462,45 @@ select:-internal-list-box {
.mw250px {
min-width: 250px;
}
+.mw500px {
+ min-width: 500px;
+}
+.mw600px {
+ min-width: 600px;
+}
+.mw800px {
+ min-width: 800px;
+}
.w20px {
width: 20px;
}
.w10p {
width: 10%;
}
-
.w20p {
width: 20%;
}
-
.w30p {
width: 30%;
}
-
.w40p {
width: 40%;
}
-
.w50p {
width: 50%;
}
-
+.w60p {
+ width: 60%;
+}
+.w70p {
+ width: 70%;
+}
+.w80p {
+ width: 80%;
+}
+.w90p {
+ width: 90%;
+}
.w100p {
width: 100%;
}
diff --git a/pandora_console/operation/agentes/estado_agente.php b/pandora_console/operation/agentes/estado_agente.php
index b1e53b88d2..342738fc7b 100644
--- a/pandora_console/operation/agentes/estado_agente.php
+++ b/pandora_console/operation/agentes/estado_agente.php
@@ -798,8 +798,18 @@ foreach ($agents as $agent) {
$data[0] .= '
';
- if ($agent['id_os'] == 100) {
- $data[0] .= '
'.__('View').'';
+ if ($agent['id_os'] == CLUSTER_OS_ID) {
+ if (enterprise_installed()) {
+ $cluster = PandoraFMS\Enterprise\Cluster::loadFromAgentId(
+ $agent['id_agente']
+ );
+ $url = 'index.php?sec=reporting&sec2='.ENTERPRISE_DIR;
+ $url .= '/operation/cluster/cluster';
+ $url = ui_get_full_url(
+ $url.'&op=view&id='.$cluster->id()
+ );
+ $data[0] .= '
'.__('View').'';
+ }
} else {
$data[0] .= '
'.__('View').'';
}
@@ -807,8 +817,18 @@ foreach ($agents as $agent) {
if (check_acl($config['id_user'], $agent['id_grupo'], 'AW')) {
$data[0] .= ' | ';
- if ($agent['id_os'] == 100) {
- $data[0] .= '
'.__('Edit').'';
+ if ($agent['id_os'] == CLUSTER_OS_ID) {
+ if (enterprise_installed()) {
+ $cluster = PandoraFMS\Enterprise\Cluster::loadFromAgentId(
+ $agent['id_agente']
+ );
+ $url = 'index.php?sec=reporting&sec2='.ENTERPRISE_DIR;
+ $url .= '/operation/cluster/cluster';
+ $url = ui_get_full_url(
+ $url.'&op=update&id='.$cluster->id()
+ );
+ $data[0] .= '
'.__('Edit').'';
+ }
} else {
$data[0] .= '
'.__('Edit').'';
}
diff --git a/pandora_console/operation/agentes/estado_monitores.php b/pandora_console/operation/agentes/estado_monitores.php
index d50ed3a0fb..37b23e622c 100755
--- a/pandora_console/operation/agentes/estado_monitores.php
+++ b/pandora_console/operation/agentes/estado_monitores.php
@@ -148,8 +148,10 @@ $sort = get_parameter('sort', 'up');
$modules_not_init = agents_monitor_notinit($id_agente);
-if (!empty($modules_not_init)) {
- $help_not_init = clippy_context_help('modules_not_init');
+if (empty($modules_not_init) === false) {
+ $help_not_init = ui_print_warning_message(
+ __('No initialized modules found.')
+ );
} else {
$help_not_init = '';
}
diff --git a/pandora_console/operation/users/user_edit.php b/pandora_console/operation/users/user_edit.php
index 68481936bf..23b797a8f2 100644
--- a/pandora_console/operation/users/user_edit.php
+++ b/pandora_console/operation/users/user_edit.php
@@ -463,7 +463,7 @@ $autorefresh_list_out['operation/snmpconsole/snmp_view'] = 'SNMP console';
$autorefresh_list_out['operation/agentes/pandora_networkmap'] = 'Network map';
$autorefresh_list_out['operation/visual_console/render_view'] = 'Visual console';
$autorefresh_list_out['operation/events/events'] = 'Events';
-$autorefresh_list_out['enterprise/godmode/reporting/cluster_view'] = 'Cluster view';
+$autorefresh_list_out['enterprise/operation/cluster/cluster'] = 'Cluster view';
if (enterprise_installed()) {
$autorefresh_list_out['general/sap_view'] = 'SAP view';
}
diff --git a/pandora_console/vendor/composer/LICENSE b/pandora_console/vendor/composer/LICENSE
index f27399a042..62ecfd8d00 100644
--- a/pandora_console/vendor/composer/LICENSE
+++ b/pandora_console/vendor/composer/LICENSE
@@ -1,4 +1,3 @@
-
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -18,4 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-
diff --git a/pandora_console/vendor/composer/autoload_classmap.php b/pandora_console/vendor/composer/autoload_classmap.php
index dea0865c69..a45d82291a 100644
--- a/pandora_console/vendor/composer/autoload_classmap.php
+++ b/pandora_console/vendor/composer/autoload_classmap.php
@@ -308,9 +308,44 @@ return array(
'Mpdf\\Utils\\NumericString' => $vendorDir . '/mpdf/mpdf/src/Utils/NumericString.php',
'Mpdf\\Utils\\PdfDate' => $vendorDir . '/mpdf/mpdf/src/Utils/PdfDate.php',
'Mpdf\\Utils\\UtfString' => $vendorDir . '/mpdf/mpdf/src/Utils/UtfString.php',
+ 'PandoraFMS\\Agent' => $baseDir . '/include/lib/Agent.php',
+ 'PandoraFMS\\Dashboard\\AgentModuleWidget' => $baseDir . '/include/lib/Dashboard/Widgets/agent_module.php',
+ 'PandoraFMS\\Dashboard\\AlertsFiredWidget' => $baseDir . '/include/lib/Dashboard/Widgets/alerts_fired.php',
'PandoraFMS\\Dashboard\\Cell' => $baseDir . '/include/lib/Dashboard/Cell.php',
+ 'PandoraFMS\\Dashboard\\ClockWidget' => $baseDir . '/include/lib/Dashboard/Widgets/clock.php',
+ 'PandoraFMS\\Dashboard\\CustomGraphWidget' => $baseDir . '/include/lib/Dashboard/Widgets/custom_graph.php',
+ 'PandoraFMS\\Dashboard\\EventsListWidget' => $baseDir . '/include/lib/Dashboard/Widgets/events_list.php',
+ 'PandoraFMS\\Dashboard\\GraphModuleHistogramWidget' => $baseDir . '/include/lib/Dashboard/Widgets/graph_module_histogram.php',
+ 'PandoraFMS\\Dashboard\\GroupsStatusWidget' => $baseDir . '/include/lib/Dashboard/Widgets/groups_status.php',
'PandoraFMS\\Dashboard\\Manager' => $baseDir . '/include/lib/Dashboard/Manager.php',
+ 'PandoraFMS\\Dashboard\\MapsMadeByUser' => $baseDir . '/include/lib/Dashboard/Widgets/maps_made_by_user.php',
+ 'PandoraFMS\\Dashboard\\MapsStatusWidget' => $baseDir . '/include/lib/Dashboard/Widgets/maps_status.php',
+ 'PandoraFMS\\Dashboard\\ModuleIconWidget' => $baseDir . '/include/lib/Dashboard/Widgets/module_icon.php',
+ 'PandoraFMS\\Dashboard\\ModuleStatusWidget' => $baseDir . '/include/lib/Dashboard/Widgets/module_status.php',
+ 'PandoraFMS\\Dashboard\\ModuleTableValueWidget' => $baseDir . '/include/lib/Dashboard/Widgets/module_table_value.php',
+ 'PandoraFMS\\Dashboard\\ModuleValueWidget' => $baseDir . '/include/lib/Dashboard/Widgets/module_value.php',
+ 'PandoraFMS\\Dashboard\\MonitorHealthWidget' => $baseDir . '/include/lib/Dashboard/Widgets/monitor_health.php',
+ 'PandoraFMS\\Dashboard\\NetworkMapWidget' => $baseDir . '/include/lib/Dashboard/Widgets/network_map.php',
+ 'PandoraFMS\\Dashboard\\PostWidget' => $baseDir . '/include/lib/Dashboard/Widgets/post.php',
+ 'PandoraFMS\\Dashboard\\ReportsWidget' => $baseDir . '/include/lib/Dashboard/Widgets/reports.php',
+ 'PandoraFMS\\Dashboard\\SLAPercentWidget' => $baseDir . '/include/lib/Dashboard/Widgets/sla_percent.php',
+ 'PandoraFMS\\Dashboard\\ServiceMapWidget' => $baseDir . '/include/lib/Dashboard/Widgets/service_map.php',
+ 'PandoraFMS\\Dashboard\\SingleGraphWidget' => $baseDir . '/include/lib/Dashboard/Widgets/single_graph.php',
+ 'PandoraFMS\\Dashboard\\SystemGroupStatusWidget' => $baseDir . '/include/lib/Dashboard/Widgets/system_group_status.php',
+ 'PandoraFMS\\Dashboard\\TacticalWidget' => $baseDir . '/include/lib/Dashboard/Widgets/tactical.php',
+ 'PandoraFMS\\Dashboard\\TopNEventByGroupWidget' => $baseDir . '/include/lib/Dashboard/Widgets/top_n_events_by_group.php',
+ 'PandoraFMS\\Dashboard\\TopNEventByModuleWidget' => $baseDir . '/include/lib/Dashboard/Widgets/top_n_events_by_module.php',
+ 'PandoraFMS\\Dashboard\\TopNWidget' => $baseDir . '/include/lib/Dashboard/Widgets/top_n.php',
+ 'PandoraFMS\\Dashboard\\TreeViewWidget' => $baseDir . '/include/lib/Dashboard/Widgets/tree_view.php',
+ 'PandoraFMS\\Dashboard\\UrlWidget' => $baseDir . '/include/lib/Dashboard/Widgets/url.php',
+ 'PandoraFMS\\Dashboard\\WelcomeWidget' => $baseDir . '/include/lib/Dashboard/Widgets/example.php',
+ 'PandoraFMS\\Dashboard\\Widget' => $baseDir . '/include/lib/Dashboard/Widget.php',
+ 'PandoraFMS\\Dashboard\\WuxStatsWidget' => $baseDir . '/include/lib/Dashboard/Widgets/wux_transaction_stats.php',
+ 'PandoraFMS\\Dashboard\\WuxWidget' => $baseDir . '/include/lib/Dashboard/Widgets/wux_transaction.php',
+ 'PandoraFMS\\Entity' => $baseDir . '/include/lib/Entity.php',
+ 'PandoraFMS\\Group' => $baseDir . '/include/lib/Group.php',
'PandoraFMS\\User' => $baseDir . '/include/lib/User.php',
+ 'PandoraFMS\\View' => $baseDir . '/include/lib/View.php',
'PandoraFMS\\WebSockets\\WSManager' => $baseDir . '/include/lib/WSManager.php',
'PandoraFMS\\Websockets\\WebSocketServer' => $baseDir . '/include/lib/WebSocketServer.php',
'PandoraFMS\\Websockets\\WebSocketUser' => $baseDir . '/include/lib/WebSocketUser.php',
diff --git a/pandora_console/vendor/composer/autoload_real.php b/pandora_console/vendor/composer/autoload_real.php
index d93d1d70ef..8576380cc1 100644
--- a/pandora_console/vendor/composer/autoload_real.php
+++ b/pandora_console/vendor/composer/autoload_real.php
@@ -13,6 +13,9 @@ class ComposerAutoloaderInitfdecadadce22e6dde51e9535fe4ad7aa
}
}
+ /**
+ * @return \Composer\Autoload\ClassLoader
+ */
public static function getLoader()
{
if (null !== self::$loader) {
diff --git a/pandora_console/vendor/composer/autoload_static.php b/pandora_console/vendor/composer/autoload_static.php
index b59d14b744..1dc3c32bc7 100644
--- a/pandora_console/vendor/composer/autoload_static.php
+++ b/pandora_console/vendor/composer/autoload_static.php
@@ -390,9 +390,44 @@ class ComposerStaticInitfdecadadce22e6dde51e9535fe4ad7aa
'Mpdf\\Utils\\NumericString' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/NumericString.php',
'Mpdf\\Utils\\PdfDate' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/PdfDate.php',
'Mpdf\\Utils\\UtfString' => __DIR__ . '/..' . '/mpdf/mpdf/src/Utils/UtfString.php',
+ 'PandoraFMS\\Agent' => __DIR__ . '/../..' . '/include/lib/Agent.php',
+ 'PandoraFMS\\Dashboard\\AgentModuleWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/agent_module.php',
+ 'PandoraFMS\\Dashboard\\AlertsFiredWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/alerts_fired.php',
'PandoraFMS\\Dashboard\\Cell' => __DIR__ . '/../..' . '/include/lib/Dashboard/Cell.php',
+ 'PandoraFMS\\Dashboard\\ClockWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/clock.php',
+ 'PandoraFMS\\Dashboard\\CustomGraphWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/custom_graph.php',
+ 'PandoraFMS\\Dashboard\\EventsListWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/events_list.php',
+ 'PandoraFMS\\Dashboard\\GraphModuleHistogramWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/graph_module_histogram.php',
+ 'PandoraFMS\\Dashboard\\GroupsStatusWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/groups_status.php',
'PandoraFMS\\Dashboard\\Manager' => __DIR__ . '/../..' . '/include/lib/Dashboard/Manager.php',
+ 'PandoraFMS\\Dashboard\\MapsMadeByUser' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/maps_made_by_user.php',
+ 'PandoraFMS\\Dashboard\\MapsStatusWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/maps_status.php',
+ 'PandoraFMS\\Dashboard\\ModuleIconWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/module_icon.php',
+ 'PandoraFMS\\Dashboard\\ModuleStatusWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/module_status.php',
+ 'PandoraFMS\\Dashboard\\ModuleTableValueWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/module_table_value.php',
+ 'PandoraFMS\\Dashboard\\ModuleValueWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/module_value.php',
+ 'PandoraFMS\\Dashboard\\MonitorHealthWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/monitor_health.php',
+ 'PandoraFMS\\Dashboard\\NetworkMapWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/network_map.php',
+ 'PandoraFMS\\Dashboard\\PostWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/post.php',
+ 'PandoraFMS\\Dashboard\\ReportsWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/reports.php',
+ 'PandoraFMS\\Dashboard\\SLAPercentWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/sla_percent.php',
+ 'PandoraFMS\\Dashboard\\ServiceMapWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/service_map.php',
+ 'PandoraFMS\\Dashboard\\SingleGraphWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/single_graph.php',
+ 'PandoraFMS\\Dashboard\\SystemGroupStatusWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/system_group_status.php',
+ 'PandoraFMS\\Dashboard\\TacticalWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/tactical.php',
+ 'PandoraFMS\\Dashboard\\TopNEventByGroupWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/top_n_events_by_group.php',
+ 'PandoraFMS\\Dashboard\\TopNEventByModuleWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/top_n_events_by_module.php',
+ 'PandoraFMS\\Dashboard\\TopNWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/top_n.php',
+ 'PandoraFMS\\Dashboard\\TreeViewWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/tree_view.php',
+ 'PandoraFMS\\Dashboard\\UrlWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/url.php',
+ 'PandoraFMS\\Dashboard\\WelcomeWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/example.php',
+ 'PandoraFMS\\Dashboard\\Widget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widget.php',
+ 'PandoraFMS\\Dashboard\\WuxStatsWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/wux_transaction_stats.php',
+ 'PandoraFMS\\Dashboard\\WuxWidget' => __DIR__ . '/../..' . '/include/lib/Dashboard/Widgets/wux_transaction.php',
+ 'PandoraFMS\\Entity' => __DIR__ . '/../..' . '/include/lib/Entity.php',
+ 'PandoraFMS\\Group' => __DIR__ . '/../..' . '/include/lib/Group.php',
'PandoraFMS\\User' => __DIR__ . '/../..' . '/include/lib/User.php',
+ 'PandoraFMS\\View' => __DIR__ . '/../..' . '/include/lib/View.php',
'PandoraFMS\\WebSockets\\WSManager' => __DIR__ . '/../..' . '/include/lib/WSManager.php',
'PandoraFMS\\Websockets\\WebSocketServer' => __DIR__ . '/../..' . '/include/lib/WebSocketServer.php',
'PandoraFMS\\Websockets\\WebSocketUser' => __DIR__ . '/../..' . '/include/lib/WebSocketUser.php',
diff --git a/pandora_console/views/dashboard/configurationWidgets.php b/pandora_console/views/dashboard/configurationWidgets.php
index aa65b06776..2e88ce35a6 100644
--- a/pandora_console/views/dashboard/configurationWidgets.php
+++ b/pandora_console/views/dashboard/configurationWidgets.php
@@ -47,8 +47,7 @@ $form = [
'extra' => 'novalidate',
];
-$html = new HTML();
-$html->printForm(
+HTML::printForm(
[
'form' => $form,
'inputs' => $htmlInputs,
diff --git a/pandora_console/views/dashboard/formDashboard.php b/pandora_console/views/dashboard/formDashboard.php
index 57a63455e7..b80f3ab557 100644
--- a/pandora_console/views/dashboard/formDashboard.php
+++ b/pandora_console/views/dashboard/formDashboard.php
@@ -120,8 +120,7 @@ $inputs = [
],
];
-$html = new HTML();
-$html->printForm(
+HTML::printForm(
[
'form' => $form,
'inputs' => $inputs,
diff --git a/pandora_console/views/dashboard/formSlides.php b/pandora_console/views/dashboard/formSlides.php
index c01a3b8d31..3421a05afc 100644
--- a/pandora_console/views/dashboard/formSlides.php
+++ b/pandora_console/views/dashboard/formSlides.php
@@ -84,8 +84,7 @@ $inputs[] = [
],
];
-$html = new HTML();
-$html->printForm(
+HTML::printForm(
[
'form' => $form,
'inputs' => $inputs,
diff --git a/pandora_console/views/dashboard/listWidgets.php b/pandora_console/views/dashboard/listWidgets.php
index 24d96acffb..f460ab824e 100644
--- a/pandora_console/views/dashboard/listWidgets.php
+++ b/pandora_console/views/dashboard/listWidgets.php
@@ -52,8 +52,7 @@ $inputs = [
],
];
-$html = new HTML();
-$html->printForm(
+HTML::printForm(
[
'form' => $form,
'inputs' => $inputs,
diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm
index cbb21d42fb..2b57922a80 100644
--- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm
+++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm
@@ -1404,63 +1404,64 @@ sub PandoraFMS::Recon::Base::report_scanned_agents($;$) {
$self->call('message', "Storing results", 6);
my @hosts = keys %{$self->{'agents_found'}};
$self->{'step'} = STEP_PROCESSING;
- my ($progress, $step) = (90, 10.0 / scalar(@hosts)); # From 90% to 100%.
+ if ((scalar (@hosts)) > 0) {
+ my ($progress, $step) = (90, 10.0 / scalar(@hosts)); # From 90% to 100%.
- foreach my $addr (keys %{$self->{'agents_found'}}) {
- my $label = $self->{'agents_found'}->{$addr}{'agent'}{'nombre'};
+ foreach my $addr (keys %{$self->{'agents_found'}}) {
+ my $label = $self->{'agents_found'}->{$addr}{'agent'}{'nombre'};
- next if is_empty($label);
+ next if is_empty($label);
- # Retrieve target agent OS version.
- $self->{'agents_found'}->{$addr}{'agent'}{'id_os'} = $self->guess_os($addr);
+ # Retrieve target agent OS version.
+ $self->{'agents_found'}->{$addr}{'agent'}{'id_os'} = $self->guess_os($addr);
- $self->call('update_progress', $progress);
- $progress += $step;
- # Store temporally. Wait user approval.
- my $encoded;
+ $self->call('update_progress', $progress);
+ $progress += $step;
+ # Store temporally. Wait user approval.
+ my $encoded;
- eval {
- local $SIG{__DIE__};
- $encoded = encode_base64(
- p_encode_json($self->{'pa_config'}, $self->{'agents_found'}->{$addr})
- );
- };
+ eval {
+ local $SIG{__DIE__};
+ $encoded = encode_base64(
+ p_encode_json($self->{'pa_config'}, $self->{'agents_found'}->{$addr})
+ );
+ };
- my $id = get_db_value(
- $self->{'dbh'},
- 'SELECT id FROM tdiscovery_tmp_agents WHERE id_rt = ? AND label = ?',
- $self->{'task_data'}{'id_rt'},
- safe_input($label)
- );
-
- if (defined($id)) {
- # Already defined.
- $self->{'agents_found'}{$addr}{'id'} = $id;
-
- db_do(
+ my $id = get_db_value(
$self->{'dbh'},
- 'UPDATE tdiscovery_tmp_agents SET `data` = ? '
- .'WHERE `id_rt` = ? AND `label` = ?',
- $encoded,
+ 'SELECT id FROM tdiscovery_tmp_agents WHERE id_rt = ? AND label = ?',
$self->{'task_data'}{'id_rt'},
safe_input($label)
);
- next;
+
+ if (defined($id)) {
+ # Already defined.
+ $self->{'agents_found'}{$addr}{'id'} = $id;
+
+ db_do(
+ $self->{'dbh'},
+ 'UPDATE tdiscovery_tmp_agents SET `data` = ? '
+ .'WHERE `id_rt` = ? AND `label` = ?',
+ $encoded,
+ $self->{'task_data'}{'id_rt'},
+ safe_input($label)
+ );
+ next;
+ }
+
+ # Insert.
+ $self->{'agents_found'}{$addr}{'id'} = db_insert(
+ $self->{'dbh'},
+ 'id',
+ 'INSERT INTO tdiscovery_tmp_agents (`id_rt`,`label`,`data`,`created`) '
+ .'VALUES (?, ?, ?, now())',
+ $self->{'task_data'}{'id_rt'},
+ safe_input($label),
+ $encoded
+ );
}
-
- # Insert.
- $self->{'agents_found'}{$addr}{'id'} = db_insert(
- $self->{'dbh'},
- 'id',
- 'INSERT INTO tdiscovery_tmp_agents (`id_rt`,`label`,`data`,`created`) '
- .'VALUES (?, ?, ?, now())',
- $self->{'task_data'}{'id_rt'},
- safe_input($label),
- $encoded
- );
}
-
if(defined($self->{'task_data'}{'review_mode'})
&& $self->{'task_data'}{'review_mode'} == DISCOVERY_REVIEW
) {
diff --git a/tests/enterprise_base/Dockerfile b/tests/enterprise_base/Dockerfile
index 1d7d10466e..22e3bb5703 100644
--- a/tests/enterprise_base/Dockerfile
+++ b/tests/enterprise_base/Dockerfile
@@ -1,4 +1,4 @@
-FROM pandorafms/pandorafms-base
+FROM pandorafms/pandorafms-base:centos7
MAINTAINER Pandora FMS Team
# Pandora FMS Server dependencies