1266 lines
39 KiB
PHP
1266 lines
39 KiB
PHP
<?php
|
|
/**
|
|
* Cluster view main class.
|
|
*
|
|
* @category Class
|
|
* @package Pandora FMS
|
|
* @subpackage Community
|
|
* @version 1.0.0
|
|
* @license See below
|
|
*
|
|
* ______ ___ _______ _______ ________
|
|
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
|
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
|
*
|
|
* ============================================================================
|
|
* Copyright (c) 2005-2021 Artica Soluciones Tecnologicas
|
|
* Please see http://pandorafms.org 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.
|
|
namespace PandoraFMS\ClusterViewer;
|
|
|
|
global $config;
|
|
|
|
require_once $config['homedir'].'/include/class/HTML.class.php';
|
|
|
|
use \HTML;
|
|
use PandoraFMS\View;
|
|
use PandoraFMS\Cluster;
|
|
|
|
/**
|
|
* Class to handle Cluster view operations.
|
|
*/
|
|
class ClusterWizard extends \HTML
|
|
{
|
|
|
|
/**
|
|
* Breadcrum titles.
|
|
*
|
|
* @var array
|
|
*/
|
|
public $labels = [
|
|
'Definition',
|
|
'Members',
|
|
];
|
|
|
|
/**
|
|
* Label set for AA clusters.
|
|
*
|
|
* @var array
|
|
*/
|
|
public $AALabels = [
|
|
2 => 'A-A Modules',
|
|
3 => 'A-A thresholds',
|
|
6 => 'Alerts',
|
|
];
|
|
|
|
/**
|
|
* Label set for AP clusters.
|
|
*
|
|
* @var array
|
|
*/
|
|
public $APLabels = [
|
|
2 => 'A-P Modules',
|
|
3 => 'A-P thresholds',
|
|
4 => 'A-P module',
|
|
5 => 'Critical A-P modules',
|
|
6 => 'Alerts',
|
|
];
|
|
|
|
/**
|
|
* Variable to store error messages while parsing
|
|
* different steps.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $errMessages = [];
|
|
|
|
/**
|
|
* Current operation (New | Update).
|
|
*
|
|
* @var string
|
|
*/
|
|
public $operation;
|
|
|
|
/**
|
|
* Parent url (for go back forms).
|
|
*
|
|
* @var string
|
|
*/
|
|
public $parentUrl;
|
|
|
|
/**
|
|
* Current cluster definition (if any).
|
|
*
|
|
* @var PandoraFMS\ClusterViewer\Cluster
|
|
*/
|
|
private $cluster;
|
|
|
|
/**
|
|
* Current cluster agent definition (if any).
|
|
*
|
|
* @var array
|
|
*/
|
|
private $agent;
|
|
|
|
|
|
/**
|
|
* Builds a Cluster Wizard.
|
|
*
|
|
* @param string $url Main url.
|
|
* @param string $operation Operation (new|update).
|
|
*/
|
|
public function __construct(string $url, string $operation=null)
|
|
{
|
|
// Check access.
|
|
check_login();
|
|
|
|
ui_require_css_file('wizard');
|
|
ui_require_css_file('discovery');
|
|
|
|
$this->access = 'AW';
|
|
$this->operation = $operation;
|
|
$this->url = $url;
|
|
$this->parentUrl = $url;
|
|
$this->page = (int) get_parameter('page', 0);
|
|
$this->id = (int) get_parameter('id', 0);
|
|
}
|
|
|
|
|
|
/**
|
|
* Run wizard.
|
|
*
|
|
* @return void
|
|
* @throws \Exception On error.
|
|
*/
|
|
public function run()
|
|
{
|
|
global $config;
|
|
|
|
ui_require_css_file('cluster_wizard');
|
|
|
|
$this->operation = get_parameter('op', '');
|
|
$cluster_id = get_parameter('id', '');
|
|
$name = get_parameter('name', '');
|
|
|
|
$this->errMessages = [];
|
|
|
|
// Cluster initialization. Load.
|
|
$load_success = true;
|
|
|
|
try {
|
|
if (empty($cluster_id) === false) {
|
|
// Load data.
|
|
$this->cluster = new Cluster($cluster_id);
|
|
|
|
if ($this->cluster->agent()->id_agente() === null) {
|
|
$this->errMessages['noagent'] = 'Agent associated to cluster does not exist. Please update to create it.';
|
|
}
|
|
|
|
if ($this->cluster->group()->id_grupo() === null) {
|
|
throw new \Exception(
|
|
'Group associated to cluster does not exist.'
|
|
);
|
|
}
|
|
} else if (empty($name) === false) {
|
|
$cluster_data = Cluster::search(['name' => $name]);
|
|
|
|
if ($cluster_data !== false) {
|
|
$init_failed = true;
|
|
$this->page--;
|
|
throw new \Exception(
|
|
__('Cluster already defined, please use another name.')
|
|
);
|
|
}
|
|
}
|
|
} catch (\Exception $e) {
|
|
$this->errMessages[] = $e->getMessage();
|
|
$load_success = false;
|
|
}
|
|
|
|
if (empty($this->cluster) === true) {
|
|
// Empty cluster. Initialize.
|
|
$this->cluster = new Cluster();
|
|
} else {
|
|
// Cluster already exists. Update operation.
|
|
$this->operation = 'update';
|
|
}
|
|
|
|
try {
|
|
// Check user has grants to edit this cluster.
|
|
if ($this->operation !== 'new'
|
|
&& (!check_acl(
|
|
$config['id_user'],
|
|
$this->cluster->group()->id_grupo(),
|
|
'AW'
|
|
))
|
|
) {
|
|
// User has no grants to edit this cluster.
|
|
throw new \Exception(
|
|
'You have no permission to edit this cluster.'
|
|
);
|
|
}
|
|
} catch (\Exception $e) {
|
|
$this->errMessages[] = $e->getMessage();
|
|
$load_success = false;
|
|
}
|
|
|
|
if ($load_success === true) {
|
|
if ($this->cluster->id() === null
|
|
&& $this->page > 1
|
|
) {
|
|
$load_success = false;
|
|
$this->errMessages[] = 'Please define this cluster first';
|
|
} else {
|
|
try {
|
|
// Parse results (previous step).
|
|
$status = $this->parseForm();
|
|
} catch (\Exception $e) {
|
|
$this->errMessages[] = $e->getMessage();
|
|
if ($this->page > 0) {
|
|
$this->page--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get form structure (current page).
|
|
$form = $this->getForm($load_success);
|
|
|
|
// Force Cluster calculation. Cluster defined.
|
|
$this->cluster->force(false);
|
|
|
|
View::render(
|
|
'cluster/edit',
|
|
[
|
|
'config' => $config,
|
|
'wizard' => $this,
|
|
'model' => $this,
|
|
'cluster' => $this->cluster,
|
|
'form' => $form,
|
|
]
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieve page value.
|
|
*
|
|
* @return integer Page value.
|
|
*/
|
|
public function getPage()
|
|
{
|
|
return $this->page;
|
|
}
|
|
|
|
|
|
/**
|
|
* Set page to target value.,
|
|
*
|
|
* @param integer $page New page value.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setPage(int $page)
|
|
{
|
|
$this->page = $page;
|
|
}
|
|
|
|
|
|
/**
|
|
* Return current operation.
|
|
*
|
|
* @return string New or Update.
|
|
*/
|
|
public function getOperation()
|
|
{
|
|
return $this->operation;
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieve labels.
|
|
*
|
|
* @return array With labels (breadcrum).
|
|
*/
|
|
public function getLabels()
|
|
{
|
|
$labels = $this->labels;
|
|
if ($this->cluster->cluster_type() !== null) {
|
|
if ($this->cluster->cluster_type() === 'AA') {
|
|
$labels = ($this->labels + $this->AALabels);
|
|
} else {
|
|
$labels = ($this->labels + $this->APLabels);
|
|
}
|
|
}
|
|
|
|
return $labels;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns a goBack form structure.
|
|
*
|
|
* @param boolean $main Go to main page.
|
|
*
|
|
* @return array Form structure.
|
|
*/
|
|
public function getGoBackForm(?bool $main=false)
|
|
{
|
|
$url = $this->url;
|
|
|
|
if ($main === false) {
|
|
$page = ($this->page - 1);
|
|
|
|
if ($page >= 0) {
|
|
$extra_url = '';
|
|
if ($this->cluster->id() !== null) {
|
|
$extra_url = '&id='.$this->cluster->id();
|
|
if ($this->cluster->cluster_type() === 'AA') {
|
|
// Jump from Alerts back to A-A Thresholds.
|
|
if ($page === 5) {
|
|
$page = 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
$url = $this->url.'&op='.$this->operation;
|
|
$url .= '&page='.$page.$extra_url;
|
|
}
|
|
}
|
|
|
|
$form['form']['action'] = $url;
|
|
$form['form']['method'] = 'POST';
|
|
$form['form']['id'] = 'go-back-form';
|
|
$form['inputs'] = [
|
|
[
|
|
'arguments' => [
|
|
'name' => 'submit',
|
|
'label' => __('Go back'),
|
|
'type' => 'submit',
|
|
'attributes' => [
|
|
'icon' => 'back',
|
|
'mode' => 'secondary',
|
|
],
|
|
'return' => true,
|
|
],
|
|
],
|
|
];
|
|
|
|
return $form;
|
|
}
|
|
|
|
|
|
/**
|
|
* Parse responses from previous steps.
|
|
*
|
|
* @return void
|
|
* @throws \Exception On error.
|
|
*/
|
|
private function parseForm()
|
|
{
|
|
global $config;
|
|
|
|
// Parse user responses.
|
|
if ($this->page <= 0) {
|
|
// No previous steps, return OK.
|
|
return;
|
|
}
|
|
|
|
if ($this->page === 1) {
|
|
/*
|
|
*
|
|
* PARSE DEFINITION.
|
|
*
|
|
*/
|
|
|
|
$name = get_parameter('name', '');
|
|
$type = get_parameter('type', null);
|
|
$description = get_parameter('description', '');
|
|
$id_group = get_parameter('id_group', '');
|
|
$server_name = get_parameter('server_name', '');
|
|
|
|
if ($name === ''
|
|
&& $type === null
|
|
&& $description === ''
|
|
&& $id_group === ''
|
|
&& $server_name === ''
|
|
) {
|
|
if ($this->cluster->id() === null) {
|
|
throw new \Exception(
|
|
'Please fulfill all required fields.'
|
|
);
|
|
}
|
|
|
|
// Default values, show page.
|
|
return;
|
|
}
|
|
|
|
if (empty($name) === true
|
|
|| empty($type) === true
|
|
|| empty($id_group) === true
|
|
|| empty($server_name) === true
|
|
) {
|
|
if (empty($server_name) === true) {
|
|
throw new \Exception(
|
|
'Please select a valid Prediction server'
|
|
);
|
|
}
|
|
|
|
throw new \Exception('Please fulfill all required fields');
|
|
}
|
|
|
|
// Verify cluster type is one from the list.
|
|
if (in_array($type, ['AA', 'AP']) === false) {
|
|
throw new \Exception('Invalid cluster type selected');
|
|
}
|
|
|
|
if ($this->cluster->id() === null) {
|
|
// Create.
|
|
// 1. Create agent.
|
|
$this->cluster->agent()->alias($name);
|
|
$this->cluster->agent()->comentarios($description);
|
|
$this->cluster->agent()->intervalo(300);
|
|
$this->cluster->agent()->id_grupo($id_group);
|
|
$this->cluster->agent()->id_os(CLUSTER_OS_ID);
|
|
$this->cluster->agent()->server_name($server_name);
|
|
$this->cluster->agent()->modo(1);
|
|
|
|
$this->cluster->agent()->save();
|
|
|
|
if ($this->cluster->agent()->id_agente() === false) {
|
|
throw new \Exception(
|
|
'Failed to create agent: '.$config['dbconnection']->error
|
|
);
|
|
}
|
|
|
|
// 2. Create cluster entry.
|
|
$this->cluster->name($name);
|
|
$this->cluster->cluster_type($type);
|
|
$this->cluster->description($description);
|
|
$this->cluster->group($id_group);
|
|
$this->cluster->id_agent($this->cluster->agent()->id_agente());
|
|
|
|
$this->cluster->save();
|
|
|
|
if ($this->cluster->id() === null) {
|
|
// Delete agent created in previous step.
|
|
\agents_delete_agent($this->cluster->agent()->id());
|
|
|
|
throw new \Exception(
|
|
'Failed to create cluster: '.$config['dbconnection']->error
|
|
);
|
|
}
|
|
|
|
// 3. Create cluster module in agent.
|
|
$this->cluster->agent()->addModule(
|
|
[
|
|
'nombre' => io_safe_input('Cluster status'),
|
|
'id_modulo' => 5,
|
|
'prediction_module' => 5,
|
|
'custom_integer_1' => $this->cluster->id(),
|
|
'id_tipo_modulo' => 1,
|
|
'descripcion' => io_safe_input(
|
|
'Cluster status information module'
|
|
),
|
|
'min_warning' => 1,
|
|
'min_critical' => 2,
|
|
]
|
|
);
|
|
} else {
|
|
// Update.
|
|
$this->cluster->name($name);
|
|
$this->cluster->cluster_type($type);
|
|
$this->cluster->description($description);
|
|
$this->cluster->group($id_group);
|
|
|
|
$this->cluster->agent()->alias($name);
|
|
$this->cluster->agent()->comentarios($description);
|
|
$this->cluster->agent()->intervalo(300);
|
|
$this->cluster->agent()->id_grupo($id_group);
|
|
$this->cluster->agent()->id_os(CLUSTER_OS_ID);
|
|
$this->cluster->agent()->server_name($server_name);
|
|
$this->cluster->agent()->modo(1);
|
|
$this->cluster->agent()->save();
|
|
|
|
// 2. Re link.
|
|
$this->cluster->id_agent($this->cluster->agent()->id_agente());
|
|
$this->cluster->save();
|
|
|
|
// If agent has been deleted, recreate module.
|
|
if ($this->errMessages['noagent'] !== null) {
|
|
// 3. Create cluster module in agent.
|
|
$this->cluster->agent()->addModule(
|
|
[
|
|
'nombre' => io_safe_input('Cluster status'),
|
|
'id_modulo' => 5,
|
|
'prediction_module' => 5,
|
|
'custom_integer_1' => $this->cluster->id(),
|
|
'id_tipo_modulo' => 1,
|
|
'descripcion' => io_safe_input(
|
|
'Cluster status information module'
|
|
),
|
|
'min_warning' => 1,
|
|
'min_critical' => 2,
|
|
]
|
|
);
|
|
}
|
|
|
|
unset($this->errMessages['noagent']);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if ($this->page === 2) {
|
|
/*
|
|
*
|
|
* PARSE MEMBERS.
|
|
*
|
|
*/
|
|
|
|
// Parse responses from page 1.
|
|
$agents_selected = get_parameter('selected-select-members', null);
|
|
|
|
if ($agents_selected === null) {
|
|
// Direct access.
|
|
return;
|
|
}
|
|
|
|
// Clear members. Reparse.
|
|
$this->cluster->cleanMembers();
|
|
|
|
// Remove 'None' field.
|
|
if (array_search(0, $agents_selected) === 0) {
|
|
unset($agents_selected[0]);
|
|
}
|
|
|
|
if (empty($agents_selected) === true) {
|
|
throw new \Exception('No members selected');
|
|
}
|
|
|
|
foreach ($agents_selected as $id_agent) {
|
|
$agent = $this->cluster->addMember($id_agent);
|
|
|
|
\db_pandora_audit(
|
|
AUDIT_LOG_AGENT_MANAGEMENT,
|
|
'Agent '.io_safe_output($agent->alias()).' added to cluster '.io_safe_output(
|
|
$this->cluster->name()
|
|
)
|
|
);
|
|
}
|
|
|
|
$this->cluster->save();
|
|
|
|
return;
|
|
}
|
|
|
|
if ($this->page === 3) {
|
|
/*
|
|
*
|
|
* PARSE AA MODULES.
|
|
*
|
|
*/
|
|
|
|
$aa_modules = get_parameter('selected-select-aa-modules', null);
|
|
|
|
if (is_array($aa_modules) === true) {
|
|
if ($aa_modules[0] === '0') {
|
|
unset($aa_modules[0]);
|
|
}
|
|
|
|
$current = array_keys($this->cluster->getAAModules());
|
|
$removed = array_diff($current, $aa_modules);
|
|
$changes = false;
|
|
|
|
foreach ($aa_modules as $m) {
|
|
$this->cluster->addAAModule($m);
|
|
$changes = true;
|
|
}
|
|
|
|
foreach ($removed as $m) {
|
|
$this->cluster->removeAAModule($m);
|
|
$changes = true;
|
|
}
|
|
|
|
if ($changes === true) {
|
|
$this->cluster->save();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if ($this->page === 4) {
|
|
/*
|
|
*
|
|
* PARSE AA THRESHOLDS
|
|
*
|
|
*/
|
|
|
|
$modules = $this->cluster->getAAModules();
|
|
|
|
$changes = false;
|
|
|
|
foreach ($modules as $item) {
|
|
$value_warning = get_parameter(
|
|
'warning-'.md5($item->name()),
|
|
null
|
|
);
|
|
|
|
$value_critical = get_parameter(
|
|
'critical-'.md5($item->name()),
|
|
null
|
|
);
|
|
|
|
if ($value_warning !== null) {
|
|
$item->warning_limit($value_warning);
|
|
$changes = true;
|
|
}
|
|
|
|
if ($value_critical !== null) {
|
|
$item->critical_limit($value_critical);
|
|
$changes = true;
|
|
}
|
|
}
|
|
|
|
if ($changes === true) {
|
|
$this->cluster->save();
|
|
}
|
|
|
|
if ($this->cluster->cluster_type() === 'AA') {
|
|
// Force next page '6' (alerts).
|
|
$this->page = 6;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if ($this->page === 5) {
|
|
/*
|
|
*
|
|
* PARSE AP MODULES
|
|
*
|
|
*/
|
|
|
|
if ($this->cluster->cluster_type() === 'AA') {
|
|
// Direct access. Accessed by URL.
|
|
$this->page = 0;
|
|
throw new \Exception(
|
|
'Unavailable page for this cluster type, please follow this wizard.'
|
|
);
|
|
}
|
|
|
|
$ap_modules = get_parameter('selected-select-ap-modules', null);
|
|
if (is_array($ap_modules) === true) {
|
|
if ($ap_modules[0] === '0') {
|
|
unset($ap_modules[0]);
|
|
}
|
|
|
|
$current = array_keys($this->cluster->getAPModules());
|
|
$removed = array_diff($current, $ap_modules);
|
|
$changes = false;
|
|
|
|
foreach ($ap_modules as $m) {
|
|
$this->cluster->addAPModule($m);
|
|
$changes = true;
|
|
}
|
|
|
|
foreach ($removed as $m) {
|
|
$this->cluster->removeAPModule($m);
|
|
$changes = true;
|
|
}
|
|
|
|
if ($changes === true) {
|
|
$this->cluster->save();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if ($this->page === 6) {
|
|
/*
|
|
*
|
|
* PARSE AP MODULES CRITICAL
|
|
*
|
|
*/
|
|
|
|
if ($this->cluster->cluster_type() === 'AA') {
|
|
// Direct access.
|
|
return;
|
|
}
|
|
|
|
$modules = $this->cluster->getAPModules();
|
|
$changes = false;
|
|
|
|
foreach ($modules as $item) {
|
|
$value = get_parameter_switch(
|
|
'switch-'.md5($item->name()),
|
|
null
|
|
);
|
|
|
|
if ($value !== null) {
|
|
// Unchecked.
|
|
$item->is_critical($value);
|
|
$changes = true;
|
|
}
|
|
}
|
|
|
|
if ($changes === true) {
|
|
$this->cluster->save();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if ($this->page === 7) {
|
|
/*
|
|
*
|
|
* PARSE ALERTS
|
|
*
|
|
*/
|
|
|
|
// There is no need to parse anything. Already managed by alert
|
|
// builder.
|
|
header('Location: '.$this->url.'&op=view&id='.$this->cluster->id());
|
|
}
|
|
|
|
throw new \Exception('Unexpected error');
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieves form estructure for current step.
|
|
*
|
|
* @param boolean $load_success Load process has been success or not.
|
|
*
|
|
* @return array Form.
|
|
*/
|
|
private function getForm(?bool $load_success=true)
|
|
{
|
|
$form = [];
|
|
$final = false;
|
|
|
|
$extra_url = '';
|
|
if ($this->cluster->id() !== null) {
|
|
$extra_url = '&id='.$this->cluster->id();
|
|
}
|
|
|
|
$url = $this->url.'&op='.$this->operation;
|
|
$target_url .= $url.'&page='.($this->page + 1).$extra_url;
|
|
|
|
$form['form'] = [
|
|
'action' => $target_url,
|
|
'method' => 'POST',
|
|
'extra' => 'autocomplete="false"',
|
|
'id' => 'cluster-edit-'.($this->page + 1),
|
|
];
|
|
|
|
if ($load_success === false && $this->page !== 0) {
|
|
return [];
|
|
}
|
|
|
|
if ($this->page === 0) {
|
|
/*
|
|
*
|
|
* Page: Cluster Definition.
|
|
*
|
|
*/
|
|
|
|
// Input cluster name.
|
|
$form['inputs'][] = [
|
|
'label' => '<b>'.__('Cluster name').'</b>'.ui_print_help_tip(
|
|
__('An agent with the same name of the cluster will be created, as well a special service with the same name'),
|
|
true
|
|
),
|
|
'arguments' => [
|
|
'name' => 'name',
|
|
'value' => $this->cluster->name(),
|
|
'type' => 'text',
|
|
'size' => 25,
|
|
'required' => true,
|
|
],
|
|
];
|
|
|
|
// Input cluster type.
|
|
$form['inputs'][] = [
|
|
'label' => '<b>'.__('Cluster type').'</b>'.ui_print_help_tip(
|
|
__('AA is a cluster where all members are working. In AP cluster only master member is working'),
|
|
true
|
|
),
|
|
'arguments' => [
|
|
'name' => 'type',
|
|
'selected' => $this->cluster->cluster_type(),
|
|
'type' => 'select',
|
|
'fields' => [
|
|
'AA' => __('Active - Active'),
|
|
'AP' => __('Active - Pasive'),
|
|
],
|
|
'required' => true,
|
|
],
|
|
];
|
|
|
|
// Input cluster description.
|
|
$form['inputs'][] = [
|
|
'label' => '<b>'.__('Description').'</b>',
|
|
'arguments' => [
|
|
'name' => 'description',
|
|
'value' => $this->cluster->description(),
|
|
'type' => 'text',
|
|
'size' => 25,
|
|
],
|
|
];
|
|
|
|
// Input Group.
|
|
$form['inputs'][] = [
|
|
'label' => '<b>'.__('Group').'</b>'.ui_print_help_tip(
|
|
__('Target cluster agent will be stored under this group'),
|
|
true
|
|
),
|
|
'arguments' => [
|
|
'name' => 'id_group',
|
|
'returnAllGroup' => false,
|
|
'privilege' => $this->access,
|
|
'type' => 'select_groups',
|
|
'selected' => $this->cluster->group()->id_grupo(),
|
|
'return' => true,
|
|
'required' => true,
|
|
],
|
|
];
|
|
|
|
// Input. Servername.
|
|
$form['inputs'][] = [
|
|
'label' => '<b>'.__('Prediction server').':</b>'.ui_print_help_tip(
|
|
__('You must select a Prediction Server to perform all cluster status calculations'),
|
|
true
|
|
),
|
|
'arguments' => [
|
|
'type' => 'select_from_sql',
|
|
'sql' => sprintf(
|
|
'SELECT name as k, name as v
|
|
FROM tserver
|
|
WHERE server_type = %d
|
|
ORDER BY name',
|
|
SERVER_TYPE_PREDICTION
|
|
),
|
|
'name' => 'server_name',
|
|
'selected' => $this->cluster->agent()->server_name(),
|
|
'return' => true,
|
|
'required' => true,
|
|
],
|
|
];
|
|
} else if ($this->page === 1) {
|
|
/*
|
|
*
|
|
* Page: Cluster members.
|
|
*
|
|
*/
|
|
|
|
$all_agents = agents_get_agents(
|
|
false,
|
|
[
|
|
'id_agente',
|
|
'alias',
|
|
]
|
|
);
|
|
|
|
if ($all_agents === false) {
|
|
$all_agents = [];
|
|
}
|
|
|
|
$all_agents = array_reduce(
|
|
$all_agents,
|
|
function ($carry, $item) {
|
|
$carry[$item['id_agente']] = $item['alias'];
|
|
return $carry;
|
|
},
|
|
[]
|
|
);
|
|
|
|
$selected = $this->cluster->getMembers();
|
|
|
|
$selected = array_reduce(
|
|
$selected,
|
|
function ($carry, $item) use (&$all_agents) {
|
|
$carry[$item->id_agente()] = $item->alias();
|
|
unset($all_agents[$item->id_agente()]);
|
|
return $carry;
|
|
},
|
|
[]
|
|
);
|
|
|
|
$form['inputs'][] = [
|
|
'arguments' => [
|
|
'type' => 'select_multiple_filtered',
|
|
'class' => 'w80p mw600px',
|
|
'name' => 'members',
|
|
'available' => $all_agents,
|
|
'selected' => $selected,
|
|
'group_filter' => [
|
|
'page' => 'operation/cluster/cluster',
|
|
'method' => 'getAgentsFromGroup',
|
|
'id' => $this->cluster->id(),
|
|
],
|
|
'texts' => [
|
|
'title-left' => 'Available agents',
|
|
'title-right' => 'Selected cluster members',
|
|
],
|
|
],
|
|
];
|
|
} else if ($this->page === 2) {
|
|
/*
|
|
*
|
|
* Page: A-A modules.
|
|
*
|
|
*/
|
|
|
|
$selected = $this->cluster->getAAModules();
|
|
|
|
$selected = array_reduce(
|
|
$selected,
|
|
function ($carry, $item) {
|
|
$name = io_safe_output($item->name());
|
|
$carry[$name] = $name;
|
|
return $carry;
|
|
},
|
|
[]
|
|
);
|
|
|
|
$members = $this->cluster->getMembers();
|
|
|
|
// Agent ids are stored in array keys.
|
|
$members = array_keys($members);
|
|
|
|
// Get common modules.
|
|
$modules = \select_modules_for_agent_group(
|
|
// Module group. 0 => All.
|
|
0,
|
|
// Agents.
|
|
$members,
|
|
// Show all modules or common ones.
|
|
false,
|
|
// Return.
|
|
false,
|
|
// Group by name.
|
|
true
|
|
);
|
|
|
|
// Escape html special chars on array keys for select value.
|
|
$modules = array_combine(
|
|
array_map(
|
|
function ($k) {
|
|
return htmlspecialchars($k);
|
|
},
|
|
array_keys($modules)
|
|
),
|
|
$modules
|
|
);
|
|
|
|
$selected = array_combine(
|
|
array_map(
|
|
function ($k) {
|
|
return htmlspecialchars($k);
|
|
},
|
|
array_keys($selected)
|
|
),
|
|
$selected
|
|
);
|
|
|
|
$modules = array_diff_key($modules, $selected);
|
|
if ($this->cluster->cluster_type() === 'AP') {
|
|
$form['inputs'][] = [
|
|
'arguments' => [
|
|
'type' => 'select_multiple_filtered',
|
|
'class' => 'w80p mw600px',
|
|
'name' => 'aa-modules',
|
|
'available' => $modules,
|
|
'selected' => $selected,
|
|
'texts' => [
|
|
'title-left' => 'Available modules (common)',
|
|
'title-right' => 'Selected active-passive modules',
|
|
'filter-item' => 'Filter options by module name',
|
|
],
|
|
'sections' => [
|
|
'filters' => 1,
|
|
'item-available-filter' => 1,
|
|
'item-selected-filter' => 1,
|
|
],
|
|
],
|
|
];
|
|
} else if ($this->cluster->cluster_type() === 'AA') {
|
|
$form['inputs'][] = [
|
|
'arguments' => [
|
|
'type' => 'select_multiple_filtered',
|
|
'class' => 'w80p mw600px',
|
|
'name' => 'aa-modules',
|
|
'available' => $modules,
|
|
'selected' => $selected,
|
|
'texts' => [
|
|
'title-left' => 'Available modules (common)',
|
|
'title-right' => 'Selected active-active modules',
|
|
'filter-item' => 'Filter options by module name',
|
|
],
|
|
'sections' => [
|
|
'filters' => 1,
|
|
'item-available-filter' => 1,
|
|
'item-selected-filter' => 1,
|
|
],
|
|
],
|
|
];
|
|
}
|
|
} else if ($this->page === 3) {
|
|
/*
|
|
*
|
|
* Page: A-A module limits.
|
|
*
|
|
*/
|
|
|
|
$aa_modules = $this->cluster->getAAModules();
|
|
$inputs = [];
|
|
foreach ($aa_modules as $module) {
|
|
$inputs[] = [
|
|
'block_id' => 'from-to-threshold',
|
|
'label' => '<b>'.$module->name().'</b>',
|
|
'class' => 'flex-row line w100p',
|
|
'direct' => 1,
|
|
'block_content' => [
|
|
[
|
|
'label' => '<i>'.$module->name().'</i>',
|
|
],
|
|
[
|
|
'label' => '<b class="state">'.__('critical if').'</b>',
|
|
'arguments' => [
|
|
'name' => 'critical-'.md5($module->name()),
|
|
'type' => 'number',
|
|
'value' => $module->critical_limit(),
|
|
'required' => true,
|
|
],
|
|
],
|
|
[
|
|
'label' => __('% of balanced modules are down (equal or greater).'),
|
|
],
|
|
],
|
|
];
|
|
|
|
$inputs[] = [
|
|
'block_id' => 'from-to-threshold',
|
|
'class' => 'flex-row line w100p',
|
|
'direct' => 1,
|
|
'block_content' => [
|
|
[
|
|
'label' => '<i>'.$module->name().'</i>',
|
|
],
|
|
[
|
|
'label' => '<b class="state">'.('warning if').'</b>',
|
|
'arguments' => [
|
|
'name' => 'warning-'.md5($module->name()),
|
|
'type' => 'number',
|
|
'value' => $module->warning_limit(),
|
|
'required' => true,
|
|
],
|
|
],
|
|
[
|
|
'label' => __('% of balanced modules are down (equal or greater).'),
|
|
],
|
|
],
|
|
];
|
|
|
|
$inputs[] = [
|
|
'block_id' => 'from-to-threshold',
|
|
'class' => 'flex-row line w100p',
|
|
'direct' => 1,
|
|
'block_content' => [],
|
|
];
|
|
}
|
|
|
|
if ($this->cluster->cluster_type() === 'AP') {
|
|
$form['inputs'][] = [
|
|
'label' => __(
|
|
'Please, set thresholds for all active-passive modules'.ui_print_help_tip(
|
|
'If you want your cluster module to be critical when 3 of 6 instances are down, set critical to \'50%\'',
|
|
true
|
|
)
|
|
),
|
|
'class' => 'indented',
|
|
'block_content' => $inputs,
|
|
];
|
|
} else if ($this->cluster->cluster_type() === 'AA') {
|
|
$form['inputs'][] = [
|
|
'label' => __(
|
|
'Please, set thresholds for all active-active modules'.ui_print_help_tip(
|
|
'If you want your cluster module to be critical when 3 of 6 instances are down, set critical to \'50%\'',
|
|
true
|
|
)
|
|
),
|
|
'class' => 'indented',
|
|
'block_content' => $inputs,
|
|
];
|
|
}
|
|
} else if ($this->page === 4) {
|
|
/*
|
|
*
|
|
* Page: A-P modules.
|
|
*
|
|
*/
|
|
|
|
$selected = $this->cluster->getAPModules();
|
|
$aa = $this->cluster->getAAModules();
|
|
|
|
$selected = array_reduce(
|
|
$selected,
|
|
function ($carry, $item) {
|
|
$name = io_safe_output($item->name());
|
|
$carry[$name] = $name;
|
|
return $carry;
|
|
},
|
|
[]
|
|
);
|
|
|
|
$aa = array_reduce(
|
|
$aa,
|
|
function ($carry, $item) {
|
|
$name = io_safe_output($item->name());
|
|
$carry[$name] = $name;
|
|
return $carry;
|
|
},
|
|
[]
|
|
);
|
|
|
|
$members = $this->cluster->getMembers();
|
|
|
|
// Agent ids are stored in array keys.
|
|
$members = array_keys($members);
|
|
|
|
// Get common modules.
|
|
$modules = \select_modules_for_agent_group(
|
|
// Module group. 0 => All.
|
|
0,
|
|
// Agents.
|
|
$members,
|
|
// Show all modules or common ones.
|
|
true,
|
|
// Return.
|
|
false,
|
|
// Group by name.
|
|
true
|
|
);
|
|
|
|
// Exclude AA modules from available options.
|
|
$modules = array_diff_key($modules, $aa);
|
|
|
|
// Exclude already used from available options.
|
|
$modules = array_diff_key($modules, $selected);
|
|
|
|
$form['inputs'][] = [
|
|
'arguments' => [
|
|
'type' => 'select_multiple_filtered',
|
|
'class' => 'w80p mw600px',
|
|
'name' => 'ap-modules',
|
|
'available' => $modules,
|
|
'selected' => $selected,
|
|
'texts' => [
|
|
'title-left' => 'Available modules (any)',
|
|
'title-right' => 'Selected active-passive modules',
|
|
'filter-item' => 'Filter options by module name',
|
|
],
|
|
'sections' => [
|
|
'filters' => 1,
|
|
'item-available-filter' => 1,
|
|
'item-selected-filter' => 1,
|
|
],
|
|
],
|
|
];
|
|
} else if ($this->page === 5) {
|
|
/*
|
|
*
|
|
* Page: A-P critical modules.
|
|
*
|
|
*/
|
|
|
|
$ap_modules = $this->cluster->getAPModules();
|
|
$inputs = [];
|
|
foreach ($ap_modules as $module) {
|
|
$inputs[] = [
|
|
'label' => $module->name(),
|
|
'arguments' => [
|
|
'type' => 'switch',
|
|
'name' => 'switch-'.md5($module->name()),
|
|
'value' => $module->is_critical(),
|
|
],
|
|
];
|
|
}
|
|
|
|
$form['inputs'][] = [
|
|
'label' => __(
|
|
'Please, check all active-passive modules critical for this cluster'
|
|
).ui_print_help_tip(
|
|
__('If a critical balanced module is going to critical status, then cluster will be critical.'),
|
|
true
|
|
),
|
|
'class' => 'indented',
|
|
'block_content' => $inputs,
|
|
];
|
|
} else if ($this->page === 6) {
|
|
/*
|
|
*
|
|
* Page: Alerts.
|
|
*
|
|
*/
|
|
|
|
ob_start();
|
|
global $config;
|
|
|
|
$id_agente = $this->cluster->agent()->id_agente();
|
|
$dont_display_alert_create_bttn = true;
|
|
include_once $config['homedir'].'/godmode/alerts/alert_list.php';
|
|
include_once $config['homedir'].'/godmode/alerts/alert_list.builder.php';
|
|
|
|
// XXX: Please do not use this kind of thing never more.
|
|
$hack = ob_get_clean();
|
|
|
|
// TODO: Alert form.
|
|
$form['pre-content'] = $hack;
|
|
|
|
$final = true;
|
|
}
|
|
|
|
// Submit.
|
|
$str = __('Next');
|
|
if ($this->cluster->id() !== null) {
|
|
$str = __('Update and continue');
|
|
}
|
|
|
|
if ($final === true) {
|
|
$str = __('Finish');
|
|
}
|
|
|
|
// Submit button.
|
|
$form['submit-external-input'] = [
|
|
'name' => 'next',
|
|
'label' => $str,
|
|
'type' => 'submit',
|
|
'attributes' => [
|
|
'icon' => 'wand',
|
|
'mode' => 'primary',
|
|
'form' => 'cluster-edit-'.($this->page + 1),
|
|
],
|
|
'return' => true,
|
|
];
|
|
|
|
return $form;
|
|
}
|
|
|
|
|
|
}
|