diff --git a/pandora_console/godmode/servers/modificar_server.php b/pandora_console/godmode/servers/modificar_server.php
index b4fcf95fcc..34524c6aa7 100644
--- a/pandora_console/godmode/servers/modificar_server.php
+++ b/pandora_console/godmode/servers/modificar_server.php
@@ -122,26 +122,44 @@ if (isset($_GET['server'])) {
$buttons = '';
- if ($server_type !== 13) {
- // Buttons.
- $buttons = [
- 'standard_editor' => [
- 'active' => false,
- 'text' => ''.html_print_image('images/list.png', true, ['title' => __('Standard editor')]).'',
- ],
- 'advanced_editor' => [
- 'active' => false,
- 'text' => ''.html_print_image('images/pen.png', true, ['title' => __('Advanced editor')]).'',
- ],
- ];
+ // Buttons.
+ $buttons = [
+ 'standard_editor' => [
+ 'active' => false,
+ 'text' => ''.html_print_image('images/list.png', true, ['title' => __('Standard editor')]).'',
+ ],
+ 'advanced_editor' => [
+ 'active' => false,
+ 'text' => ''.html_print_image('images/pen.png', true, ['title' => __('Advanced editor')]).'',
+ ],
+ ];
- $buttons[$tab]['active'] = true;
+ if ($server_type === SERVER_TYPE_ENTERPRISE_SATELLITE) {
+ $buttons['agent_editor'] = [
+ 'active' => false,
+ 'text' => ''.html_print_image('images/agent.png', true, ['title' => __('Advanced editor')]).'',
+
+ ];
}
+ $buttons[$tab]['active'] = true;
+
ui_print_page_header(__('Remote Configuration'), 'images/gm_servers.png', false, 'servers', true, $buttons);
- if ($server_type !== 13 && $tab == 'standard_editor') {
+ if ($tab === 'standard_editor') {
$advanced_editor = false;
+
+ if ($server_type === 13) {
+ echo "
+ ";
+ echo '';
+ echo __('Dynamic search').' ';
+ html_print_input_text('search_config_token', $search, '', 12);
+ echo ' | ';
+ echo '
';
+ }
+ } else if ($tab === 'agent_editor' && $server_type === SERVER_TYPE_ENTERPRISE_SATELLITE) {
+ $advanced_editor = 'agent_editor';
}
enterprise_include('godmode/servers/server_disk_conf_editor.php');
diff --git a/pandora_console/include/class/SatelliteAgent.class.php b/pandora_console/include/class/SatelliteAgent.class.php
new file mode 100644
index 0000000000..f1c187afdf
--- /dev/null
+++ b/pandora_console/include/class/SatelliteAgent.class.php
@@ -0,0 +1,768 @@
+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');
+
+ global $config;
+ // Datatables list.
+ try {
+ $columns = [
+ 'name',
+ 'address',
+ 'actions',
+ ];
+
+ $column_names = [
+ __('Agent Name'),
+ __('IP Adrress'),
+ __('Actions'),
+ ];
+
+ $this->tableId = 'satellite_agents';
+
+ if (is_metaconsole() === true) {
+ // Only in case of Metaconsole, format the frame.
+ open_meta_frame();
+ }
+
+ // 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,
+ ],
+ 'search_button_class' => 'sub filter float-right',
+ 'form' => [
+ 'inputs' => [
+ [
+ 'label' => __('Search').ui_print_help_tip(
+ __('Search filter by alias, name, description, IP address or custom fields content'),
+ true
+ ),
+ 'type' => 'text',
+ 'name' => 'filter_search',
+ 'size' => 12,
+ ],
+
+ ],
+ ],
+ ]
+ );
+ } catch (Exception $e) {
+ echo $e->getMessage();
+ }
+
+ if (is_metaconsole() === true) {
+ // Close the frame.
+ close_meta_frame();
+ }
+
+ // Auxiliar div.
+ $modal = '';
+ $msg = '';
+ $aux = '';
+
+ echo $modal.$msg.$aux;
+
+ // Create button.
+ echo '';
+ html_print_submit_button(
+ __('Add host'),
+ 'create',
+ false,
+ 'class="sub next"'
+ );
+
+ echo '
';
+ // Load own javascript file.
+ echo $this->loadJS();
+
+ }
+
+
+ /**
+ * Get the data for draw the table.
+ *
+ * @return void.
+ */
+ public function draw()
+ {
+ global $config;
+ // Initialice filter.
+ $filter = '1=1';
+ // 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();
+ $data = [];
+
+ foreach ($this->satellite_config as $line) {
+ $re = '/^#*add_host \b(\S+) (\S*)$/m';
+
+ if (preg_match($re, $line, $matches, PREG_OFFSET_CAPTURE, 0) > 0) {
+ $agent['address'] = $matches[1][0];
+ if (isset($matches[2][0]) === false || empty($matches[2][0]) === true) {
+ $agent['name'] = '';
+ } else {
+ $agent['name'] = $matches[2][0];
+ }
+
+ if (empty($filters['filter_search']) === false) {
+ if (empty(preg_grep('/'.$filters['filter_search'].'?/mi', array_values($agent))) === true) {
+ continue;
+ }
+ }
+
+ array_push($data, $agent);
+ }
+ }
+
+ if (empty($data) === false) {
+ $data = array_reduce(
+ $data,
+ function ($carry, $item) {
+ global $config;
+ // Transforms array of arrays $data into an array
+ // of objects, making a post-process of certain fields.
+ $tmp = (object) $item;
+
+ $tmp->actions .= html_print_image(
+ 'images/cross.png',
+ true,
+ [
+ 'border' => '0',
+ 'class' => 'action_button_img invert_filter',
+ 'onclick' => 'delete_agent(\''.$tmp->address.'\',\''.$tmp->name.'\')',
+ ]
+ );
+
+ $carry[] = $tmp;
+ return $carry;
+ }
+ );
+ }
+
+ $data = array_slice($data, $start, $length, true);
+ $total = count($data);
+
+ 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;
+ }
+
+
+ /**
+ * Prints inputs for modal "Add agent".
+ *
+ * @return void
+ */
+ public function loadModal()
+ {
+ $values['address'] = get_parameter('address', null);
+ $values['name'] = get_parameter('name', null);
+
+ echo $this->printInputs($values);
+ }
+
+
+ /**
+ * Generates inputs for new/update agents.
+ *
+ * @param array $values Values or null.
+ *
+ * @return string Inputs.
+ */
+ public function printInputs($values=null)
+ {
+ if (!is_array($values)) {
+ $values = [];
+ }
+
+ $return_all_group = false;
+
+ if (users_can_manage_group_all('AR') === true) {
+ $return_all_group = true;
+ }
+
+ $form = [
+ 'action' => '#',
+ 'id' => 'modal_form',
+ 'onsubmit' => 'return false;',
+ 'class' => 'modal',
+ ];
+
+ $inputs = [];
+
+ $inputs[] = [
+ 'label' => __('Agent address'),
+ 'id' => 'div-identifier',
+ 'arguments' => [
+ 'name' => 'address',
+ 'type' => 'text',
+ 'value' => $values['address'],
+ 'return' => true,
+ ],
+ ];
+
+ $inputs[] = [
+ 'label' => __('Agent name'),
+ 'id' => 'div-identifier',
+ 'arguments' => [
+ 'name' => 'name',
+ 'type' => 'text',
+ 'value' => $values['name'],
+ 'return' => true,
+ ],
+ ];
+
+ return $this->printForm(
+ [
+ 'form' => $form,
+ 'inputs' => $inputs,
+ ],
+ true
+ );
+ }
+
+
+ /**
+ * Add agent to satellite conf.
+ *
+ * @return void
+ */
+ public function addAgent()
+ {
+ global $config;
+
+ $values['address'] = get_parameter('address');
+ $values['name'] = get_parameter('name');
+
+ if ($this->parseSatelliteConf('save', $values) === false) {
+ $this->ajaxMsg('error', __('Error saving agent'));
+ } else {
+ $this->ajaxMsg('result', _('Host '.$values['addres'].' added.'));
+ }
+
+ exit;
+
+ }
+
+
+ /**
+ * Delete agent from satellite conf.
+ *
+ * @return void
+ */
+ public function deleteAgent()
+ {
+ $values['address'] = get_parameter('address', '');
+ $values['name'] = get_parameter('name', '');
+
+ if ($this->parseSatelliteConf('delete', $values) === false) {
+ $this->ajaxMsg('error', __('Error saving agent'));
+ } else {
+ $this->ajaxMsg('result', _('Host '.$values['addres'].' added.'));
+ }
+
+ exit;
+ }
+
+
+ /**
+ * Parse satellite configuration .
+ *
+ * @param string $action Action to perform (save, delete).
+ * @param array $values.
+ * @return void
+ */
+ private function parseSatelliteConf(string $action, array $values)
+ {
+ switch ($action) {
+ case 'save':
+ if (isset($values['address']) === true && empty($values['address']) === false) {
+ $string_hosts = 'add_host '.$values['address'].' '.$values['name']."\n";
+
+ // Add host to conf
+ array_push($this->satellite_config, $string_hosts);
+
+ // Check config.
+ if (empty($this->satellite_config)) {
+ return false;
+ }
+
+ $conf = implode('', $this->satellite_config);
+ } else {
+ return false;
+ }
+ break;
+
+ case 'delete':
+ $conf = implode('', $this->satellite_config);
+ // Find agent to mark for deletion.
+ $pattern = io_safe_expreg($values['address'].' '.$values['name']);
+ $re = "/add_host ($pattern)/m";
+ $subst = 'delete_host $1';
+ $conf = preg_replace($re, $subst, $conf);
+ break;
+
+ default:
+ $this->ajaxMsg('error', __('Error'));
+ exit;
+ }
+
+ return $this->saveAgent($conf);
+ }
+
+
+ /**
+ * Saves agent to satellite cofiguration file.
+ *
+ * @param array $values
+ * @return void
+ */
+ private function saveAgent(string $new_conf)
+ {
+ global $config;
+
+ if (empty($new_conf)) {
+ 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.
+ * @param boolean $delete Deletion messages.
+ *
+ * @return void
+ */
+ private function ajaxMsg($type, $msg, $delete=false)
+ {
+ $msg_err = 'Failed while saving: %s';
+ $msg_ok = 'Successfully saved agent ';
+
+ if ($delete) {
+ $msg_err = 'Failed while removing: %s';
+ $msg_ok = 'Successfully deleted ';
+ }
+
+ if ($type == 'error') {
+ echo json_encode(
+ [
+ $type => ui_print_error_message(
+ __(
+ $msg_err,
+ $msg
+ ),
+ '',
+ true
+ ),
+ ]
+ );
+ } else {
+ echo json_encode(
+ [
+ $type => ui_print_success_message(
+ __(
+ $msg_ok,
+ $msg
+ ),
+ '',
+ true
+ ),
+ ]
+ );
+ }
+
+ exit;
+ }
+
+
+ /**
+ * Load Javascript code.
+ *
+ * @return string.
+ */
+ public function loadJS()
+ {
+ // Nothing for this moment.
+ ob_start();
+
+ // Javascript content.
+ ?>
+
+