Adjust Monitoring\BackendForm to use handleRequest() & Co.

refs #5525
This commit is contained in:
Johannes Meyer 2014-09-04 11:25:47 +02:00
parent 9d66cc9023
commit 439d1895a7
4 changed files with 346 additions and 328 deletions

View File

@ -2,14 +2,13 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Config\PreservingIniWriter;
use Icinga\Web\Controller\ModuleActionController;
use Icinga\Web\Notification;
use Icinga\Data\ResourceFactory;
use Icinga\Form\ConfirmRemovalForm;
use Icinga\Module\Monitoring\Form\Config\BackendForm;
use Icinga\Web\Controller\ModuleActionController;
use Icinga\Module\Monitoring\Form\Config\BackendConfigForm;
use Icinga\Module\Monitoring\Form\Config\InstanceConfigForm;
use Icinga\Module\Monitoring\Form\Config\SecurityConfigForm;
use Icinga\Exception\NotReadableError;
/**
* Configuration controller for editing monitoring resources
@ -21,19 +20,9 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function indexAction()
{
$this->view->backendsConfig = $this->Config('backends');
$this->view->instancesConfig = $this->Config('instances');
$this->view->tabs = $this->Module()->getConfigTabs()->activate('backends');
foreach (array('backends', 'instances') as $element) {
try {
$elementConfig = $this->Config($element);
if ($elementConfig === null) {
$this->view->{$element} = array();
} else {
$this->view->{$element} = $elementConfig->toArray();
}
} catch (NotReadableError $e) {
$this->view->{$element} = $e;
}
}
}
/**
@ -41,38 +30,11 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function editbackendAction()
{
// Fetch the backend to be edited
$backend = $this->getParam('backend');
$backendsConfig = $this->Config('backends')->toArray();
if (false === array_key_exists($backend, $backendsConfig)) {
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
Notification::error(sprintf($this->translate('Cannot edit "%s". Backend not found.'), $backend));
$this->redirectNow('monitoring/config');
}
$form = new BackendForm();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
list($newName, $config) = $form->getBackendConfig();
if ($newName !== $backend) {
// Backend name has changed
unset($backendsConfig[$backend]); // We can safely use unset as all values are part of the form
}
$backendsConfig[$newName] = $config;
if ($this->writeConfiguration($backendsConfig, 'backends')) {
Notification::success(sprintf($this->translate('Backend "%s" successfully modified.'), $backend));
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
}
}
} else {
$form->setBackendConfig($backend, $backendsConfig[$backend]);
}
$form = new BackendConfigForm();
$form->setConfig($this->Config('backends'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
}
@ -82,20 +44,11 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function createbackendAction()
{
$form = new BackendForm();
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getPost())) {
list($name, $config) = $form->getBackendConfig();
$backendsConfig = $this->Config('backends')->toArray();
$backendsConfig[$name] = $config;
if ($this->writeConfiguration($backendsConfig, 'backends')) {
Notification::success(sprintf($this->translate('Backend "%s" created successfully.'), $name));
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
}
}
$form = new BackendConfigForm();
$form->setConfig($this->Config('backends'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
}
@ -105,26 +58,29 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function removebackendAction()
{
$backend = $this->getParam('backend');
$backendsConfig = $this->Config('backends')->toArray();
if (false === array_key_exists($backend, $backendsConfig)) {
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
Notification::error(sprintf($this->translate('Cannot remove "%s". Backend not found.'), $backend));
$this->redirectNow('monitoring/config');
}
$config = $this->Config('backends');
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) use ($config) {
$backendName = $request->getQuery('backend');
$configForm = new BackendConfigForm();
$configForm->setConfig($config);
$form = new ConfirmRemovalForm();
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getPost())) {
unset($backendsConfig[$backend]);
if ($this->writeConfiguration($backendsConfig, 'backends')) {
Notification::success(sprintf($this->translate('Backend "%s" successfully removed.'), $backend));
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
try {
$configForm->remove($backendName);
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
if ($configForm->save()) {
Notification::success(sprintf(t('Backend "%s" successfully removed.'), $backendName));
} else {
return false;
}
}
}
));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
}
@ -187,34 +143,6 @@ class Monitoring_ConfigController extends ModuleActionController
$this->view->form = $form;
}
/**
* Write configuration to an ini file
*
* @param Zend_Config $config The configuration to write
* @param string $file The config file to write to
*
* @return bool Whether the configuration was written or not
*/
protected function writeConfiguration($config, $file = null)
{
if (is_array($config)) {
$config = new Zend_Config($config);
}
$target = $this->Config($file)->getConfigFile();
$writer = new PreservingIniWriter(array('filename' => $target, 'config' => $config));
try {
$writer->write();
} catch (Exception $exc) {
$this->view->exceptionMessage = $exc->getMessage();
$this->view->iniConfigurationString = $writer->render();
$this->view->file = $target;
return false;
}
return true;
}
/**
* Display a form to adjust security relevant settings
*/

View File

@ -0,0 +1,244 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
use Icinga\Application\Config;
use Icinga\Exception\ConfigurationError;
/**
* Form class for creating/modifying monitoring backends
*/
class BackendConfigForm extends ConfigForm
{
/**
* The available monitoring backend resources split by type
*
* @var array
*/
protected $resources;
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_monitoring_backends');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* Set the resource configuration to use
*
* @param Config $resources The resource configuration
*
* @return self
*
* @throws ConfigurationError In case there are no valid monitoring backend resources
*/
public function setResourceConfig(Config $resourceConfig)
{
$resources = array();
foreach ($resourceConfig as $name => $resource) {
if ($resource->type === 'db' || $resource->type === 'statusdat' || $resource->type === 'livestatus') {
$resources[$resource->type === 'db' ? 'ido' : strtolower($resource->type)][] = $name;
}
}
if (empty($resources)) {
throw new ConfigurationError(t('Could not find any valid monitoring backend resources'));
}
$this->resources = $resources;
return $this;
}
/**
* Add a particular monitoring backend
*
* The backend to add is identified by the array-key `name'.
*
* @param array $values The values to extend the configuration with
*
* @return self
*
* @throws InvalidArgumentException In case the backend does already exist
*/
public function add(array $values)
{
$name = isset($values['name']) ? $values['name'] : '';
if (! $name) {
throw new InvalidArgumentException(t('Monitoring backend name missing'));
} elseif ($this->config->get($name) !== null) {
throw new InvalidArgumentException(t('Monitoring backend already exists'));
}
unset($values['name']);
$this->config->{$name} = $values;
return $this;
}
/**
* Edit a particular monitoring backend
*
* @param string $name The name of the backend to edit
* @param array $values The values to edit the configuration with
*
* @return array The edited backend configuration
*
* @throws InvalidArgumentException In case the backend does not exist
*/
public function edit($name, array $values)
{
if (! $name) {
throw new InvalidArgumentException(t('Old monitoring backend name missing'));
} elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) {
throw new InvalidArgumentException(t('New monitoring backend name missing'));
} elseif (($backendConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown monitoring backend provided'));
}
unset($values['name']);
unset($this->config->{$name});
$this->config->{$newName} = $values;
return $this->config->{$newName};
}
/**
* Remove the given monitoring backend
*
* @param string $name The name of the backend to remove
*
* @return array The removed backend configuration
*
* @throws InvalidArgumentException In case the backend does not exist
*/
public function remove($name)
{
if (! $name) {
throw new InvalidArgumentException(t('Monitoring backend name missing'));
} elseif (($backendConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown monitoring backend provided'));
}
unset($this->config->{$name});
return $backendConfig;
}
/**
* Add or edit a monitoring backend and save the configuration
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
$monitoringBackend = $request->getQuery('backend');
try {
if ($monitoringBackend === null) { // create new backend
$this->add($this->getValues());
$message = t('Monitoring backend "%s" has been successfully created');
} else { // edit existing backend
$this->edit($monitoringBackend, $this->getValues());
$message = t('Monitoring backend "%s" has been successfully changed');
}
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
if ($this->save()) {
Notification::success(sprintf($message, $this->getElement('name')->getValue()));
} else {
return false;
}
}
/**
* Populate the form in case a monitoring backend is being edited
*
* @see Form::onRequest()
*
* @throws ConfigurationError In case the backend name is missing in the request or is invalid
*/
public function onRequest(Request $request)
{
$monitoringBackend = $request->getQuery('backend');
if ($monitoringBackend !== null) {
if ($monitoringBackend === '') {
throw new ConfigurationError(t('Monitoring backend name missing'));
} elseif (false === isset($this->config->{$monitoringBackend})) {
throw new ConfigurationError(t('Unknown monitoring backend provided'));
}
$backendConfig = $this->config->{$monitoringBackend}->toArray();
$backendConfig['name'] = $monitoringBackend;
$this->populate($backendConfig);
}
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$resourceType = isset($formData['type']) ? $formData['type'] : key($this->resources);
$resourceTypes = array();
if ($resourceType === 'ido' || array_key_exists('ido', $this->resources)) {
$resourceTypes['ido'] = 'IDO Backend';
}
if ($resourceType === 'statusdat' || array_key_exists('statusdat', $this->resources)) {
$resourceTypes['statusdat'] = 'Status.dat';
}
if ($resourceType === 'livestatus' || array_key_exists('livestatus', $this->resources)) {
$resourceTypes['livestatus'] = 'Livestatus';
}
$this->addElement(
'checkbox',
'disabled',
array(
'required' => true,
'label' => t('Disable This Backend')
)
);
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Backend Name'),
'description' => t('The identifier of this backend')
)
);
$this->addElement(
'select',
'type',
array(
'required' => true,
'autosubmit' => true,
'label' => t('Backend Type'),
'description' => t('The data source used for retrieving monitoring information'),
'multiOptions' => $resourceTypes,
'value' => $resourceType
)
);
$this->addElement(
'select',
'resource',
array(
'required' => true,
'label' => t('Resource'),
'description' => t('The resource to use'),
'multiOptions' => $this->resources[$resourceType]
)
);
return $this;
}
}

View File

@ -1,125 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config;
use Icinga\Web\Form;
use Icinga\Data\ResourceFactory;
/**
* Form for modifying a monitoring backend
*/
class BackendForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_monitoring_backends');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
return array(
$this->createElement(
'text',
'name',
array(
'required' => true,
'label' => t('Backend Name'),
'helptext' => t('The identifier of this backend')
)
),
$this->createElement(
'select',
'type',
array(
'required' => true,
'class' => 'autosubmit',
'label' => t('Backend Type'),
'helptext' => t('The data source used for retrieving monitoring information'),
'multiOptions' => array(
'ido' => 'IDO Backend',
'statusdat' => 'Status.dat',
'livestatus' => 'Livestatus'
)
)
),
$this->createElement(
'select',
'resource',
array(
'required' => true,
'label' => t('Resource'),
'helptext' => t('The resource to use'),
'multiOptions' => $this->getResourcesByType(
false === isset($formData['type']) || $formData['type'] === 'ido' ? 'db' : $formData['type']
)
)
),
$this->createElement(
'checkbox',
'disabled',
array(
'required' => true,
'label' => t('Disable This Backend')
)
)
);
}
/**
* Return the backend configuration values and its name
*
* The first value is the name and the second one the values as array.
*
* @return array
*/
public function getBackendConfig()
{
$values = $this->getValues();
$name = $values['name'];
if ($values['disabled'] == '0') {
unset($values['disabled']);
}
unset($values['name']);
return array($name, $values);
}
/**
* Populate the form with the given configuration values
*
* @param string $name The name of the backend
* @param array $config The configuration values
*/
public function setBackendConfig($name, array $config)
{
$config['name'] = $name;
$this->populate($config);
}
/**
* Return a list of all resources of the given type ready to be used as content for a select input
*
* @param string $type The type of resources to return
*
* @return array
*/
protected function getResourcesByType($type)
{
$backends = array();
foreach (array_keys(ResourceFactory::getResourceConfigs($type)->toArray()) as $name) {
$backends[$name] = $name;
}
return $backends;
}
}

View File

@ -1,99 +1,70 @@
<?php
use Icinga\Web\Url;
$fileNotReadable = array();
foreach (array('backends', 'instances') as $element) {
if (is_object($this->{$element}) &&
get_class($this->{$element}) === 'Icinga\Exception\NotReadableError') {
$fileNotReadable[$element] = $this->{$element}->getMessage();
} else {
$fileNotReadable[$element] = false;
}
}
?>
<div class="controls">
<?= $this->tabs->render($this); ?>
<?= $tabs; ?>
</div>
<div class="content" data-base-target="_next">
<?php if ($fileNotReadable['backends'] === false): ?>
<h1>Monitoring Backends</h1>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<p>
<a href="<?= Url::fromPath('/monitoring/config/createbackend')->getAbsoluteUrl();?>">
<?= $this->icon('create.png'); ?> Create New Monitoring Backend
</a>
</p>
<table class="action">
<thead>
<th>Monitoring Backend</th>
<th style="width: 5em">Remove</th>
</thead>
<tbody>
<?php foreach ($this->backends as $backendName => $config): ?>
<?php
$removeUrl = Url::fromPath('/monitoring/config/removebackend', array('backend' => $backendName));
$editUrl = Url::fromPath('/monitoring/config/editbackend', array('backend' => $backendName));
?>
<tr>
<td>
<a href="<?= $editUrl; ?>"><?= $this->icon('edit.png'); ?> <?= $this->escape($backendName); ?></a>
<small>(Type: <?= $this->escape($config['type'] === 'ido' ? 'IDO' : ucfirst($config['type'])); ?>)</small>
</td>
<td>
<a href="<?= $removeUrl; ?>"><?= $this->icon('remove.png'); ?></a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p class="fileNotReadable">
<?= $this->escape($fileNotReadable['backends']) ?>
</p>
<?php endif ?>
<?php if ($fileNotReadable['instances'] === false): ?>
<h1>Monitoring Instances</h1>
<p>
<a href="<?= Url::fromPath('/monitoring/config/createinstance')->getAbsoluteUrl();?>">
<?= $this->icon('create.png'); ?> Create New Instance
</a>
</p>
<table class="action">
<thead>
<th>Instance</th>
<th style="width: 5em">Remove</th>
</thead>
<tbody>
<?php foreach ($this->instances as $instanceName => $config): ?>
<?php
$removeUrl = Url::fromPath('/monitoring/config/removeinstance', array('instance' => $instanceName));
$editUrl = Url::fromPath('/monitoring/config/editinstance', array('instance' => $instanceName));
?>
<tr>
<td>
<a href="<?= $editUrl; ?>"><?= $this->icon('edit.png'); ?> <?= $this->escape($instanceName); ?></a>
<small>(Type: <?= isset($config['host']) ? 'Remote' : 'Local'; ?>)</small>
</td>
<td>
<a href="<?= $removeUrl; ?>"><?= $this->icon('remove.png'); ?></a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p class="fileNotReadable">
<?= $this->escape($fileNotReadable['instances']) ?>
</p>
<?php endif ?>
</div>
<h1>Monitoring Backends</h1>
<p>
<a href="<?= $this->href('/monitoring/config/createbackend'); ?>">
<?= $this->icon('create.png'); ?> <?= $this->translate('Create New Monitoring Backend'); ?>
</a>
</p>
<table class="action">
<thead>
<th><?= $this->translate('Monitoring Backend'); ?></th>
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
</thead>
<tbody>
<?php foreach ($this->backendsConfig as $backendName => $config): ?>
<tr>
<td>
<a href="<?= $this->href('/monitoring/config/editbackend', array('backend' => $backendName)); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($backendName); ?>
</a>
<small>(<?= sprintf(
$this->translate('Type: %s'),
$this->escape($config->type === 'ido' ? 'IDO' : ucfirst($config->type))
); ?>)</small>
</td>
<td>
<a href="<?= $this->href('/monitoring/config/removebackend', array('backend' => $backendName)); ?>">
<?= $this->icon('remove.png'); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<h1>Monitoring Instances</h1>
<p>
<a href="<?= $this->href('/monitoring/config/createinstance'); ?>">
<?= $this->icon('create.png'); ?> <?= $this->translate('Create New Instance'); ?>
</a>
</p>
<table class="action">
<thead>
<th><?= $this->translate('Instance'); ?></th>
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
</thead>
<tbody>
<?php foreach ($this->instancesConfig as $instanceName => $config): ?>
<tr>
<td>
<a href="<?= $this->href('/monitoring/config/editinstance', array('instance' => $instanceName)); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($instanceName); ?>
</a>
<small>(<?= sprintf(
$this->translate('Type: %s'),
$config->host !== null ? $this->translate('Remote') : $this->translate('Local')
); ?>)</small>
</td>
<td>
<a href="<?= $this->href('/monitoring/config/removeinstance', array('instance' => $instanceName)); ?>">
<?= $this->icon('remove.png'); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>