Merge branch 'ent-2685-7938-aadcm-dashboards-en-metaconsola' into 'develop'

dashboards meta

See merge request artica/pandorafms!3840
This commit is contained in:
Daniel Rodriguez 2021-04-07 10:53:31 +00:00
commit ed6fa1a803
25 changed files with 931 additions and 152 deletions

View File

@ -1727,7 +1727,10 @@ class NetworkMap
$item['image_height'] = 0;
if (empty($node['style']['image']) === false) {
$item['image_url'] = ui_get_full_url(
$node['style']['image']
$node['style']['image'],
false,
false,
false
);
$image_size = getimagesize(
$config['homedir'].'/'.$node['style']['image']
@ -3391,7 +3394,7 @@ class NetworkMap
&& isset($this->useTooltipster)
&& $this->useTooltipster == true
) {
$output .= '<script type="text/javascript" src="'.ui_get_full_url(
$output = '<script type="text/javascript" src="'.ui_get_full_url(
'include/javascript/d3.3.5.14.js'
).'" charset="utf-8"></script>';
$output .= '<script type="text/javascript" src="'.ui_get_full_url(
@ -3443,13 +3446,35 @@ class NetworkMap
$networkmap['filter']['l2_network_interfaces'] = 1;
$output .= '<script type="text/javascript" src="'.$config['homeurl'].'include/javascript/d3.3.5.14.js" charset="utf-8"></script>';
$output .= '<script type="text/javascript" src="';
$output .= ui_get_full_url(
'include/javascript/d3.3.5.14.js',
false,
false,
false
);
$output .= '" charset="utf-8"></script>';
if (isset($this->map['__simulated']) === false) {
// Load context menu if manageable networkmap.
$output .= '<script type="text/javascript" src="'.$config['homeurl'].'include/javascript/jquery.contextMenu.js"></script>';
$output .= '<script type="text/javascript" src="';
$output .= ui_get_full_url(
'include/javascript/jquery.contextMenu.js',
false,
false,
false
);
$output .= '" charset="utf-8"></script>';
}
$output .= '<script type="text/javascript" src="'.$config['homeurl'].'include/javascript/functions_pandora_networkmap.js"></script>';
$output .= '<script type="text/javascript" src="';
$output .= ui_get_full_url(
'include/javascript/functions_pandora_networkmap.js',
false,
false,
false
);
$output .= '" charset="utf-8"></script>';
// Open networkconsole_id div.
$output .= '<div id="networkconsole_'.$networkmap['id'].'"';

View File

@ -1084,6 +1084,7 @@ function agents_common_modules($id_agent, $filter=false, $indexed=true, $get_not
* @param string $separator Only in metaconsole. Separator for the serialized data. By default |.
* @param boolean $add_alert_bulk_op //TODO documentation
* @param boolean $force_serialized. If the agent has not id_server (typically in node) put 0 as <server_id>.
* @param boolean $meta_fields If true, then id_agente is returned instead id_tagente.
*
* @return array An array with all agents in the group or an empty array
*/
@ -1096,7 +1097,8 @@ function agents_get_group_agents(
$serialized=false,
$separator='|',
$add_alert_bulk_op=false,
$force_serialized=false
$force_serialized=false,
$meta_fields=false
) {
global $config;
@ -1268,11 +1270,19 @@ function agents_get_group_agents(
if (is_metaconsole()) {
$table_name = 'tmetaconsole_agent ta LEFT JOIN tmetaconsole_agent_secondary_group tasg ON ta.id_agente = tasg.id_agent';
$fields = [
'ta.id_tagente AS id_agente',
'alias',
'ta.id_tmetaconsole_setup AS id_server',
];
if ($meta_fields === true) {
$fields = [
'id_agente',
'alias',
'ta.id_tmetaconsole_setup AS id_server',
];
} else {
$fields = [
'ta.id_tagente AS id_agente',
'alias',
'ta.id_tmetaconsole_setup AS id_server',
];
}
} else {
$table_name = 'tagente LEFT JOIN tagent_secondary_group ON id_agente=id_agent';
@ -3253,6 +3263,7 @@ function agents_get_agent_custom_field($agent_id, $custom_field_name)
* @param boolean $selection Show common (false) or all modules (true).
* @param boolean $return Return (false) or dump to output (true).
* @param boolean $index_by_name Use module name as key.
* @param boolean $pure_return Return as retrieved from DB.
*
* @return array With modules or null if error.
*/
@ -3261,7 +3272,8 @@ function select_modules_for_agent_group(
$id_agents,
$selection,
$return=true,
$index_by_name=false
$index_by_name=false,
$pure_return=false
) {
global $config;
$agents = (empty($id_agents)) ? [] : implode(',', $id_agents);
@ -3341,6 +3353,10 @@ function select_modules_for_agent_group(
return;
}
if ($pure_return === true) {
return $modules;
}
$modules_array = [];
foreach ($modules as $value) {
if ($index_by_name) {

View File

@ -133,9 +133,14 @@ function custom_graphs_get_user($id_user=0, $only_names=false, $returnAllGroup=t
continue;
}
$all_graph = db_get_all_rows_in_table('tgraph', 'name');
if ($all_graph !== false) {
$all_graphs = array_merge($all_graphs, $all_graph);
$tmp_graphs = db_get_all_rows_in_table('tgraph', 'name');
if ($tmp_graphs !== false) {
foreach ($tmp_graphs as $g) {
$g['id_tgraph'] = $g['id_graph'];
$g['id_graph'] = $connection['id'].'|'.$g['id_graph'];
$g['name'] = $g['name'].' ('.$connection['server_name'].')';
$all_graphs[] = $g;
}
}
metaconsole_restore_db();
@ -168,10 +173,15 @@ function custom_graphs_get_user($id_user=0, $only_names=false, $returnAllGroup=t
$graphs[$graph['id_graph']] = $graph['name'];
} else {
$graphs[$graph['id_graph']] = $graph;
$id_graph = 'id_graph';
if ((bool) is_metaconsole() === true) {
$id_graph = 'id_tgraph';
}
$graphsCount = db_get_value_sql(
'SELECT COUNT(id_gs)
FROM tgraph_source
WHERE id_graph = '.$graph['id_graph']
WHERE id_graph = '.$graph[$id_graph]
);
$graphs[$graph['id_graph']]['graphs_count'] = $graphsCount;
}

View File

@ -712,6 +712,7 @@ function events_update_status($id_evento, $status, $filter=null, $history=false)
* @param boolean $validatedEvents If true, evaluate validated events.
* @param boolean $recursiveGroups If true, filtered groups and their children
* will be search.
* @param boolean $nodeConnected Already connected to node (uses tevento).
*
* @return array Events.
* @throws Exception On error.
@ -727,7 +728,8 @@ function events_get_all(
$return_sql=false,
$having='',
$validatedEvents=false,
$recursiveGroups=true
$recursiveGroups=true,
$nodeConnected=false
) {
global $config;
@ -1017,7 +1019,10 @@ function events_get_all(
);
}
$table = events_get_events_table(is_metaconsole(), $history);
$table = events_get_events_table(
(is_metaconsole() && $nodeConnected === false),
$history
);
$tevento = sprintf(
' %s te',
$table
@ -1028,7 +1033,7 @@ function events_get_all(
$tagente_table = 'tagente';
$tagente_field = 'id_agente';
$conditionMetaconsole = '';
if (is_metaconsole()) {
if (is_metaconsole() && $nodeConnected === false) {
$tagente_table = 'tmetaconsole_agent';
$tagente_field = 'id_tagente';
$conditionMetaconsole = ' AND ta.id_tmetaconsole_setup = te.server_id ';
@ -1075,7 +1080,7 @@ function events_get_all(
);
}
if (is_metaconsole()) {
if (is_metaconsole() && $nodeConnected === false) {
// Id source event.
if (!empty($filter['id_source_event'])) {
$sql_filters[] = sprintf(
@ -1239,7 +1244,7 @@ function events_get_all(
// Query_table.
'',
// Meta.
is_metaconsole(),
is_metaconsole() && $nodeConnected === false,
// Childrens_ids.
[],
// Force_group_and_tag.
@ -1265,7 +1270,7 @@ function events_get_all(
// Query_table.
'',
// Meta.
is_metaconsole(),
is_metaconsole() && $nodeConnected === false,
// Childrens_ids.
[],
// Force_group_and_tag.
@ -1291,7 +1296,7 @@ function events_get_all(
// Query_table.
'',
// Meta.
is_metaconsole(),
is_metaconsole() && $nodeConnected === false,
// Childrens_ids.
[],
// Force_group_and_tag.
@ -1312,7 +1317,7 @@ function events_get_all(
// Module search.
$agentmodule_join = 'LEFT JOIN tagente_modulo am ON te.id_agentmodule = am.id_agente_modulo';
if (is_metaconsole()) {
if (is_metaconsole() && $nodeConnected === false) {
$agentmodule_join = '';
} else if (!empty($filter['module_search'])) {
$agentmodule_join = 'INNER JOIN tagente_modulo am ON te.id_agentmodule = am.id_agente_modulo';
@ -1339,7 +1344,7 @@ function events_get_all(
}
$extra = '';
if (is_metaconsole()) {
if (is_metaconsole() && $nodeConnected === false) {
$extra = ', server_id';
}
@ -1405,7 +1410,7 @@ function events_get_all(
}
$server_join = '';
if (is_metaconsole()) {
if (is_metaconsole() && $nodeConnected === false) {
$server_join = ' LEFT JOIN tmetaconsole_setup ts
ON ts.id = te.server_id';
if (!empty($filter['server_id'])) {

View File

@ -1391,7 +1391,29 @@ function html_print_select_multiple_modules_filtered(array $data):string
$output .= '<div>';
// Agent.
$agents = agents_get_group_agents($data['mGroup']);
$agents = agents_get_group_agents(
// Id_group.
$data['mGroup'],
// Search.
false,
// Case.
'lower',
// NoACL.
false,
// ChildGroups.
false,
// Serialized.
false,
// Separator.
'|',
// Add_alert_bulk_op.
false,
// Force_serialized.
false,
// Meta_fields.
$data['mMetaFields']
);
if ((empty($agents)) === true || $agents == -1) {
$agents = [];
}
@ -4414,8 +4436,10 @@ function html_print_input($data, $wrapper='div', $input_only=false)
return '';
}
enterprise_include_once('include/functions_metaconsole.php');
if ($config['style'] === 'pandora_black') {
$style = 'style="color: white"';
$style = 'style="color: white"';
}
$output = '';

View File

@ -31,6 +31,7 @@ require_once 'functions_agents.php';
require_once $config['homedir'].'/include/functions_modules.php';
require_once $config['homedir'].'/include/functions_groups.php';
enterprise_include_once('include/functions_networkmap.php');
enterprise_include_once('include/functions_metaconsole.php');
// Check if a node descends from a given node
function networkmap_is_descendant($node, $ascendant, $parents)
@ -1228,7 +1229,7 @@ function networkmap_get_networkmap($id_networkmap, $filter=false, $fields=false,
* @param array Extra filter.
* @param array Fields to get.
*
* @return Networkmap with the given id. False if not available or readable.
* @return array Networkmap with the given id. False if not available or readable.
*/
function networkmap_get_networkmaps(
$id_user=null,
@ -1243,10 +1244,16 @@ function networkmap_get_networkmaps(
$id_user = $config['id_user'];
}
// Configure filters
// Configure filters.
$where = [];
$where['type'] = MAP_TYPE_NETWORKMAP;
$where['id_group'] = array_keys(users_get_groups($id_user, 'AR', $return_all_group));
$where['id_group'] = array_keys(
users_get_groups(
$id_user,
'AR',
$return_all_group
)
);
if (!empty($type)) {
$where['subtype'] = $type;
}
@ -1256,7 +1263,30 @@ function networkmap_get_networkmaps(
$where['order'][1]['field'] = 'name';
$where['order'][1]['order'] = 'ASC';
$networkmaps_raw = db_get_all_rows_filter('tmap', $where);
if ((bool) is_metaconsole() === true) {
$servers = metaconsole_get_connection_names();
foreach ($servers as $key => $server) {
$connection = metaconsole_get_connection($server);
if (metaconsole_connect($connection) != NOERR) {
continue;
}
$tmp_maps = db_get_all_rows_filter('tmap', $where);
if ($tmp_maps !== false) {
foreach ($tmp_maps as $g) {
$g['id_t'] = $g['id'];
$g['id'] = $connection['id'].'_'.$g['id'];
$g['name'] = $g['name'].' ('.$connection['server_name'].')';
$networkmaps_raw[] = $g;
}
}
metaconsole_restore_db();
}
} else {
$networkmaps_raw = db_get_all_rows_filter('tmap', $where);
}
if (empty($networkmaps_raw)) {
return [];
}

View File

@ -21,13 +21,32 @@ function include_javascript_d3($return=false)
if (!$is_include_javascript) {
$is_include_javascript = true;
if (is_metaconsole()) {
$output .= '<script type="text/javascript" src="'.$config['homeurl'].'../../include/javascript/d3.3.5.14.js" charset="utf-8"></script>';
$output .= '<script type="text/javascript" src="'.$config['homeurl'].'../../include/graphs/pandora.d3.js" charset="utf-8"></script>';
} else {
$output .= '<script type="text/javascript" src="'.$config['homeurl'].'include/javascript/d3.3.5.14.js" charset="utf-8"></script>';
$output .= '<script type="text/javascript" src="'.$config['homeurl'].'include/graphs/pandora.d3.js" charset="utf-8"></script>';
}
$output .= '<script type="text/javascript" src="';
$output .= ui_get_full_url(
'include/javascript/d3.3.5.14.js',
false,
false,
false
);
$output .= '" charset="utf-8"></script>';
$output .= '<script type="text/javascript" src="';
$output .= ui_get_full_url(
'include/graphs/bullet.js',
false,
false,
false
);
$output .= '" charset="utf-8"></script>';
$output .= '<script type="text/javascript" src="';
$output .= ui_get_full_url(
'include/graphs/pandora.d3.js',
false,
false,
false
);
$output .= '" charset="utf-8"></script>';
}
if (!$return) {

View File

@ -304,7 +304,7 @@ function initialiceLayout(data) {
},
dataType: "html",
success: function(data) {
console.log(data);
return data;
},
error: function(error) {
console.error(error);
@ -782,7 +782,8 @@ function dashboardLoadNetworkMap(settings) {
auth_class: settings.auth_class,
auth_hash: settings.auth_hash,
id_user: settings.id_user,
ignore_acl: 1
ignore_acl: 1,
node: settings.node
},
dataType: "html",
success: function(data) {

View File

@ -216,8 +216,6 @@ class Cell
*/
public static function getCells(int $dashboardId):array
{
global $config;
$cells = db_get_all_rows_filter(
'twidget_dashboard',
[

View File

@ -178,6 +178,7 @@ class Manager
'saveWidgetIntoCell',
'imageIconDashboardAjax',
'formSlides',
'callWidgetMethod',
];
@ -1014,6 +1015,10 @@ class Manager
// Header.
if ($this->slides === 0) {
if ((bool) \is_metaconsole() === true) {
open_meta_frame();
}
View::render(
'dashboard/header',
[
@ -1098,6 +1103,13 @@ class Manager
'dashboard/jsLayout',
['dashboardId' => $this->dashboardId]
);
if ((bool) \is_metaconsole() === true
&& $this->slides === 0
) {
close_meta_frame();
}
return null;
}
@ -1490,4 +1502,25 @@ class Manager
}
/**
* Call widget method (ajax only).
*
* @param string $method Method to be invoked.
*
* @return boolean Executed or not.
*/
public function callWidgetMethod(string $method):bool
{
$widget = $this->instanceWidget();
if (method_exists($widget, $method) === true) {
$widget->$method();
return true;
}
return false;
}
}

View File

@ -14,7 +14,7 @@ class Widget
*
* @var integer
*/
private $dashboardId;
protected $dashboardId;
/**
* Cell ID.
@ -28,7 +28,7 @@ class Widget
*
* @var integer
*/
private $widgetId;
protected $widgetId;
/**
* Values widget.
@ -37,6 +37,20 @@ class Widget
*/
private $values;
/**
* Target node Id.
*
* @var integer
*/
protected $nodeId;
/**
* Should we show select node in metaconsole environments?
*
* @var boolean
*/
private $showSelectNodeMeta;
/**
* Contructor widget.
@ -56,10 +70,14 @@ class Widget
$this->cellId = $cellId;
$this->dashboardId = $dashboardId;
$this->fields = $this->get();
$this->className = $this->fields['class_name'];
$cellClass = new Cell($this->cellId, $this->dashboardId);
$this->dataCell = $cellClass->get();
$this->values = $this->decoders($this->getOptionsWidget());
if (isset($this->values['node']) === true) {
$this->nodeId = $this->values['node'];
}
}
return $this;
@ -73,8 +91,6 @@ class Widget
*/
public function get()
{
global $config;
$sql = sprintf(
'SELECT *
FROM twidget
@ -417,6 +433,24 @@ class Widget
$output = '';
if ((bool) \is_metaconsole() === true) {
\enterprise_include_once('include/functions_metaconsole.php');
if ($this->nodeId > 0) {
if (\metaconsole_connect(null, $this->nodeId) !== NOERR) {
$output .= '<div class="container-center">';
$output .= \ui_print_info_message(
__('Failed to connect to node %d', $this->nodeId),
'',
true
);
$output .= '</div>';
return $output;
}
$config['metaconsole'] = false;
}
}
if ($this->configurationRequired === true) {
$output .= '<div class="container-center">';
$output .= \ui_print_info_message(
@ -438,6 +472,13 @@ class Widget
$output .= $this->load();
}
if ((bool) \is_metaconsole() === true) {
if ($this->nodeId > 0) {
\metaconsole_restore_db();
$config['metaconsole'] = true;
}
}
return $output;
}
@ -508,6 +549,38 @@ class Widget
],
];
if ((bool) \is_metaconsole() === true
&& $this->shouldSelectNode() === true
) {
\enterprise_include_once('include/functions_metaconsole.php');
$servers = \metaconsole_get_servers();
if (is_array($servers) === true) {
$servers = array_reduce(
$servers,
function ($carry, $item) {
$carry[$item['id']] = $item['server_name'];
return $carry;
}
);
} else {
$servers = [];
}
$inputs[] = [
'label' => __('Node'),
'arguments' => [
'wrapper' => 'div',
'name' => 'node',
'type' => 'select',
'fields' => $servers,
'selected' => $values['node'],
'nothing' => __('This metaconsole'),
'nothing_value' => -1,
'return' => true,
],
];
}
return $inputs;
}
@ -522,6 +595,13 @@ class Widget
$values = [];
$values['title'] = \get_parameter('title', '');
$values['background'] = \get_parameter('background', '#ffffff');
if ((bool) \is_metaconsole() === true) {
if ($this->shouldSelectNode() === true) {
$values['node'] = \get_parameter('node', null);
} else {
$values['node'] = \get_parameter('metaconsoleId', null);
}
}
return $values;
@ -551,6 +631,10 @@ class Widget
$values['background'] = $decoder['background'];
}
if (isset($decoder['node']) === true) {
$values['node'] = $decoder['node'];
}
return $values;
}
@ -589,6 +673,34 @@ class Widget
}
/**
* Should select for nodes been shown while in metaconsole environment?
*
* @return boolean
*/
protected function shouldSelectNode():bool
{
if ($this->showSelectNodeMeta !== null) {
return (bool) $this->showSelectNodeMeta;
}
switch ($this->className) {
case 'EventsListWidget':
case 'ReportsWidget':
case 'MapsMadeByUser':
case 'AlertsFiredWidget':
$this->showSelectNodeMeta = true;
break;
default:
$this->showSelectNodeMeta = false;
break;
}
return (bool) $this->showSelectNodeMeta;
}
/**
* Get description should be implemented for each child.
*

View File

@ -266,6 +266,7 @@ class AgentModuleWidget extends Widget
'mModules' => $this->values['mModules'],
'mShowSelectedOtherGroups' => true,
'mReturnAllGroup' => $return_all_group,
'mMetaFields' => ((bool) is_metaconsole()),
],
];
@ -329,7 +330,7 @@ class AgentModuleWidget extends Widget
$name = $module;
$modules_by_name[$cont]['name'] = $name;
$modules_by_name[$cont]['id'][] = $key;
$cont ++;
$cont++;
}
}
@ -351,7 +352,10 @@ class AgentModuleWidget extends Widget
$agent_modules = db_get_all_rows_sql($sql);
$agent_modules = array_combine(array_column($agent_modules, 'id_agente_modulo'), array_column($agent_modules, 'nombre'));
$agent_modules = array_combine(
array_column($agent_modules, 'id_agente_modulo'),
array_column($agent_modules, 'nombre')
);
$row['modules'] = [];
foreach ($modules_by_name as $module) {
@ -449,6 +453,10 @@ class AgentModuleWidget extends Widget
$table_data .= $file_name;
$table_data .= '</td>';
if ($row['modules'] === null) {
$row['modules'] = [];
}
foreach ($row['modules'] as $module_name => $module) {
if ($module === null) {
if (in_array($module_name, $allModules) === true) {
@ -591,6 +599,7 @@ class AgentModuleWidget extends Widget
{
global $config;
$output = '';
if (check_acl($config['id_user'], 0, 'AR') === 0) {
$output .= '<div class="container-center">';
$output .= ui_print_error_message(
@ -602,27 +611,44 @@ class AgentModuleWidget extends Widget
return $output;
}
// Estract info all modules selected.
// Extract info all modules selected.
$target_modules = explode(',', $this->values['mModules']);
$all_modules = Module::search(
['id_agente_modulo' => $target_modules]
);
$reduceAllModules = array_reduce(
$all_modules,
function ($carry, $item) {
$carry[$item->name()] = null;
return $carry;
}
);
\ksort($reduceAllModules);
if ($all_modules !== null) {
$reduceAllModules = array_reduce(
$all_modules,
function ($carry, $item) {
$carry[$item->name()] = null;
return $carry;
}
);
} else {
$reduceAllModules = [];
}
$visualData = [];
// Estract info agents selected.
// Extract info agents selected.
$target_agents = explode(',', $this->values['mAgents']);
foreach ($target_agents as $agent_id) {
try {
$agent = new Agent($agent_id);
$id_agente = $agent_id;
if ((bool) is_metaconsole() === true) {
$tmeta_agent = db_get_row_filter(
'tmetaconsole_agent',
[ 'id_agente' => $id_agente ]
);
$id_agente = $tmeta_agent['id_tagente'];
$tserver = $tmeta_agent['id_tmetaconsole_setup'];
if (metaconsole_connect(null, $tserver) !== NOERR) {
continue;
}
}
$agent = new Agent((int) $id_agente);
$visualData[$agent_id]['agent_status'] = $agent->lastStatus();
$visualData[$agent_id]['agent_name'] = $agent->name();
$visualData[$agent_id]['agent_alias'] = $agent->alias();
@ -633,14 +659,27 @@ class AgentModuleWidget extends Widget
$visualData[$agent_id]['modules'] = $reduceAllModules;
foreach ($modules as $module) {
if ((bool) is_metaconsole() === true) {
$reduceAllModules[$module->name()] = null;
}
$visualData[$agent_id]['modules'][$module->name()] = $module->getStatus()->estado();
}
} catch (Exception $e) {
echo 'Error: '.$e->getMessage();
if ((bool) is_metaconsole() === true) {
metaconsole_restore_db();
}
} catch (\Exception $e) {
echo 'Error: ['.$agent_id.']'.$e->getMessage();
}
}
ksort($reduceAllModules);
$allModules = array_keys($reduceAllModules);
if ($allModules === null) {
$allModules = [];
}
$output = $this->generateViewAgentModule(
$visualData,
$allModules

View File

@ -200,6 +200,10 @@ class CustomGraphWidget extends Widget
$values['id_graph'] = $decoder['id_graph'];
}
if (isset($decoder['node']) === true) {
$values['node'] = $decoder['node'];
}
if (isset($decoder['stacked']) === true) {
$values['type'] = $decoder['stacked'];
}
@ -252,21 +256,47 @@ class CustomGraphWidget extends Widget
// Custom graph.
$fields = \custom_graphs_get_user(0, false, $return_all_group);
if ((bool) is_metaconsole() === true) {
$selected = $values['node'].'|'.$values['id_graph'];
} else {
$selected = $values['id_graph'];
}
// If currently selected graph is not included in fields array
// (it belongs to a group over which user has no permissions),
// then add it to fields array.
// This is aimed to avoid overriding this value when a user
// with narrower permissions edits widget configuration.
// then user has no grants over this item.
if ($values['id_graph'] !== null
&& array_key_exists($values['id_graph'], $fields) === false
&& array_key_exists($selected, $fields) === false
) {
$selected_graph = db_get_row(
if ((bool) is_metaconsole() === true) {
$server_name = \db_get_value(
'server_name',
'tmetaconsole_setup',
'id',
$values['node']
);
metaconsole_connect(null, $values['node']);
}
$name = \db_get_value(
'name',
'tgraph',
'id_graph',
$values['id_graph']
);
$fields[$values['id_graph']] = $selected_graph;
if ((bool) is_metaconsole() === true) {
metaconsole_restore_db();
}
if ($name === false) {
$name = \__('This graph has been deleted.');
} else {
$name .= ' ('.$server_name.')';
}
$fields[$selected] = $name;
}
$inputs[] = [
@ -275,7 +305,7 @@ class CustomGraphWidget extends Widget
'type' => 'select',
'fields' => $fields,
'name' => 'id_graph',
'selected' => $values['id_graph'],
'selected' => $selected,
'return' => true,
],
];
@ -340,8 +370,49 @@ class CustomGraphWidget extends Widget
{
// Retrieve global - common inputs.
$values = parent::getPost();
$id_graph = \get_parameter('id_graph', null);
if ($id_graph !== null) {
$values['id_graph'] = $id_graph;
if ((bool) is_metaconsole() === true) {
$mc_stuff = explode('|', $values['id_graph']);
$values['node'] = $mc_stuff[0];
$values['id_graph'] = $mc_stuff[1];
}
// VERIFY ACCESS.
$return_all_group = false;
if (users_can_manage_group_all('RM') === true) {
$return_all_group = true;
}
$availables = \custom_graphs_get_user(0, false, $return_all_group);
if ((bool) is_metaconsole() === true) {
$selected = $values['node'].'|'.$values['id_graph'];
} else {
$selected = $values['id_graph'];
}
// If currently selected graph is not included in fields array
// (it belongs to a group over which user has no permissions),
// then user has no grants over this item.
if ($values['id_graph'] !== null
&& array_key_exists($selected, $availables) === false
) {
// User has no access to this graph.
// Keep previous definition if not grant over desired item.
$values['node'] = $this->values['node'];
$values['id_graph'] = $this->values['id_graph'];
}
} else {
// Keep previous definition if not grant over desired item.
$values['node'] = $this->values['node'];
$values['id_graph'] = $this->values['id_graph'];
}
$values['id_graph'] = \get_parameter('id_graph', 0);
$values['type'] = \get_parameter('type', 0);
$values['period'] = \get_parameter('period', 0);
$values['showLegend'] = \get_parameter_switch('showLegend');

View File

@ -603,7 +603,10 @@ class EventsListWidget extends Widget
'ta.alias as agent_name',
'tg.nombre as group_name',
];
if ((bool) \is_metaconsole() === false) {
if ((bool) \is_metaconsole() === false
|| $this->nodeId > 0
) {
$fields[] = 'am.nombre as module_name';
$fields[] = 'am.id_agente_modulo as id_agentmodule';
$fields[] = 'am.custom_id as module_custom_id';
@ -636,7 +639,9 @@ class EventsListWidget extends Widget
// ValidatedEvents.
false,
// Recursive Groups.
(bool) $this->values['groupRecursion']
(bool) $this->values['groupRecursion'],
// Already connected.
($this->nodeId > 0)
);
if ($events === false) {

View File

@ -213,6 +213,81 @@ class MapsMadeByUser extends Widget
}
/**
* Dumps consoles list in json to fullfill select for consoles.
*
* @return void
*/
public function getVisualConsolesList(): void
{
$node_id = \get_parameter('nodeId', $this->nodeId);
if (\is_metaconsole() === true && $node_id > 0) {
if (\metaconsole_connect(null, $node_id) !== NOERR) {
echo json_encode(
['error' => __('Failed to connect to node %d', $node_id) ]
);
}
}
echo json_encode(
$this->getVisualConsoles(),
1
);
if (\is_metaconsole() === true && $node_id > 0) {
\metaconsole_restore_db();
}
}
/**
* Retrieve visual consoles.
*
* @return array
*/
private function getVisualConsoles()
{
global $config;
$return_all_group = false;
if (users_can_manage_group_all('RM')) {
$return_all_group = true;
}
$fields = \visual_map_get_user_layouts(
$config['id_user'],
true,
['can_manage_group_all' => $return_all_group],
$return_all_group
);
foreach ($fields as $k => $v) {
$fields[$k] = \io_safe_output($v);
}
// If currently selected graph is not included in fields array
// (it belongs to a group over which user has no permissions), then add
// it to fields array.
// This is aimed to avoid overriding this value when a user with
// narrower permissions edits widget configuration.
if ($this->values['vcId'] !== null
&& array_key_exists($this->values['vcId'], $fields) === false
) {
$selected_vc = db_get_value(
'name',
'tlayout',
'id',
$this->values['vcId']
);
$fields[$this->values['vcId']] = $selected_vc;
}
return $fields;
}
/**
* Generates inputs for form (specific).
*
@ -229,31 +304,13 @@ class MapsMadeByUser extends Widget
// Retrieve global - common inputs.
$inputs = parent::getFormInputs();
$return_all_group = false;
if (users_can_manage_group_all('RM')) {
$return_all_group = true;
}
$fields = \visual_map_get_user_layouts(
$config['id_user'],
true,
['can_manage_group_all' => $return_all_group],
$return_all_group
);
// If currently selected graph is not included in fields array (it belongs to a group over which user has no permissions), then add it to fields array.
// This is aimed to avoid overriding this value when a user with narrower permissions edits widget configuration.
if ($values['vcId'] !== null && !array_key_exists($values['vcId'], $fields)) {
$selected_vc = db_get_value('name', 'tlayout', 'id', $values['vcId']);
$fields[$values['vcId']] = $selected_vc;
}
$fields = $this->getVisualConsoles();
// Visual console.
$inputs[] = [
'label' => __('Visual console'),
'arguments' => [
'id' => 'vcId',
'type' => 'select',
'fields' => $fields,
'name' => 'vcId',
@ -476,4 +533,51 @@ class MapsMadeByUser extends Widget
}
/**
* Return aux javascript code for forms.
*
* @return string
*/
public function getFormJS()
{
ob_start();
?>
$('#node').on('change', function() {
$.ajax({
method: "POST",
url: '<?php echo \ui_get_full_url('ajax.php'); ?>',
data: {
page: 'operation/dashboard/dashboard',
dashboardId: '<?php echo $this->dashboardId; ?>',
widgetId: '<?php echo $this->widgetId; ?>',
cellId: '<?php echo $this->cellId; ?>',
class: '<?php echo __CLASS__; ?>',
method: 'getVisualConsolesList',
nodeId: $('#node').val()
},
dataType: 'JSON',
success: function(data) {
console.log(data);
$('#vcId').empty();
Object.entries(data).forEach(e => {
key = e[0];
value = e[1];
$('#vcId').append($('<option>').val(key).text(value))
});
if (Object.entries(data).length == 0) {
$('#vcId').append(
$('<option>')
.val(-1)
.text("<?php echo __('None'); ?>")
);
}
}
})
});
<?php
$js = ob_get_clean();
return $js;
}
}

View File

@ -203,6 +203,10 @@ class NetworkMapWidget extends Widget
$values['networkmapId'] = $decoder['networkmaps'];
}
if (isset($decoder['node']) === true) {
$values['node'] = $decoder['node'];
}
if (isset($decoder['networkmapId']) === true) {
$values['networkmapId'] = $decoder['networkmapId'];
}
@ -268,14 +272,44 @@ class NetworkMapWidget extends Widget
$return_all_group = true;
}
// Selected.
$selected = $values['networkmapId'];
if ((bool) is_metaconsole() === true) {
$selected = $values['node'].'_'.$values['networkmapId'];
} else {
$selected = $values['networkmapId'];
}
// Map.
$fields = \networkmap_get_networkmaps(null, null, true, false, $return_all_group);
$fields = \networkmap_get_networkmaps(
null,
null,
true,
false,
$return_all_group
);
// If currently selected networkmap is not included in fields array (it belongs to a group over which user has no permissions), then add it to fields array.
if ($values['networkmapId'] !== null && !array_key_exists($values['networkmapId'], $fields)) {
$selected_networkmap = db_get_row('tmap', 'id', $values['networkmapId']);
// If currently selected networkmap is not included in fields array
// (it belongs to a group over which user has no permissions), then add
// it to fields array.
if ($values['networkmapId'] !== null
&& array_key_exists($selected, $fields) === false
) {
if ((bool) is_metaconsole() === true) {
metaconsole_connect(null, $values['nodeId']);
}
$fields[$values['networkmapId']] = $selected_networkmap;
$selected_networkmap = db_get_value(
'id',
'tmap',
$values['networkmapId']
);
$fields[$selected] = $selected_networkmap;
if ((bool) is_metaconsole() === true) {
metaconsole_restore_db();
}
}
$inputs[] = [
@ -358,7 +392,18 @@ class NetworkMapWidget extends Widget
// Retrieve global - common inputs.
$values = parent::getPost();
$values['networkmapId'] = \get_parameter('networkmapId', 0);
$nmId = \get_parameter('networkmapId', null);
if ($nmId !== null) {
if ((bool) is_metaconsole() === true) {
$mc_stuff = explode('_', $nmId);
$values['node'] = $mc_stuff[0];
$values['networkmapId'] = $mc_stuff[1];
} else {
$values['networkmapId'] = $nmId;
}
}
$values['xOffset'] = \get_parameter('xOffset', 0);
$values['yOffset'] = \get_parameter('yOffset', 0);
$values['zoomLevel'] = (float) \get_parameter('zoomLevel', 0.5);
@ -382,8 +427,9 @@ class NetworkMapWidget extends Widget
$x_offset = $this->values['xOffset'];
$y_offset = $this->values['yOffset'];
$zoom_dash = $this->values['zoomLevel'];
$node = ($this->values['node'] ?? '');
$hash = md5($config['dbpass'].$id_networkmap.$config['id_user']);
$hash = md5($config['dbpass'].$id_networkmap.$config['id_user'].$node);
$style = 'width:'.$size['width'].'px; height:'.$size['height'].'px;';
$id = 'body_cell-'.$this->cellId;
@ -401,6 +447,7 @@ class NetworkMapWidget extends Widget
'id_user' => $config['id_user'],
'auth_class' => 'PandoraFMS\Dashboard\Manager',
'auth_hash' => Manager::generatePublicHash(),
'node' => $node,
]
);

View File

@ -203,6 +203,90 @@ class ReportsWidget extends Widget
}
/**
* Return report list.
*
* @return array
*/
protected function getReports(): array
{
$return_all_group = false;
if ((bool) users_can_manage_group_all('RM') === true) {
$return_all_group = true;
}
// Reports.
$reports = \reports_get_reports(
false,
[
'id_report',
'name',
],
$return_all_group
);
// If currently selected report is not included in fields array
// (it belongs to a group over which user has no permissions), then add
// it to fields array.
// This is aimed to avoid overriding this value when a user with
// narrower permissions edits widget configuration.
if ($this->values['reportId'] !== null
&& in_array(
$this->values['reportId'],
array_column(
$reports,
'id_report'
)
) === false
) {
$selected_report = db_get_row(
'treport',
'id_report',
$this->values['reportId']
);
$reports[] = $selected_report;
}
$fields = array_reduce(
$reports,
function ($carry, $item) {
$carry[$item['id_report']] = \io_safe_output($item['name']);
return $carry;
},
[]
);
return $fields;
}
/**
* Dumps report list in json to fullfill select for report.
*
* @return void
*/
public function getReportList(): void
{
$node_id = \get_parameter('nodeId', $this->nodeId);
if (\is_metaconsole() === true && $node_id > 0) {
if (\metaconsole_connect(null, $node_id) !== NOERR) {
echo json_encode(
['error' => __('Failed to connect to node %d', $node_id) ]
);
}
}
echo json_encode(
$this->getReports(),
1
);
if (\is_metaconsole() === true && $node_id > 0) {
\metaconsole_restore_db();
}
}
/**
* Generates inputs for form (specific).
*
@ -217,31 +301,7 @@ class ReportsWidget extends Widget
// Retrieve global - common inputs.
$inputs = parent::getFormInputs();
$return_all_group = false;
if (users_can_manage_group_all('RM')) {
$return_all_group = true;
}
// Reports.
$reports = \reports_get_reports(false, ['id_report', 'name'], $return_all_group);
// If currently selected report is not included in fields array (it belongs to a group over which user has no permissions), then add it to fields array.
// This is aimed to avoid overriding this value when a user with narrower permissions edits widget configuration.
if ($values['reportId'] !== null && !in_array($values['reportId'], array_column($reports, 'id_report'))) {
$selected_report = db_get_row('treport', 'id_report', $values['reportId']);
$reports[] = $selected_report;
}
$fields = array_reduce(
$reports,
function ($carry, $item) {
$carry[$item['id_report']] = $item['name'];
return $carry;
},
[]
);
$fields = $this->getReports();
$inputs[] = [
'label' => __('Report'),
@ -282,10 +342,6 @@ class ReportsWidget extends Widget
*/
public function load()
{
global $config;
$size = parent::getSize();
$output = '';
ob_start();
if ($this->values['reportId'] !== 0) {
@ -397,4 +453,50 @@ class ReportsWidget extends Widget
}
/**
* Return aux javascript code for forms.
*
* @return string
*/
public function getFormJS()
{
ob_start();
?>
$('#node').on('change', function() {
$.ajax({
method: "POST",
url: '<?php echo \ui_get_full_url('ajax.php'); ?>',
data: {
page: 'operation/dashboard/dashboard',
dashboardId: '<?php echo $this->dashboardId; ?>',
widgetId: '<?php echo $this->widgetId; ?>',
cellId: '<?php echo $this->cellId; ?>',
class: '<?php echo __CLASS__; ?>',
method: 'getReportList',
nodeId: $('#node').val()
},
dataType: 'JSON',
success: function(data) {
$('#reportId').empty();
Object.entries(data).forEach(e => {
key = e[0];
value = e[1];
$('#reportId').append($('<option>').val(key).text(value))
});
if (Object.entries(data).length == 0) {
$('#reportId').append(
$('<option>')
.val(-1)
.text("<?php echo __('None'); ?>")
);
}
}
})
});
<?php
$js = ob_get_clean();
return $js;
}
}

View File

@ -88,7 +88,7 @@ class Module extends Entity
* @param array $params Search parameters (fields from tagente_modulo).
* @param integer $limit Limit results to N rows.
*
* @return PandoraFMS\Module found or null if not found.
* @return array|null of PandoraFMS\Module found or null if not found.
* @throws \Exception On error.
*/
public static function search(

View File

@ -32,7 +32,6 @@ namespace PandoraFMS;
global $config;
require_once $config['homedir'].'/include/class/HTML.class.php';
use \HTML as HTML;
/**
* View class.

View File

@ -0,0 +1,24 @@
div#page {
width: 90% !important;
margin: 0 auto;
}
.networkconsole {
height: 100%;
}
.networkconsole svg {
height: 100%;
}
.minimap {
position: absolute;
left: 0px;
top: 0px;
border: 1px solid #bbbbbb;
}
.holding_networkmap {
display: none;
position: absolute;
right: 50px;
top: 20px;
}

View File

@ -163,7 +163,9 @@ if (is_ajax()) {
// Add_alert_bulk_op.
$cluster_mode,
// Force_serialized.
false
false,
// Meta fields.
(bool) is_metaconsole()
);
if (empty($agents)) {
@ -192,7 +194,93 @@ if (is_ajax()) {
$id_agents = get_parameter('id_agents');
$selection = get_parameter('selection');
select_modules_for_agent_group($id_group, $id_agents, $selection);
if ((bool) is_metaconsole() === true) {
if (count($id_agents) > 0) {
$rows = db_get_all_rows_sql(
sprintf(
'SELECT `id_agente`, `id_tagente`, `id_tmetaconsole_setup`
FROM `tmetaconsole_agent`
WHERE `id_agente` IN (%s)',
implode(',', $id_agents)
)
);
} else {
$rows = [];
}
$agents = array_reduce(
$rows,
function ($carry, $item) {
if ($carry[$item['id_tmetaconsole_setup']] === null) {
$carry[$item['id_tmetaconsole_setup']] = [];
}
$carry[$item['id_tmetaconsole_setup']][] = $item['id_tagente'];
return $carry;
},
[]
);
$modules = [];
foreach ($agents as $tserver => $id_agents) {
if (metaconsole_connect(null, $tserver) == NOERR) {
$modules[$tserver] = select_modules_for_agent_group(
$id_group,
$id_agents,
$selection,
false,
false,
true
);
metaconsole_restore_db();
}
}
if (!$selection) {
// Common modules.
$final_modules = [];
$nodes_consulted = count($modules);
foreach ($modules as $tserver => $mods) {
foreach ($mods as $module) {
if ($final_modules[$module['nombre']] === null) {
$final_modules[$module['nombre']] = 0;
}
$final_modules[$module['nombre']]++;
}
}
$modules = [];
$i = 1;
foreach ($final_modules as $module_name => $occurrences) {
if ($occurrences === $nodes_consulted) {
// Module already present in ALL nodes.
$modules[] = [
'id_agente_modulo' => ($i++),
'nombre' => $module_name,
];
}
}
} else {
// All modules.
$modules = array_reduce(
$modules[$tserver],
function ($carry, $item) {
$carry[] = $item;
return $carry;
},
[]
);
}
echo json_encode($modules);
} else {
select_modules_for_agent_group($id_group, $id_agents, $selection);
}
}
if ($get_modules_group_value_name_json) {

View File

@ -29,10 +29,14 @@
global $config;
require 'vendor/autoload.php';
require $config['homedir'].'/vendor/autoload.php';
use PandoraFMS\Dashboard\Manager;
if ((bool) is_metaconsole() === true) {
ui_require_css_file('meta_dashboards');
}
$ajaxPage = 'operation/dashboard/dashboard';
// Control call flow.
@ -61,7 +65,9 @@ if (is_ajax() === true) {
$cs->error('Unavailable method.');
}
} else {
$cs->error('Method not found. ['.$method.']');
if ($cs->callWidgetMethod($method) === false) {
$cs->error('Method not found. ['.$method.']');
}
}
} else {
// Run.

View File

@ -274,14 +274,22 @@ if (isset($config['public_dashboard']) === true
}
if ($publicLink === false) {
ui_print_page_header(
$dashboardName,
'',
false,
'',
false,
$buttons
);
if ((bool) is_metaconsole() === true) {
ui_meta_print_header(
__('Dashboards').' » '.__('List'),
false,
$buttons
);
} else {
ui_print_page_header(
$dashboardName,
'',
false,
'',
false,
$buttons
);
}
} else {
$output = '<div id="dashboard-controls">';
foreach ($buttons as $key => $value) {

View File

@ -27,10 +27,18 @@
*/
// Css Files.
\ui_require_css_file('bootstrap.min');
if ((bool) \is_metaconsole() !== true) {
\ui_require_css_file('bootstrap.min');
}
\ui_require_css_file('gridstack.min');
\ui_require_css_file('gridstack-extra.min');
\ui_require_css_file('pandora');
if ((bool) \is_metaconsole() === true) {
\ui_require_css_file('meta_pandora');
} else {
\ui_require_css_file('pandora');
}
\ui_require_css_file('dashboards');
// Js Files.

View File

@ -32,15 +32,20 @@ require_once $config['homedir'].'/include/class/HTML.class.php';
global $config;
ui_require_css_file('dashboards');
if ((bool) \is_metaconsole() === true) {
\ui_require_css_file('meta_dashboards');
}
// Header.
\ui_print_page_header(
__('Dashboards'),
'',
false,
'',
false
);
if ((bool) is_metaconsole() === false) {
\ui_print_page_header(
__('Dashboards'),
'',
false,
'',
false
);
}
if (isset($resultDelete) === true) {
\ui_print_result_message(