RedisConfigForm: Validate the configuration upon save

This commit is contained in:
Johannes Meyer 2020-04-20 14:09:17 +02:00
parent 90d3d6194d
commit 7d602ac03f

View file

@ -4,18 +4,25 @@
namespace Icinga\Module\Icingadb\Forms;
use Icinga\Data\ResourceFactory;
use Exception;
use Icinga\Forms\ConfigForm;
use Redis;
class RedisConfigForm extends ConfigForm
{
public function init()
{
$this->setSubmitLabel(t('Save Changes'));
$this->setValidatePartial(true);
}
public function createElements(array $formData)
{
if (isset($formData['skip_validation']) && $formData['skip_validation']) {
// In case another error occured and the checkbox was displayed before
static::addSkipValidationCheckbox($this);
}
$this->addElement('text', 'redis1_host', [
'description' => t('Redis Host'),
'label' => t('Redis Host'),
@ -81,4 +88,145 @@ class RedisConfigForm extends ConfigForm
]
);
}
public static function addSkipValidationCheckbox($form)
{
$form->addElement(
'checkbox',
'skip_validation',
[
'order' => 0,
'ignore' => true,
'label' => t('Skip Validation'),
'description' => t(
'Check this box to enforce changes without validating that Redis is available.'
)
]
);
}
public function isValid($formData)
{
if (! parent::isValid($formData)) {
return false;
}
if (($el = $this->getElement('skip_validation')) === null || ! $el->isChecked()) {
if (! static::checkRedis($this)) {
if ($el === null) {
static::addSkipValidationCheckbox($this);
}
return false;
}
}
return true;
}
public function isValidPartial(array $formData)
{
if (! parent::isValidPartial($formData)) {
return false;
}
if ($this->getElement('backend_validation')->isChecked()) {
return static::checkRedis($this);
}
return true;
}
public function addSubmitButton()
{
parent::addSubmitButton()
->getElement('btn_submit')
->setDecorators(['ViewHelper']);
$this->addElement(
'submit',
'backend_validation',
[
'ignore' => true,
'label' => t('Validate Configuration'),
'data-progress-label' => t('Validation In Progress'),
'decorators' => ['ViewHelper']
]
);
$this->addDisplayGroup(
['btn_submit', 'backend_validation'],
'submit_validation',
[
'decorators' => [
'FormElements',
['HtmlTag', ['tag' => 'div', 'class' => 'control-group form-controls']]
]
]
);
return $this;
}
public static function checkRedis($form)
{
$streamy = version_compare(phpversion('redis'), '4.3.0', '>=');
$priPort = $form->getElement('redis1_port')->getValue();
try {
$redis1 = new Redis();
$redis1->connect(
$form->getElement('redis1_host')->getValue(),
empty($priPort) ? 6380 : $priPort,
0.5
);
} catch (Exception $e) {
$form->warning(sprintf(
t('Failed to connect to primary Redis: %s'),
$e->getMessage()
));
return false;
}
if ($streamy) {
$rs = $redis1->xRead(['icinga:stats' => 0], 1);
if (empty($rs)) {
$form->warning(t(
'Primary connection established but failed to verify Icinga is connected as well.'
));
return false;
}
}
if (($secHost = $form->getElement('redis2_host')->getValue())) {
$secPort = $form->getElement('redis2_port')->getValue();
try {
$redis2 = new Redis();
$redis2->connect(
$secHost,
empty($secPort) ? 6380 : $secPort,
0.5
);
} catch (Exception $e) {
$form->warning(sprintf(
t('Failed to connect to secondary Redis: %s'),
$e->getMessage()
));
return false;
}
if ($streamy) {
$rs = $redis2->xRead(['icinga:stats' => 0], 1);
if (empty($rs)) {
$form->warning(t(
'Secondary connection established but failed to verify Icinga is connected as well.'
));
return false;
}
}
}
$form->info(t('The configuration has been successfully validated.'));
return true;
}
}