Merge branch 'feature/validate-pgsql-version-9460'

resolves #9460
This commit is contained in:
Johannes Meyer 2015-08-19 14:45:10 +02:00
commit 23f0686936
4 changed files with 144 additions and 59 deletions

View File

@ -8,6 +8,7 @@ use Icinga\Forms\Config\ResourceConfigForm;
use Icinga\Forms\Config\Resource\DbResourceForm; use Icinga\Forms\Config\Resource\DbResourceForm;
use Icinga\Web\Form; use Icinga\Web\Form;
use Icinga\Module\Monitoring\Forms\Config\BackendConfigForm; use Icinga\Module\Monitoring\Forms\Config\BackendConfigForm;
use Icinga\Module\Setup\Utils\DbTool;
class IdoResourcePage extends Form class IdoResourcePage extends Form
{ {
@ -73,23 +74,8 @@ class IdoResourcePage extends Form
} }
if (! isset($formData['skip_validation']) || !$formData['skip_validation']) { if (! isset($formData['skip_validation']) || !$formData['skip_validation']) {
$inspection = ResourceConfigForm::inspectResource($this); if (! $this->validateConfiguration()) {
if ($inspection !== null && $inspection->hasError()) { $this->addSkipValidationCheckbox();
$this->error($inspection->getError());
$this->addSkipValidationCheckbox($this->translate(
'Check this to not to validate connectivity with the given database server.'
));
return false;
}
$configObject = new ConfigObject($this->getValues());
if (
! BackendConfigForm::isValidIdoSchema($this, $configObject)
|| !BackendConfigForm::isValidIdoInstance($this, $configObject)
) {
$this->addSkipValidationCheckbox($this->translate(
'Check this to not to validate the IDO schema in the given database.'
));
return false; return false;
} }
} }
@ -109,8 +95,31 @@ class IdoResourcePage extends Form
public function isValidPartial(array $formData) public function isValidPartial(array $formData)
{ {
if (isset($formData['backend_validation']) && parent::isValid($formData)) { if (isset($formData['backend_validation']) && parent::isValid($formData)) {
$inspection = ResourceConfigForm::inspectResource($this); if (! $this->validateConfiguration(true)) {
if ($inspection !== null) { return false;
}
$this->info($this->translate('The configuration has been successfully validated.'));
} elseif (! isset($formData['backend_validation'])) {
// This is usually done by isValid(Partial), but as we're not calling any of these...
$this->populate($formData);
}
return true;
}
/**
* Return whether the configuration is valid
*
* @param bool $showLog Whether to show the validation log
*
* @return bool
*/
protected function validateConfiguration($showLog = false)
{
$inspection = ResourceConfigForm::inspectResource($this);
if ($inspection !== null) {
if ($showLog) {
$join = function ($e) use (& $join) { $join = function ($e) use (& $join) {
return is_string($e) ? $e : join("\n", array_map($join, $e)); return is_string($e) ? $e : join("\n", array_map($join, $e));
}; };
@ -127,45 +136,53 @@ class IdoResourcePage extends Form
) )
) )
); );
if ($inspection->hasError()) {
$this->warning(sprintf(
$this->translate('Failed to successfully validate the configuration: %s'),
$inspection->getError()
));
return false;
}
} }
$this->info($this->translate('The configuration has been successfully validated.')); if ($inspection->hasError()) {
} elseif (! isset($formData['backend_validation'])) { $this->error(sprintf(
// This is usually done by isValid(Partial), but as we're not calling any of these... $this->translate('Failed to successfully validate the configuration: %s'),
$this->populate($formData); $inspection->getError()
));
return false;
}
}
$configObject = new ConfigObject($this->getValues());
if (
! BackendConfigForm::isValidIdoSchema($this, $configObject)
|| !BackendConfigForm::isValidIdoInstance($this, $configObject)
) {
return false;
}
if ($this->getValue('db') === 'pgsql') {
$db = new DbTool($this->getValues());
$version = $db->connectToDb()->getServerVersion();
if (version_compare($version, '9.1', '<')) {
$this->error($this->translate(sprintf(
'The server\'s version %s is too old. The minimum required version is %s.',
$version,
'9.1'
)));
return false;
}
} }
return true; return true;
} }
/** /**
* Add a checkbox to the form by which the user can skip the resource validation * Add a checkbox to the form by which the user can skip the configuration validation
*
* @param string $description
*/ */
protected function addSkipValidationCheckbox($description = null) protected function addSkipValidationCheckbox()
{ {
if (empty($description)) {
$description = $this->translate(
'Proceed without any further (custom) validation.'
);
}
$this->addElement( $this->addElement(
'checkbox', 'checkbox',
'skip_validation', 'skip_validation',
array( array(
'required' => true, 'required' => true,
'label' => $this->translate('Skip Validation'), 'label' => $this->translate('Skip Validation'),
'description' => $description 'description' => $this->translate('Check this to not to validate the configuration')
) )
); );
} }

View File

@ -15,6 +15,11 @@ class Setup_IndexController extends Controller
*/ */
protected $requiresAuthentication = false; protected $requiresAuthentication = false;
/**
* {@inheritdoc}
*/
protected $innerLayout = 'inline';
/** /**
* Show the web wizard and run the configuration once finished * Show the web wizard and run the configuration once finished
*/ */

View File

@ -68,11 +68,7 @@ class DbResourcePage extends Form
} }
if (false === isset($data['skip_validation']) || $data['skip_validation'] == 0) { if (false === isset($data['skip_validation']) || $data['skip_validation'] == 0) {
try { if (! $this->validateConfiguration()) {
$db = new DbTool($this->getValues());
$db->checkConnectivity();
} catch (PDOException $e) {
$this->error($e->getMessage());
$this->addSkipValidationCheckbox(); $this->addSkipValidationCheckbox();
return false; return false;
} }
@ -93,14 +89,7 @@ class DbResourcePage extends Form
public function isValidPartial(array $formData) public function isValidPartial(array $formData)
{ {
if (isset($formData['backend_validation']) && parent::isValid($formData)) { if (isset($formData['backend_validation']) && parent::isValid($formData)) {
try { if (! $this->validateConfiguration()) {
$db = new DbTool($this->getValues());
$db->checkConnectivity();
} catch (PDOException $e) {
$this->warning(sprintf(
$this->translate('Failed to successfully validate the configuration: %s'),
$e->getMessage()
));
return false; return false;
} }
@ -114,7 +103,55 @@ class DbResourcePage extends Form
} }
/** /**
* Add a checkbox to the form by which the user can skip the connection validation * Return whether the configuration is valid
*
* @return bool
*/
protected function validateConfiguration()
{
try {
$db = new DbTool($this->getValues());
$db->checkConnectivity();
} catch (PDOException $e) {
$this->error(sprintf(
$this->translate('Failed to successfully validate the configuration: %s'),
$e->getMessage()
));
return false;
}
if ($this->getValue('db') === 'pgsql') {
if (! $db->isConnected()) {
try {
$db->connectToDb();
} catch (PDOException $e) {
$this->warning($this->translate(sprintf(
'Unable to check the server\'s version. This is usually not a critical error as there is'
. ' probably only access to the database permitted which does not exist yet. If you are'
. ' absolutely sure you are running PostgreSQL in a version equal to or newer than 9.1,'
. ' you can skip the validation and safely proceed to the next step. The error was: %s',
$e->getMessage()
)));
return false;
}
}
$version = $db->getServerVersion();
if (version_compare($version, '9.1', '<')) {
$this->error($this->translate(sprintf(
'The server\'s version %s is too old. The minimum required version is %s.',
$version,
'9.1'
)));
return false;
}
}
return true;
}
/**
* Add a checkbox to the form by which the user can skip the configuration validation
*/ */
protected function addSkipValidationCheckbox() protected function addSkipValidationCheckbox()
{ {
@ -124,9 +161,7 @@ class DbResourcePage extends Form
array( array(
'required' => true, 'required' => true,
'label' => $this->translate('Skip Validation'), 'label' => $this->translate('Skip Validation'),
'description' => $this->translate( 'description' => $this->translate('Check this to not to validate the configuration')
'Check this to not to validate connectivity with the given database server'
)
) )
); );
} }

View File

@ -204,6 +204,16 @@ class DbTool
} }
} }
/**
* Return whether a connection with the server has been established
*
* @return bool
*/
public function isConnected()
{
return $this->pdoConn !== null;
}
/** /**
* Establish a connection with the database or just the server by omitting the database name * Establish a connection with the database or just the server by omitting the database name
* *
@ -434,6 +444,24 @@ class DbTool
return $stmt; return $stmt;
} }
/**
* Return the version of the server currently connected to
*
* @return string|null
*/
public function getServerVersion()
{
if ($this->config['db'] === 'mysql') {
return $this->query('show variables like "version"')->fetchColumn(1) ?: null;
} elseif ($this->config['db'] === 'pgsql') {
return $this->query('show server_version')->fetchColumn() ?: null;
} else {
throw new LogicException(
sprintf('Unable to fetch the server\'s version. Unsupported PDO driver "%s"', $this->config['db'])
);
}
}
/** /**
* Import the given SQL file * Import the given SQL file
* *