pandorafms/pandora_console/include/class/SatelliteCollection.class.php

676 lines
22 KiB
PHP

<?php
// phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
/**
* Controller for collections
*
* @category Controller
* @package Pandora FMS
* @subpackage Community
* @version 1.0.0
* @license See below
*
* ______ ___ _______ _______ ________
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
*
* ============================================================================
* Copyright (c) 2005-2023 Pandora FMS
* Please see https://pandorafms.com/community/ for full contribution list
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation for version 2.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* ============================================================================
*/
// Begin.
global $config;
// Necessary classes for extends.
require_once $config['homedir'].'/include/class/HTML.class.php';
require_once $config['homedir'].'/include/functions_servers.php';
enterprise_include_once('include/functions_satellite.php');
enterprise_include_once('include/functions_collection.php');
/**
* Class SatelliteCollection
*/
class SatelliteCollection extends HTML
{
/**
* Allowed methods to be called using AJAX request.
*
* @var array
*/
public $AJAXMethods = [
'draw',
'addCollection',
'deleteCollection',
'loadModal',
];
/**
* Ajax page.
*
* @var string
*/
private $ajaxController;
/**
* Class constructor
*
* @param string $ajaxController Ajax controller.
*/
public function __construct(string $ajaxController)
{
global $config;
check_login();
if (check_acl($config['id_user'], 0, 'PM') === false
&& is_user_admin($config['id_user']) === true
) {
db_pandora_audit(
AUDIT_LOG_ACL_VIOLATION,
'Trying to access Satellite agents'
);
include 'general/noaccess.php';
return;
}
if ((int) $config['license_nms'] === 1) {
db_pandora_audit(
AUDIT_LOG_NMS_VIOLATION,
'Trying to access satellite collections'
);
include $config['homedir'].'/general/noaccess.php';
return;
}
// Set the ajax controller.
$this->ajaxController = $ajaxController;
// Capture all parameters before start.
$this->satellite_server = (int) get_parameter('server_remote');
if ($this->satellite_server !== 0) {
$this->satellite_name = servers_get_name($this->satellite_server);
$this->satellite_config = (array) config_satellite_get_config_file($this->satellite_name);
}
}
/**
* Run view
*
* @return void
*/
public function run()
{
// Javascript.
ui_require_jquery_file('pandora');
// CSS.
ui_require_css_file('wizard');
ui_require_css_file('discovery');
$this->createBlock();
// Datatables list.
try {
$columns = [
'name',
'dir',
'description',
'actions',
];
$column_names = [
__('Name'),
__('Dir'),
__('Description'),
__('Actions'),
];
$this->tableId = 'satellite_collections';
// Load datatables user interface.
ui_print_datatable(
[
'id' => $this->tableId,
'class' => 'info_table',
'style' => 'width: 100%',
'columns' => $columns,
'column_names' => $column_names,
'ajax_url' => $this->ajaxController,
'ajax_data' => [
'method' => 'draw',
'server_remote' => $this->satellite_server,
],
'ajax_postprocces' => 'process_datatables_item(item)',
'no_sortable_columns' => [
0,
1,
2,
3,
],
'search_button_class' => 'sub filter float-right',
'form' => [
'inputs' => [
[
'label' => __('Search'),
'type' => 'text',
'name' => 'filter_search',
'class' => 'w400px',
'size' => 12,
],
],
],
'filter_main_class' => 'box-flat white_table_graph fixed_filter_bar',
]
);
} catch (Exception $e) {
echo $e->getMessage();
}
echo '<div id="aux" class="invisible"></div>';
echo '<div id="msg" class="invisible"></div>';
html_print_action_buttons('');
// Load own javascript file.
echo $this->loadJS();
}
/**
* Get the data for draw the table.
*
* @return void.
*/
public function draw()
{
global $config;
// Init data.
$data = [];
// Count of total records.
$count = 0;
// Catch post parameters.
$start = get_parameter('start', 0);
$length = get_parameter('length', $config['block_size']);
$order = get_datatable_order(true);
$filters = get_parameter('filter', []);
try {
ob_start();
// Gets all collections (database).
$collections = collection_get_collections(null, $filters['filter_search']);
if (empty($collections) === false) {
$data = $collections;
}
// All satellite conf collections.
foreach ($this->satellite_config as $line) {
$regex = '/^file_collection\s(\S+)/m';
if (preg_match($regex, $line, $matches, PREG_OFFSET_CAPTURE, 0) > 0) {
$key = array_search($matches[1][0], array_column($data, 'short_name'));
if ($key !== false) {
$data[$key]['delete'] = true;
}
}
}
if (empty($data) === false) {
$data = array_reduce(
$data,
function ($carry, $item) {
// Transforms array of arrays $data into an array
// of objects, making a post-process of certain fields.
$tmp = (object) $item;
$delete = (int) isset($tmp->delete);
$tmp->dir = $tmp->short_name;
$tmp->actions = '';
$tmp->actions .= html_print_image(
($delete === 0) ? 'images/add.png' : 'images/delete.svg',
true,
[
'border' => '0',
'class' => 'action_button_img mrgn_lft_05em invert_filter',
'onclick' => ($delete === 0)
? 'add_collection(\''.$tmp->short_name.'\')'
: 'delete_collection(\''.$tmp->short_name.'\')',
]
);
$carry[] = $tmp;
return $carry;
}
);
}
if (empty($data) === true) {
$total = 0;
$data = [];
} else {
$total = count($data);
$data = array_slice($data, $start, $length, false);
}
echo json_encode(
[
'data' => $data,
'recordsTotal' => $total,
'recordsFiltered' => $total,
]
);
// Capture output.
$response = ob_get_clean();
} catch (Exception $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;
}
/**
* Add collection to satellite conf.
*
* @return void
*/
public function addCollection()
{
$short_name = get_parameter('short_name');
if ($this->parseSatelliteConf('add', $short_name) === false) {
$this->ajaxMsg('error', __('Error adding collection'));
} else {
$this->ajaxMsg('result', _('Collection '.$short_name.' added.'));
}
exit;
}
/**
* Delete collection to satellite conf.
*
* @return void
*/
public function deleteCollection()
{
$short_name = get_parameter('short_name');
if ($this->parseSatelliteConf('delete', $short_name) === false) {
$this->ajaxMsg('error', __('Error deleting collection'));
} else {
$this->ajaxMsg('result', _('Collection '.$short_name.' deleted.'));
}
exit;
}
/**
* Parse satellite configuration .
*
* @param string $action Action to perform (add, delete).
* @param string $short_name Short name.
*
* @return boolean
*/
private function parseSatelliteConf(string $action, string $short_name)
{
switch ($action) {
case 'delete':
$pos = preg_grep('/^file_collection '.$short_name.'/', $this->satellite_config);
if (empty($pos) === false) {
$key_pos = 0;
foreach ($pos as $key => $value) {
$key_pos = $key;
break;
}
unset($this->satellite_config[$key_pos]);
}
$conf = implode('', $this->satellite_config);
break;
default:
case 'add':
$pos = preg_grep('/^file_collection/', $this->satellite_config);
if (empty($pos) === false) {
$string_collection = 'file_collection '.$short_name."\n";
$key_pos = array_keys($pos)[(count($pos) - 1)];
$array1 = array_slice($this->satellite_config, 0, ($key_pos + 1));
$array2 = array_slice($this->satellite_config, ($key_pos + 1));
$array_merge = array_merge($array1, [$string_collection], $array2);
$this->satellite_config = $array_merge;
// Check config.
if (empty($this->satellite_config) === true) {
return false;
}
} else {
$pos = preg_grep('/^\#\sFile\scollections/', $this->satellite_config);
$string_collection = 'file_collection '.$short_name."\n";
$key_pos = 0;
foreach ($pos as $key => $value) {
$key_pos = $key;
break;
}
$key_pos++;
$array1 = array_slice($this->satellite_config, 0, $key_pos);
$array2 = array_slice($this->satellite_config, $key_pos);
// Add collection to conf.
$array_merge = array_merge($array1, [$string_collection], $array2);
$this->satellite_config = $array_merge;
// Check config.
if (empty($this->satellite_config) === true) {
return false;
}
}
$conf = implode('', $this->satellite_config);
break;
}
return $this->saveAgent($conf);
}
/**
* Saves agent to satellite cofiguration file.
*
* @param string $new_conf Config file.
*
* @return boolean|void
*/
private function saveAgent(string $new_conf)
{
global $config;
if (empty($new_conf) === true) {
return false;
}
db_pandora_audit(
AUDIT_LOG_SYSTEM,
'Update remote config for server '.$this->satellite_name
);
// Convert to config file encoding.
$encoding = config_satellite_get_encoding($new_conf);
if ($encoding !== false) {
$converted_server_config = mb_convert_encoding($new_conf, $encoding, 'UTF-8');
if ($converted_server_config !== false) {
$new_conf = $converted_server_config;
}
}
// Get filenames.
if ($this->satellite_server !== false) {
$files = config_satellite_get_satellite_config_filenames($this->satellite_name);
} else {
$files = [];
$files['conf'] = $config['remote_config'].'/conf/'.md5($this->satellite_name).'.srv.conf';
$files['md5'] = $config['remote_config'].'/md5/'.md5($this->satellite_name).'.srv.md5';
}
// Save configuration.
$result = file_put_contents($files['conf'], $new_conf);
if ($result === false) {
return false;
}
// Save configuration md5.
$result = file_put_contents($files['md5'], md5($new_conf));
}
/**
* 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)
{
return in_array($method, $this->AJAXMethods);
}
/**
* Minor function to dump json message as ajax response.
*
* @param string $type Type: result || error.
* @param string $msg Message.
*
* @return void
*/
private function ajaxMsg(string $type, string $msg)
{
echo json_encode(
[
$type => __($msg),
]
);
exit;
}
/**
* Create file_collections blocks
*
* @return void
*/
public function createBlock()
{
$init = preg_grep('/^\#\sFile\scollections/', $this->satellite_config);
if (empty($init) === true) {
$collection = "# File collections\n";
array_push($this->satellite_config, "\n");
array_push($this->satellite_config, $collection);
array_push($this->satellite_config, "\n");
$conf = implode('', $this->satellite_config);
$this->saveAgent($conf);
}
}
/**
* Load Javascript code.
*
* @return string.
*/
public function loadJS()
{
// Nothing for this moment.
ob_start();
// Javascript content.
?>
<script type="text/javascript">
/**
* Add collection.
*/
function add_collection(short_name) {
$('#aux').empty();
$('#aux').text('<?php echo __('Are you sure?'); ?>');
$('#aux').dialog({
title: '<?php echo __('Add collection'); ?>',
buttons: [{
class: 'ui-widget ui-state-default ui-corner-all ui-button-text-only sub upd submit-cancel',
text: '<?php echo __('Cancel'); ?>',
click: function(e) {
$(this).dialog('close');
}
},
{
text: 'Add',
class: 'ui-widget ui-state-default ui-corner-all ui-button-text-only sub ok submit-next',
click: function(e) {
$.ajax({
method: 'post',
url: '<?php echo ui_get_full_url('ajax.php', false, false, false); ?>',
data: {
page: 'enterprise/godmode/servers/collections_satellite',
method: 'addCollection',
short_name: short_name,
server_remote: <?php echo $this->satellite_server; ?>,
},
datatype: "json",
success: function(data) {
console.log(data);
showMsg(data);
},
error: function(e) {
showMsg(e);
}
});
}
}
]
});
}
/**
* Delete collection.
*/
function delete_collection(short_name) {
$('#aux').empty();
$('#aux').text('<?php echo __('Are you sure?'); ?>');
$('#aux').dialog({
title: '<?php echo __('Delete collection'); ?>',
buttons: [{
class: 'ui-widget ui-state-default ui-corner-all ui-button-text-only sub upd submit-cancel',
text: '<?php echo __('Cancel'); ?>',
click: function(e) {
$(this).dialog('close');
}
},
{
text: 'Delete',
class: 'ui-widget ui-state-default ui-corner-all ui-button-text-only sub ok submit-next',
click: function(e) {
$.ajax({
method: 'post',
url: '<?php echo ui_get_full_url('ajax.php', false, false, false); ?>',
data: {
page: 'enterprise/godmode/servers/collections_satellite',
method: 'deleteCollection',
short_name: short_name,
server_remote: <?php echo $this->satellite_server; ?>,
},
datatype: "json",
success: function(data) {
console.log(data);
showMsg(data);
},
error: function(e) {
showMsg(e);
}
});
}
}
]
});
}
/**
* Process ajax responses and shows a dialog with results.
*/
function showMsg(data) {
var title = "<?php echo __('Success'); ?>";
var dt_satellite_agents = $("#satellite_collections").DataTable();
dt_<?php echo $this->tableId; ?>.draw(false);
var text = '';
var failed = 0;
try {
data = JSON.parse(data);
text = data['result'];
} catch (err) {
title = "<?php echo __('Failed'); ?>";
text = err.message;
failed = 1;
}
if (!failed && data['error'] != undefined) {
title = "<?php echo __('Failed'); ?>";
text = data['error'];
failed = 1;
}
if (data['report'] != undefined) {
data['report'].forEach(function (item){
text += '<br>'+item;
});
}
$('#msg').empty();
$('#msg').html(text);
$('#msg').dialog({
width: 450,
position: {
my: 'center',
at: 'center',
of: window,
collision: 'fit'
},
title: title,
buttons: [
{
class: "ui-widget ui-state-default ui-corner-all ui-button-text-only sub ok submit-next",
text: 'OK',
click: function(e) {
if (!failed) {
$(".ui-dialog-content").dialog("close");
$('.info').hide();
} else {
$(this).dialog('close');
}
}
}
]
});
}
</script>
<?php
// EOF Javascript content.
return ob_get_clean();
}
}