From 2cf154310bdacb4d51df9d45df9111efa8ac36af Mon Sep 17 00:00:00 2001 From: Matthias Jentsch Date: Wed, 6 Nov 2013 19:02:30 +0100 Subject: [PATCH] Add controller to handle resource configuration Add the controller, forms and views to handle the resource configuration. refs #4786 --- application/controllers/ConfigController.php | 147 ++++++++++---- .../Config/Authentication/LdapBackendForm.php | 76 +++----- .../forms/Config/Resource/EditBackendForm.php | 182 ++++++++++++++++++ .../views/scripts/config/resource.phtml | 56 ++++++ .../scripts/config/resource/create.phtml | 18 ++ .../scripts/config/resource/modify.phtml | 17 ++ .../scripts/config/resource/remove.phtml | 7 + library/Icinga/Data/ResourceFactory.php | 25 ++- 8 files changed, 434 insertions(+), 94 deletions(-) create mode 100644 application/forms/Config/Resource/EditBackendForm.php create mode 100644 application/views/scripts/config/resource.phtml create mode 100644 application/views/scripts/config/resource/create.phtml create mode 100644 application/views/scripts/config/resource/modify.phtml create mode 100644 application/views/scripts/config/resource/remove.phtml diff --git a/application/controllers/ConfigController.php b/application/controllers/ConfigController.php index 898e39a53..b2e3ea55b 100644 --- a/application/controllers/ConfigController.php +++ b/application/controllers/ConfigController.php @@ -34,6 +34,7 @@ use \Icinga\Web\Url; use \Icinga\Web\Hook\Configuration\ConfigurationTabBuilder; use \Icinga\Application\Icinga; use \Icinga\Application\Config as IcingaConfig; +use \Icinga\Data\ResourceFactory; use \Icinga\Form\Config\GeneralForm; use \Icinga\Form\Config\Authentication\ReorderForm; use \Icinga\Form\Config\Authentication\LdapBackendForm; @@ -47,6 +48,12 @@ use \Icinga\Config\PreservingIniWriter; */ class ConfigController extends BaseConfigController { + /** + * The resource types that are available. + * + * @var array + */ + private $resourceTypes = array('livestatus', 'ido', 'statusdat', 'ldap'); /** * Create tabs for this configuration controller @@ -72,7 +79,13 @@ class ConfigController extends BaseConfigController 'url' => Url::fromPath('/config/authentication') ) ), - + 'resources' => new Tab( + array( + 'name' => 'resource', + 'title' => 'Resources', + 'url' => Url::fromPath('/config/resource') + ) + ), 'logging' => new Tab( array( 'name' => 'logging', @@ -210,40 +223,6 @@ class ConfigController extends BaseConfigController $this->render('authentication'); } - /** - * Action for removing a backend from the authentication list. - * - * Redirects to the overview after removal is finished - */ - public function removeauthenticationbackendAction() - { - $configArray = IcingaConfig::app('authentication', true)->toArray(); - $authBackend = $this->getParam('auth_backend'); - if (!isset($configArray[$authBackend])) { - $this->view->errorMessage = 'Can\'t perform removal: Unknown Authentication Backend Provided'; - $this->authenticationAction(true); - return; - } - - $form = new ConfirmRemovalForm(); - $form->setRequest($this->getRequest()); - $form->setRemoveTarget('auth_backend', $authBackend); - - if ($form->isSubmittedAndValid()) { - unset($configArray[$authBackend]); - if ($this->writeAuthenticationFile($configArray)) { - $this->view->successMessage = 'Authentication Backend "' . $authBackend . '" Removed'; - $this->authenticationAction(true); - } - return; - } - - $this->view->form = $form; - - $this->view->name = $authBackend; - $this->render('authentication/remove'); - } - /** * Action for creating a new authentication backend */ @@ -281,6 +260,7 @@ class ConfigController extends BaseConfigController $this->render('authentication/create'); } + /** * Form for editing backends * @@ -296,11 +276,24 @@ class ConfigController extends BaseConfigController $this->authenticationAction(true); return; } + if (!array_key_exists('resource', $configArray[$authBackend])) { + $this->view->errorMessage = 'Configuration error: Backend "' . $authBackend . '" has no Resource'; + $this->authenticationAction(true); + return; + } - if ($configArray[$authBackend]['backend'] === 'ldap') { - $form = new LdapBackendForm(); - } else { - $form = new DbBackendForm(); + $type = ResourceFactory::getResourceConfig($configArray[$authBackend]['resource'])->type; + switch ($type) { + case 'ldap': + $form = new LdapBackendForm(); + break; + case 'db': + $form = new DbBackendForm(); + break; + default: + $this->view->errorMessage = 'Can\'t edit: backend type "' . $type . '" of given resource not supported.'; + $this->authenticationAction(true); + return; } $form->setBackendName($this->getParam('auth_backend')); @@ -329,6 +322,82 @@ class ConfigController extends BaseConfigController $this->render('authentication/modify'); } + /** + * Action for removing a backend from the authentication list. + * + * Redirects to the overview after removal is finished + */ + public function removeauthenticationbackendAction() + { + $configArray = IcingaConfig::app('authentication', true)->toArray(); + $authBackend = $this->getParam('auth_backend'); + if (!isset($configArray[$authBackend])) { + $this->view->errorMessage = 'Can\'t perform removal: Unknown Authentication Backend Provided'; + $this->authenticationAction(true); + return; + } + if (!array_key_exists('resource', $configArray[$authBackend])) { + $this->view->errorMessage = 'Configuration error: Backend "' . $authBackend . '" has no Resource'; + $this->authenticationAction(true); + return; + } + + $form = new ConfirmRemovalForm(); + $form->setRequest($this->getRequest()); + $form->setRemoveTarget('auth_backend', $authBackend); + + if ($form->isSubmittedAndValid()) { + unset($configArray[$authBackend]); + if ($this->writeAuthenticationFile($configArray)) { + $this->view->successMessage = 'Authentication Backend "' . $authBackend . '" Removed'; + $this->authenticationAction(true); + } + return; + } + + $this->view->form = $form; + + $this->view->name = $authBackend; + $this->render('authentication/remove'); + } + + public function resourceAction($showOnly = false) + { + $this->view->resources = ResourceFactory::getResourceConfigs()->toArray(); + $this->view->createActions = array(); + $this->render('resource'); + } + + public function createresourceAction() + { + $this->view->resourceTypes = $this->resourceTypes; + $this->render('resource/create'); + } + + public function editresourceAction() + { + $resources = ResourceFactory::getResourceConfigs()->toArray(); + $name = $resources[$this->getParam('resource')]; + if (!isset($resources[$name])) { + $this->view->errorMessage = 'Can\'t edit: Unknown Resource Provided'; + $this->resourceAction(true); + return; + } + $this->render('resource/modify'); + } + + public function removeresourceAction() + { + $resources = ResourceFactory::getResourceConfigs()->toArray(); + $name = $resources[$this->getParam('resource')]; + if (!isset($resources[$name])) { + $this->view->errorMessage = 'Can\'t remove: Unknown Resource Provided'; + $this->resourceAction(true); + return; + } + $this->render('resource/remove'); + } + /** * Write changes to an authentication file * diff --git a/application/forms/Config/Authentication/LdapBackendForm.php b/application/forms/Config/Authentication/LdapBackendForm.php index 7dfe68539..5a48b9d90 100644 --- a/application/forms/Config/Authentication/LdapBackendForm.php +++ b/application/forms/Config/Authentication/LdapBackendForm.php @@ -30,6 +30,7 @@ namespace Icinga\Form\Config\Authentication; use \Exception; +use Icinga\Data\ResourceFactory; use \Zend_Config; use \Icinga\Web\Form; use \Icinga\Authentication\Backend\LdapUserBackend; @@ -64,48 +65,15 @@ class LdapBackendForm extends BaseBackendForm ); $this->addElement( - 'text', - 'backend_' . $name . '_hostname', + 'select', + 'backend_' . $name . '_resource', array( - 'label' => 'LDAP Server Host', + 'label' => 'Database Connection', + 'required' => true, 'allowEmpty' => false, - 'value' => $backend->get('hostname', 'localhost'), - 'helptext' => 'The hostname or address of the LDAP server to use for authentication', - 'required' => true - ) - ); - - $this->addElement( - 'text', - 'backend_' . $name . '_root_dn', - array( - 'label' => 'LDAP Root DN', - 'value' => $backend->get('root_dn', 'ou=people,dc=icinga,dc=org'), - 'helptext' => 'The path where users can be found on the ldap server', - 'required' => true - ) - ); - - $this->addElement( - 'text', - 'backend_' . $name . '_bind_dn', - array( - 'label' => 'LDAP Bind DN', - 'value' => $backend->get('bind_dn', 'cn=admin,cn=config'), - 'helptext' => 'The user dn to use for querying the ldap server', - 'required' => true - ) - ); - - $this->addElement( - 'password', - 'backend_' . $name . '_bind_pw', - array( - 'label' => 'LDAP Bind Password', - 'renderPassword' => true, - 'value' => $backend->get('bind_pw', 'admin'), - 'helptext' => 'The password to use for querying the ldap server', - 'required' => true + 'helptext' => 'The database connection to use for authenticating with this provider', + 'value' => $this->getBackend()->get('resource'), + 'multiOptions' => $this->getLdapResources() ) ); @@ -158,14 +126,16 @@ class LdapBackendForm extends BaseBackendForm $section = $this->getValue($prefix . 'name'); $cfg = array( - 'backend' => 'ldap', - 'target' => 'user', + 'target' => 'user', + 'resource' => $this->getValue($prefix . 'resource'), + 'user_class' => $this->getValue($prefix . 'user_class'), + 'user_name_attribute' => $this->getValue($prefix . 'user_name_attribute') + /* 'hostname' => $this->getValue($prefix . 'hostname'), 'root_dn' => $this->getValue($prefix . 'root_dn'), 'bind_dn' => $this->getValue($prefix . 'bind_dn'), 'bind_pw' => $this->getValue($prefix . 'bind_pw'), - 'user_class' => $this->getValue($prefix . 'user_class'), - 'user_name_attribute' => $this->getValue($prefix . 'user_name_attribute') + */ ); return array( $section => $cfg @@ -184,21 +154,25 @@ class LdapBackendForm extends BaseBackendForm $cfg = $this->getConfig(); $backendName = 'backend_' . $this->filterName($this->getBackendName()) . '_name'; $backendConfig = new Zend_Config($cfg[$this->getValue($backendName)]); - $testConn = new LdapUserBackend( - new LdapConnection($backendConfig), $backendConfig - ); - + $testConn = new LdapUserBackend($backendConfig); if ($testConn->getUserCount() === 0) { throw new Exception('No Users Found On Directory Server'); } } catch (Exception $exc) { - $this->addErrorMessage( - 'Connection Validation Failed:'. - $exc->getMessage() + 'Connection Validation Failed:' . $exc->getMessage() ); return false; } return true; } + + private function getLdapResources() + { + $res = ResourceFactory::getResourceConfigs('ldap')->toArray(); + foreach ($res as $key => $value) { + $res[$key] = $key; + } + return $res; + } } diff --git a/application/forms/Config/Resource/EditBackendForm.php b/application/forms/Config/Resource/EditBackendForm.php new file mode 100644 index 000000000..7765434e1 --- /dev/null +++ b/application/forms/Config/Resource/EditBackendForm.php @@ -0,0 +1,182 @@ + + * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 + * @author Icinga Development Team + * + */ +// {{{ICINGA_LICENSE_HEADER}}} + +namespace Icinga\Module\Monitoring\Form\Config\Backend; + +use \Zend_Config; +use \Icinga\Web\Form; +use \Icinga\Application\Icinga; +use Icinga\Data\ResourceFactory; + +/** + * Form for modifying a monitoring backend + */ +class EditResourceForm extends Form +{ + /** + * The currently edited resource. + * + * @var Zend_Config + */ + private $resource; + + private $name; + + private function addDbForm() + { + + } + + private function addStatusdatForm() + { + $this->addElement( + 'text', + 'backend_statusdat_statusfile', + array ( + 'label' => 'Status.dat File', + 'value' => $this->backend->status_file, + 'required' => true, + 'helptext' => 'Location of your icinga status.dat file' + ) + ); + $this->addElement( + 'text', + 'backend_statusdat_objectfile', + array ( + 'label' => 'Objects.cache File', + 'value' => $this->backend->status_file, + 'required' => true, + 'helptext' => 'Location of your icinga objects.cache file' + ) + ); + } + + private function addLivestatusForm() + { + $this->addElement( + 'text', + 'backend_livestatus_socket', + array( + 'label' => 'Livestatus Socket Location', + 'required' => true, + 'helptext' => 'The path to your livestatus socket used for querying monitoring data', + 'value' => $this->backend->socket, + ) + ); + } + + private function addLdapForm() + { + $this->addElement( + 'text', + 'resource_' . $this->name . '_hostname', + array( + 'label' => 'LDAP Server Host', + 'allowEmpty' => false, + 'value' => $this->resource->get('hostname', 'localhost'), + 'helptext' => 'The hostname or address of the LDAP server to use for authentication', + 'required' => true + ) + ); + + $this->addElement( + 'text', + 'resource_' . $this->name . '_root_dn', + array( + 'label' => 'LDAP Root DN', + 'value' => $this->resource->get('root_dn', 'ou=people,dc=icinga,dc=org'), + 'helptext' => 'The path where users can be found on the ldap server', + 'required' => true + ) + ); + + $this->addElement( + 'text', + 'resource_' . $this->name . '_bind_dn', + array( + 'label' => 'LDAP Bind DN', + 'value' => $this->resource->get('bind_dn', 'cn=admin,cn=config'), + 'helptext' => 'The user dn to use for querying the ldap server', + 'required' => true + ) + ); + + $this->addElement( + 'password', + 'resource_' . $this->name . '_bind_pw', + array( + 'label' => 'LDAP Bind Password', + 'renderPassword' => true, + 'value' => $this->resource->get('bind_pw', 'admin'), + 'helptext' => 'The password to use for querying the ldap server', + 'required' => true + ) + ); + } + + /** + * Add a select box for choosing the type to use for this backend + */ + private function addTypeSelectionBox() + { + $this->addElement( + 'select', + 'resource_type', + array( + 'label' => 'Resource Type', + 'value' => $this->resource->type, + 'required' => true, + 'helptext' => 'Choose the type of resource you want to create.', + 'multiOptions' => array( + 'db' => 'SQL Database', + 'ldap' => 'Ldap', + 'statusdat' => 'Status.dat', + 'livestatus' => 'Livestatus' + ) + ) + ); + $this->enableAutoSubmit(array('resource_type')); + } + + public function create() + { + $this->addTypeSelectionBox(); + switch ($this->getRequest()->getParam('resource_type', $this->resource->type)) { + case 'db': + break; + case 'statusdat': + break; + case 'livestatus': + break; + case 'ldap': + break; + } + $this->setSubmitLabel('{{SAVE_ICON}} Save Changes'); + } +} diff --git a/application/views/scripts/config/resource.phtml b/application/views/scripts/config/resource.phtml new file mode 100644 index 000000000..6bb38727d --- /dev/null +++ b/application/views/scripts/config/resource.phtml @@ -0,0 +1,56 @@ +href('/config/createresource'); +?> + +tabs->render($this); ?> + +errorMessage): ?> +
+ + escape($this->errorMessage); ?> +
+ + + +successMessage): ?> +
+ + escape($this->successMessage); ?> +
+ + +
+
+ Create Resource +
+ +
+ +resources as $name => $resource): ?> +
+ +
+ Resource: escape($name); ?> +
+
+
+ + + Edit This Resource + +
+ + resources) > 1): ?> + + Remove This Resource + +
+ + +
+ +
+ \ No newline at end of file diff --git a/application/views/scripts/config/resource/create.phtml b/application/views/scripts/config/resource/create.phtml new file mode 100644 index 000000000..ee7d9b610 --- /dev/null +++ b/application/views/scripts/config/resource/create.phtml @@ -0,0 +1,18 @@ +tabs->render($this); ?> + +

+ + Create New Resource +

+ +errorMessage): ?> +
+ escape($this->errorMessage); ?> +
+ + +

+ Create a new backend for authenticating your users. This backend will be added at the end of your authentication order. +

+ +form ?> \ No newline at end of file diff --git a/application/views/scripts/config/resource/modify.phtml b/application/views/scripts/config/resource/modify.phtml new file mode 100644 index 000000000..481e4349b --- /dev/null +++ b/application/views/scripts/config/resource/modify.phtml @@ -0,0 +1,17 @@ +tabs->render($this); ?> + +

+ + Edit Resource "escape($this->name); ?>" +

+ +errorMessage || $this->form->getErrorMessages()): ?> +
+ escape($this->errorMessage); ?> + form->getErrorMessages() as $error): ?> + escape($error); ?>
+ +
+ + +form ?> \ No newline at end of file diff --git a/application/views/scripts/config/resource/remove.phtml b/application/views/scripts/config/resource/remove.phtml new file mode 100644 index 000000000..4ccaea397 --- /dev/null +++ b/application/views/scripts/config/resource/remove.phtml @@ -0,0 +1,7 @@ +tabs->render($this); ?> + +

+ + Remove Resource "escape($this->name); ?>" +

+form ?> \ No newline at end of file diff --git a/library/Icinga/Data/ResourceFactory.php b/library/Icinga/Data/ResourceFactory.php index ac524b769..7746e4f6e 100644 --- a/library/Icinga/Data/ResourceFactory.php +++ b/library/Icinga/Data/ResourceFactory.php @@ -68,14 +68,26 @@ class ResourceFactory implements ConfigAwareFactory } /** - * Return the configuration of all existing resources. + * Return the configuration of all existing resources, or get all resources of a given type. * - * @return Zend_Config The configuration containing all resources + * @param String|null $type Fetch only resources that have the given type. + * + * @return Zend_Config The configuration containing all resources */ - public static function getResourceConfigs() + public static function getResourceConfigs($type = null) { self::assertResourcesExist(); - return self::$resources; + if (!isset($type)) { + return self::$resources; + } else { + $resources = array(); + foreach (self::$resources as $name => $resource) { + if (strtolower($resource->type) === $type) { + $resources[$name] = $resource; + } + } + return new Zend_Config($resources); + } } /** @@ -124,4 +136,9 @@ class ResourceFactory implements ConfigAwareFactory } return $resource; } + + public static function getBackendType($resource) + { + + } }