Merge branch 'bugfix/commands-6593'

fixes #6593
fixes #6961
fixes #4588
resolves #6666
This commit is contained in:
Eric Lippmann 2014-09-23 23:03:06 -07:00
commit 0ac7574a8f
234 changed files with 11105 additions and 11690 deletions

View File

@ -14,7 +14,6 @@ use Icinga\Exception\AuthenticationException;
use Icinga\Exception\NotReadableError;
use Icinga\Exception\ConfigurationError;
use Icinga\User;
use Icinga\Web\Session;
use Icinga\Web\Url;
/**
@ -36,7 +35,6 @@ class AuthenticationController extends ActionController
{
$auth = $this->Auth();
$this->view->form = $form = new LoginForm();
$form->setRequest($this->_request);
$this->view->title = $this->translate('Icingaweb Login');
try {
@ -55,27 +53,17 @@ class AuthenticationController extends ActionController
$config = Config::app('authentication');
} catch (NotReadableError $e) {
throw new ConfigurationError(
$this->translate(
'Could not read your authentiction.ini, no authentication methods are available.'
)
$this->translate('Could not read your authentiction.ini, no authentication methods are available.'),
0,
$e
);
}
$chain = new AuthChain($config);
if ($this->getRequest()->isGet()) {
$user = new User('');
foreach ($chain as $backend) {
if ($backend instanceof AutoLoginBackend) {
$authenticated = $backend->authenticate($user);
if ($authenticated === true) {
$auth->setAuthenticated($user);
$this->rerenderLayout()->redirectNow($redirectUrl);
}
}
}
} elseif ($form->isSubmittedAndValid()) {
$user = new User($form->getValue('username'));
$password = $form->getValue('password');
$request = $this->getRequest();
if ($request->isPost() && $this->view->form->isValid($request->getPost())) {
$user = new User($this->view->form->getValue('username'));
$password = $this->view->form->getValue('password');
$backendsTried = 0;
$backendsWithError = 0;
@ -121,14 +109,25 @@ class AuthenticationController extends ActionController
);
}
if ($backendsWithError) {
$form->addNote(
$this->view->form->getElement('username')->addError(
$this->translate(
'Please note that not all authentication methods where available.'
. ' Check the system log or Icinga Web 2 log for more information.'
)
);
}
$form->getElement('password')->addError($this->translate('Incorrect username or password'));
$this->view->form->getElement('password')->addError($this->translate('Incorrect username or password'));
} elseif ($request->isGet()) {
$user = new User('');
foreach ($chain as $backend) {
if ($backend instanceof AutoLoginBackend) {
$authenticated = $backend->authenticate($user);
if ($authenticated === true) {
$auth->setAuthenticated($user);
$this->rerenderLayout()->redirectNow($redirectUrl);
}
}
}
}
} catch (Exception $e) {
$this->view->errorInfo = $e->getMessage();

View File

@ -2,38 +2,25 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Web\Controller\BaseConfigController;
use Icinga\Web\Widget\Tab;
use Icinga\Web\Widget\AlertMessageBox;
use Icinga\Web\Controller\ActionController;
use Icinga\Web\Notification;
use Icinga\Application\Modules\Module;
use Icinga\Web\Url;
use Icinga\Web\Widget;
use Icinga\Application\Icinga;
use Icinga\Application\Config as IcingaConfig;
use Icinga\Form\Config\GeneralConfigForm;
use Icinga\Form\Config\AuthenticationBackendReorderForm;
use Icinga\Form\Config\AuthenticationBackendConfigForm;
use Icinga\Form\Config\ResourceConfigForm;
use Icinga\Form\ConfirmRemovalForm;
use Icinga\Data\ResourceFactory;
use Icinga\Form\Config\GeneralForm;
use Icinga\Form\Config\Authentication\ReorderForm;
use Icinga\Form\Config\Authentication\LdapBackendForm;
use Icinga\Form\Config\Authentication\DbBackendForm;
use Icinga\Form\Config\ResourceForm;
use Icinga\Form\Config\LoggingForm;
use Icinga\Form\Config\ConfirmRemovalForm;
use Icinga\Config\PreservingIniWriter;
/**
* Application wide controller for application preferences
*/
class ConfigController extends BaseConfigController
class ConfigController extends ActionController
{
/**
* The resource types that are available.
*
* @var array
*/
private $resourceTypes = array('livestatus', 'ido', 'statusdat', 'ldap');
public function init()
{
$this->view->tabs = Widget::create('tabs')->add('index', array(
@ -45,9 +32,6 @@ class ConfigController extends BaseConfigController
))->add('resources', array(
'title' => 'Resources',
'url' => 'config/resource'
))->add('logging', array(
'title' => 'Logging',
'url' => 'config/logging'
));
}
@ -61,42 +45,12 @@ class ConfigController extends BaseConfigController
*/
public function indexAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$form = new GeneralConfigForm();
$form->setIniConfig(IcingaConfig::app());
$form->handleRequest();
$this->view->form = $form;
$this->view->tabs->activate('index');
$form = new GeneralForm();
$form->setConfiguration(IcingaConfig::app());
$form->setRequest($this->_request);
if ($form->isSubmittedAndValid()) {
if (!$this->writeConfigFile($form->getConfig(), 'config')) {
return;
}
Notification::success('New configuration has successfully been stored');
$form->setConfiguration(IcingaConfig::app(), true);
$this->redirectNow('config/index');
}
$this->view->form = $form;
}
/**
* Form for modifying the logging configuration
*/
public function loggingAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$this->view->tabs->activate('logging');
$form = new LoggingForm();
$form->setConfiguration(IcingaConfig::app());
$form->setRequest($this->_request);
if ($form->isSubmittedAndValid()) {
if (!$this->writeConfigFile($form->getConfig(), 'config')) {
return;
}
Notification::success('New configuration has sucessfully been stored');
$form->setConfiguration(IcingaConfig::app(), true);
$this->redirectNow('config/logging');
}
$this->view->form = $form;
}
/**
@ -172,40 +126,17 @@ class ConfigController extends BaseConfigController
}
/**
* Action for creating a new authentication backend
* Action for listing and reordering authentication backends
*/
public function authenticationAction()
{
$config = IcingaConfig::app('authentication', true);
$form = new AuthenticationBackendReorderForm();
$form->setIniConfig(IcingaConfig::app('authentication'));
$form->handleRequest();
$this->view->form = $form;
$this->view->tabs->activate('authentication');
$order = array_keys($config->toArray());
$this->view->messageBox = new AlertMessageBox(true);
$backends = array();
foreach ($order as $backend) {
$form = new ReorderForm();
$form->setName('form_reorder_backend_' . $backend);
$form->setBackendName($backend);
$form->setCurrentOrder($order);
$form->setRequest($this->_request);
if ($form->isSubmittedAndValid()) {
if ($this->writeAuthenticationFile($form->getReorderedConfig($config))) {
Notification::success('Authentication Order Updated');
$this->redirectNow('config/authentication');
}
return;
}
$backends[] = (object) array(
'name' => $backend,
'reorderForm' => $form
);
}
$this->view->backends = $backends;
$this->render('authentication/reorder');
}
/**
@ -213,316 +144,151 @@ class ConfigController extends BaseConfigController
*/
public function createauthenticationbackendAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$form = new AuthenticationBackendConfigForm();
$form->setIniConfig(IcingaConfig::app('authentication'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('config/authentication');
$form->handleRequest();
if ($this->getRequest()->getParam('type') === 'ldap') {
$form = new LdapBackendForm();
} else {
$form = new DbBackendForm();
}
if ($this->getParam('auth_backend')) {
$form->setBackendName($this->getParam('auth_backend'));
}
$form->setRequest($this->getRequest());
if ($form->isSubmittedAndValid()) {
$backendCfg = IcingaConfig::app('authentication')->toArray();
foreach ($backendCfg as $backendName => $settings) {
unset($backendCfg[$backendName]['name']);
}
foreach ($form->getConfig() as $backendName => $settings) {
unset($settings->{'name'});
if (isset($backendCfg[$backendName])) {
$this->addErrorMessage('Backend name already exists');
$this->view->form = $form;
$this->render('authentication/create');
return;
}
$backendCfg[$backendName] = $settings;
}
if ($this->writeAuthenticationFile($backendCfg)) {
// redirect to overview with success message
Notification::success('Backend Modification Written.');
$this->redirectNow("config/authentication");
}
return;
}
$this->view->messageBox->addForm($form);
$this->view->form = $form;
$this->view->tabs->activate('authentication');
$this->render('authentication/create');
}
/**
* Form for editing backends
*
* Mostly the same like the createAuthenticationBackendAction, but with additional checks for backend existence
* and form population
* Action for editing authentication backends
*/
public function editauthenticationbackendAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$form = new AuthenticationBackendConfigForm();
$form->setIniConfig(IcingaConfig::app('authentication'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('config/authentication');
$form->handleRequest();
$configArray = IcingaConfig::app('authentication', true)->toArray();
$authBackend = $this->getParam('auth_backend');
if (!isset($configArray[$authBackend])) {
$this->addErrorMessage('Can\'t edit: Unknown Authentication Backend Provided');
$this->configurationerrorAction();
return;
}
if (!array_key_exists('resource', $configArray[$authBackend])) {
$this->addErrorMessage('Configuration error: Backend "' . $authBackend . '" has no Resource');
$this->configurationerrorAction();
return;
}
$type = ResourceFactory::getResourceConfig($configArray[$authBackend]['resource'])->type;
switch ($type) {
case 'ldap':
$form = new LdapBackendForm();
break;
case 'db':
$form = new DbBackendForm();
break;
default:
$this->addErrorMessage('Can\'t edit: backend type "' . $type . '" of given resource not supported.');
$this->configurationerrorAction();
return;
}
$form->setBackendName($this->getParam('auth_backend'));
$form->setBackend(IcingaConfig::app('authentication', true)->$authBackend);
$form->setRequest($this->getRequest());
if ($form->isSubmittedAndValid()) {
$backendCfg = IcingaConfig::app('authentication')->toArray();
foreach ($form->getConfig() as $backendName => $settings) {
$backendCfg[$backendName] = $settings;
// Remove the old section if the backend is renamed
if ($backendName != $authBackend) {
unset($backendCfg[$authBackend]);
}
unset($settings['name']);
}
if ($this->writeAuthenticationFile($backendCfg)) {
// redirect to overview with success message
Notification::success('Backend "' . $authBackend . '" created');
$this->redirectNow("config/authentication");
}
return;
}
$this->view->messageBox->addForm($form);
$this->view->name = $authBackend;
$this->view->form = $form;
$this->view->tabs->activate('authentication');
$this->render('authentication/modify');
}
/**
* Action for removing a backend from the authentication list.
*
* Redirects to the overview after removal is finished
* Action for removing a backend from the authentication list
*/
public function removeauthenticationbackendAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) {
$configForm = new AuthenticationBackendConfigForm();
$configForm->setIniConfig(IcingaConfig::app('authentication'));
$authBackend = $request->getQuery('auth_backend');
$configArray = IcingaConfig::app('authentication', true)->toArray();
$authBackend = $this->getParam('auth_backend');
if (!isset($configArray[$authBackend])) {
Notification::error('Can\'t perform removal: Unknown Authentication Backend Provided');
$this->render('authentication/remove');
return;
}
try {
$configForm->remove($authBackend);
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
$form = new ConfirmRemovalForm();
$form->setRequest($this->getRequest());
$form->setRemoveTarget('auth_backend', $authBackend);
if ($form->isSubmittedAndValid()) {
unset($configArray[$authBackend]);
if ($this->writeAuthenticationFile($configArray)) {
Notification::success('Authentication Backend "' . $authBackend . '" Removed');
$this->redirectNow("config/authentication");
if ($configForm->save()) {
Notification::success(sprintf(
t('Authentication backend "%s" has been successfully removed'),
$authBackend
));
} else {
return false;
}
}
return;
}
));
$form->setRedirectUrl('config/authentication');
$form->handleRequest();
$this->view->form = $form;
$this->view->name = $authBackend;
$this->view->tabs->activate('authentication');
$this->render('authentication/remove');
}
public function resourceAction($showOnly = false)
/**
* Display all available resources and a link to create a new one and to remove existing ones
*/
public function resourceAction()
{
$this->view->tabs->activate('resources');
$this->view->messageBox = new AlertMessageBox(true);
$this->view->resources = IcingaConfig::app('resources', true)->toArray();
$this->render('resource');
$this->view->tabs->activate('resources');
}
/**
* Display a form to create a new resource
*/
public function createresourceAction()
{
$this->view->resourceTypes = $this->resourceTypes;
$resources = IcingaConfig::app('resources', true);
$form = new ResourceForm();
$form->setRequest($this->_request);
if ($form->isSubmittedAndValid()) {
$name = $form->getName();
if (isset($resources->{$name})) {
$this->addErrorMessage('Resource name "' . $name .'" already in use.');
} else {
$resources->{$name} = $form->getConfig();
if ($this->writeConfigFile($resources, 'resources')) {
$this->addSuccessMessage('Resource "' . $name . '" created.');
$this->redirectNow("config/resource");
}
}
}
$form = new ResourceConfigForm();
$form->setIniConfig(IcingaConfig::app('resources'));
$form->setRedirectUrl('config/resource');
$form->handleRequest();
$this->view->messageBox = new AlertMessageBox(true);
$this->view->messageBox->addForm($form);
$this->view->form = $form;
$this->render('resource/create');
}
/**
* Display a form to edit a existing resource
*/
public function editresourceAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$form = new ResourceConfigForm();
$form->setIniConfig(IcingaConfig::app('resources'));
$form->setRedirectUrl('config/resource');
$form->handleRequest();
$resources = ResourceFactory::getResourceConfigs();
$name = $this->getParam('resource');
if ($resources->get($name) === null) {
$this->addErrorMessage('Can\'t edit: Unknown Resource Provided');
$this->render('resource/modify');
return;
}
$form = new ResourceForm();
if ($this->_request->isPost() === false) {
$form->setOldName($name);
$form->setName($name);
}
$form->setRequest($this->_request);
$form->setResource($resources->get($name));
if ($form->isSubmittedAndValid()) {
$oldName = $form->getOldName();
$name = $form->getName();
if ($oldName !== $name) {
unset($resources->{$oldName});
}
$resources->{$name} = $form->getConfig();
if ($this->writeConfigFile($resources, 'resources')) {
$this->addSuccessMessage('Resource "' . $name . '" edited.');
$this->redirectNow("config/resource");
}
return;
}
$this->view->messageBox->addForm($form);
$this->view->form = $form;
$this->view->name = $name;
$this->render('resource/modify');
}
/**
* Display a confirmation form to remove a resource
*/
public function removeresourceAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) {
$configForm = new ResourceConfigForm();
$configForm->setIniConfig(IcingaConfig::app('resources'));
$resource = $request->getQuery('resource');
$resources = ResourceFactory::getResourceConfigs()->toArray();
$name = $this->getParam('resource');
if (!isset($resources[$name])) {
$this->addSuccessMessage('Can\'t remove: Unknown resource provided');
$this->render('resource/remove');
return;
}
try {
$configForm->remove($resource);
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
$form = new ConfirmRemovalForm();
$form->setRequest($this->getRequest());
$form->setRemoveTarget('resource', $name);
if ($configForm->save()) {
Notification::success(sprintf(t('Resource "%s" has been successfully removed'), $resource));
} else {
return false;
}
}
));
$form->setRedirectUrl('config/resource');
$form->handleRequest();
// Check if selected resource is currently used for authentication
$authConfig = IcingaConfig::app('authentication', true)->toArray();
$resource = $this->getRequest()->getQuery('resource');
$authConfig = IcingaConfig::app('authentication')->toArray();
foreach ($authConfig as $backendName => $config) {
if (array_key_exists('resource', $config) && $config['resource'] === $name) {
$this->addErrorMessage(
'Warning: The resource "' . $name . '" is currently used for user authentication by "' . $backendName . '". ' .
' Deleting it could eventally make login impossible.'
);
}
}
if ($form->isSubmittedAndValid()) {
unset($resources[$name]);
if ($this->writeConfigFile($resources, 'resources')) {
$this->addSuccessMessage('Resource "' . $name . '" removed.');
$this->redirectNow('config/resource');
if (array_key_exists('resource', $config) && $config['resource'] === $resource) {
$form->addError(sprintf(
$this->translate(
'The resource "%s" is currently in use by the authentication backend "%s". ' .
'Removing the resource can result in noone being able to log in any longer.'
),
$resource,
$backendName
));
}
return;
}
$this->view->name = $name;
$this->view->form = $form;
$this->render('resource/remove');
}
/**
* Redirect target only for error-states
*
* When an error is opened in the side-pane, redirecting this request to the index or the overview will look
* weird. This action returns a clear page containing only an AlertMessageBox.
*/
public function configurationerrorAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$this->render('error/error', null, true);
}
/**
* Write changes to an authentication file
*
* @param array $config The configuration changes
*
* @return bool True when persisting succeeded, otherwise false
*
* @see writeConfigFile()
*/
private function writeAuthenticationFile($config) {
return $this->writeConfigFile($config, 'authentication');
}
/**
* Write changes to a configuration file $file, using the supplied writer or PreservingIniWriter if none is set
*
* @param array|Zend_Config $config The configuration to write
* @param string $file The filename to write to (without .ini)
* @param Zend_Config_Writer $writer An optional writer to use for persisting changes
*
* @return bool True when persisting succeeded, otherwise false
*/
private function writeConfigFile($config, $file, $writer = null)
{
if (is_array($config)) {
$config = new Zend_Config($config);
}
if ($writer === null) {
$writer = new PreservingIniWriter(
array(
'config' => $config,
'filename' => IcingaConfig::app($file)->getConfigFile()
)
);
}
try {
$writer->write();
return true;
} catch (Exception $exc) {
$this->view->exceptionMessage = $exc->getMessage();
$this->view->iniConfigurationString = $writer->render();
$this->view->file = $file;
$this->render('show-configuration');
return false;
}
}
}

View File

@ -82,25 +82,29 @@ class DashboardController extends ActionController
)->activate('addurl');
$form = new AddUrlForm();
$form->setRequest($this->getRequest());
$form->setAction(Url::fromRequest()->setParams(array())->getAbsoluteUrl());
$this->view->form = $form;
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost()) && $form->isSubmitted()) {
$dashboard = $this->getDashboard();
$dashboard->setComponentUrl(
$form->getValue('pane'),
$form->getValue('component'),
ltrim($form->getValue('url'), '/')
);
if ($form->isSubmittedAndValid()) {
$dashboard = $this->getDashboard();
$dashboard->setComponentUrl(
$form->getValue('pane'),
$form->getValue('component'),
ltrim($form->getValue('url'), '/')
);
$configFile = IcingaConfig::app('dashboard/dashboard')->getConfigFile();
if ($this->writeConfiguration(new Zend_Config($dashboard->toArray()), $configFile)) {
$this->redirectNow(Url::fromPath('dashboard', array('pane' => $form->getValue('pane'))));
} else {
$this->render('show-configuration');
$configFile = IcingaConfig::app('dashboard/dashboard')->getConfigFile();
if ($this->writeConfiguration(new Zend_Config($dashboard->toArray()), $configFile)) {
$this->redirectNow(Url::fromPath('dashboard', array('pane' => $form->getValue('pane'))));
} else {
$this->render('showConfiguration');
return;
}
}
} else {
$form->create()->setDefault('url', htmlspecialchars_decode($request->getParam('url', '')));
}
$this->view->form = $form;
}
/**
@ -160,9 +164,9 @@ class DashboardController extends ActionController
$writer->write();
} catch (Exception $e) {
Logger::error(new ConfiguationError("Cannot write dashboard to $target", 0, $e));
$this->view->iniConfigurationString = $writer->render();
$this->view->exceptionMessage = $e->getMessage();
$this->view->file = $target;
$this->view->configString = $writer->render();
$this->view->errorMessage = $e->getMessage();
$this->view->filePath = $target;
return false;
}

View File

@ -3,11 +3,12 @@
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Web\Controller\BasePreferenceController;
use Icinga\Web\Widget\Tab;
use Icinga\Application\Config as IcingaConfig;
use Icinga\Web\Url;
use Icinga\Form\Preference\GeneralForm;
use Icinga\Web\Notification;
use Icinga\Web\Widget\Tab;
use Icinga\Application\Config;
use Icinga\Form\PreferenceForm;
use Icinga\Exception\ConfigurationError;
use Icinga\User\Preferences\PreferencesStore;
/**
* Application wide preference controller for user preferences
@ -34,27 +35,22 @@ class PreferenceController extends BasePreferenceController
}
/**
* General settings for date and time
* Show form to adjust user preferences
*/
public function indexAction()
{
$form = new GeneralForm();
$this->getTabs()->activate('general');
$form->setConfiguration(IcingaConfig::app())
->setRequest($this->getRequest());
if ($form->isSubmittedAndValid()) {
try {
$this->savePreferences($form->getPreferences());
Notification::success(t('Preferences updated successfully'));
// Recreate form to show new values
// TODO(el): It must sufficient to call $form->populate(...)
$form = new GeneralForm();
$form->setConfiguration(IcingaConfig::app());
$form->setRequest($this->getRequest());
} catch (Exception $e) {
Notification::error(sprintf(t('Failed to persist preferences. (%s)'), $e->getMessage()));
}
$storeConfig = Config::app()->preferences;
if ($storeConfig === null) {
throw new ConfigurationError(t('You need to configure how to store preferences first.'));
}
$user = $this->getRequest()->getUser();
$form = new PreferenceForm();
$form->setPreferences($user->getPreferences());
$form->setStore(PreferencesStore::create($storeConfig, $user));
$form->handleRequest();
$this->view->form = $form;
$this->getTabs()->activate('general');
}
}

View File

@ -13,36 +13,45 @@ use Icinga\Web\Url;
class LoginForm extends Form
{
/**
* Interface how the form should be created
* Initialize this login form
*/
protected function create()
public function init()
{
$url = Url::fromRequest()->without('renderLayout');
$this->setName('form_login');
$this->addElement('text', 'username', array(
'label' => t('Username'),
'placeholder' => t('Please enter your username...'),
'required' => true,
));
$redir = $this->addElement('hidden', 'redirect');
$redirectUrl = $url->shift('redirect');
if ($redirectUrl) {
$this->setDefault('redirect', $redirectUrl);
}
$this->setSubmitLabel(t('Login'));
}
$this->addElement('password', 'password', array(
'label' => t('Password'),
'placeholder' => t('...and your password'),
'required' => true
));
// TODO: We need a place to intercept filled forms before rendering
if ($this->getRequest()->getPost('username') !== null) {
$this->getElement('password')->setAttrib('class', 'autofocus');
} else {
$this->getElement('username')->setAttrib('class', 'autofocus');
}
$this->setAction((string) $url);
$this->setSubmitLabel('Login');
/**
* @see Form::createElements()
*/
public function createElements($formData)
{
$this->addElement(
'text',
'username',
array(
'required' => true,
'label' => t('Username'),
'placeholder' => t('Please enter your username...'),
'class' => false === isset($formData['username']) ? 'autofocus' : ''
)
);
$this->addElement(
'password',
'password',
array(
'required' => true,
'label' => t('Password'),
'placeholder' => t('...and your password'),
'class' => isset($formData['username']) ? 'autofocus' : ''
)
);
$this->addElement(
'hidden',
'redirect',
array(
'value' => Url::fromRequest()->getParam('redirect')
)
);
}
}

View File

@ -0,0 +1,89 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Authentication;
use Zend_Validate_Callback;
use Icinga\Web\Form;
/**
* Form class for adding/modifying autologin authentication backends
*/
class AutologinBackendForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_authbackend_autologin');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Backend Name'),
'description' => t('The name of this authentication backend'),
'validators' => array(
array(
'Regex',
false,
array(
'pattern' => '/^[^\\[\\]:]+$/',
'messages' => array(
'regexNotMatch' => 'The backend name cannot contain \'[\', \']\' or \':\'.'
)
)
)
)
)
);
$this->addElement(
'text',
'strip_username_regexp',
array(
'required' => true,
'label' => t('Backend Domain Pattern'),
'description' => t('The domain pattern of this authentication backend'),
'value' => '/\@[^$]+$/',
'validators' => array(
new Zend_Validate_Callback(function ($value) {
return @preg_match($value, '') !== false;
})
)
)
);
$this->addElement(
'hidden',
'backend',
array(
'required' => true,
'value' => 'autologin'
)
);
return $this;
}
/**
* Validate the configuration by creating a backend and requesting the user count
*
* Returns always true as autologin backends are just "passive" backends. (The webserver authenticates users.)
*
* @param Form $form The form to fetch the configuration values from
*
* @return bool Whether validation succeeded or not
*/
public function isValidAuthenticationBackend(Form $form)
{
return true;
}
}

View File

@ -1,164 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Authentication;
use Zend_Config;
use Zend_Form_Element_Checkbox;
use Icinga\Web\Form;
use Icinga\Data\ResourceFactory;
use Icinga\Web\Form\Decorator\HelpText;
/**
* Base form for authentication backend forms
*/
abstract class BaseBackendForm extends Form
{
/**
* The name of the backend currently displayed in this form
*
* Will be the section in the authentication.ini file
*
* @var string
*/
protected $backendName = '';
/**
* The backend configuration as a Zend_Config object
*
* @var Zend_Config
*/
protected $backend;
/**
* The resources to use instead of the factory provided ones (use for testing)
*
* @var Zend_Config
*/
protected $resources;
/**
* Set the name of the currently displayed backend
*
* @param string $name The name to be stored as the section when persisting
*/
public function setBackendName($name)
{
$this->backendName = $name;
}
/**
* Return the backend name of this form
*
* @return string
*/
public function getBackendName()
{
return $this->backendName;
}
/**
* Return the backend configuration or a empty Zend_Config object if none is given
*
* @return Zend_Config
*/
public function getBackend()
{
return ($this->backend !== null) ? $this->backend : new Zend_Config(array());
}
/**
* Set the backend configuration for initial population
*
* @param Zend_Config $backend The backend to display in this form
*/
public function setBackend(Zend_Config $backend)
{
$this->backend = $backend;
}
/**
* Set an alternative array of resources that should be used instead of the DBFactory resource set
*
* @param array $resources The resources to use for populating the db selection field
*/
public function setResources(array $resources)
{
$this->resources = $resources;
}
/**
* Return content of the resources.ini or previously set resources
*
* @return array
*/
public function getResources()
{
if ($this->resources === null) {
return ResourceFactory::getResourceConfigs()->toArray();
} else {
return $this->resources;
}
}
/**
* Add checkbox at the beginning of the form which allows to skip logic connection validation
*/
protected function addForceCreationCheckbox()
{
$checkbox = new Zend_Form_Element_Checkbox(
array(
'name' => 'backend_force_creation',
'label' => t('Force Changes'),
'helptext' => t('Check this box to enforce changes without connectivity validation'),
'order' => 0
)
);
$checkbox->addDecorator(new HelpText());
$this->addElement($checkbox);
}
/**
* Validate this form with the Zend validation mechanism and perform a logic validation of the connection.
*
* If logic validation fails, the 'backend_force_creation' checkbox is prepended to the form to allow users to
* skip the logic connection validation.
*
* @param array $data The form input to validate
*
* @return bool Whether validation succeeded or not
*/
public function isValid($data)
{
if (!parent::isValid($data)) {
return false;
}
if (isset($data['backend_force_creation']) && $data['backend_force_creation']) {
return true;
}
if (!$this->isValidAuthenticationBackend()) {
$this->addForceCreationCheckbox();
return false;
}
return true;
}
/**
* Return an array containing all sections defined by this form as the key and all settings
* as an key-value sub-array
*
* @return array
*/
abstract public function getConfig();
/**
* Validate the configuration state of this backend with the concrete authentication backend.
*
* An implementation should not throw any exception, but use the add/setErrorMessages method of
* Zend_Form. If the 'backend_force_creation' checkbox is set, this method won't be called.
*
* @return bool Whether validation succeeded or not
*/
abstract public function isValidAuthenticationBackend();
}

View File

@ -5,123 +5,116 @@
namespace Icinga\Form\Config\Authentication;
use Exception;
use Zend_Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Data\ResourceFactory;
use Icinga\Authentication\DbConnection;
use Icinga\Authentication\Backend\DbUserBackend;
/**
* Form class for adding/modifying database authentication backends
*/
class DbBackendForm extends BaseBackendForm
class DbBackendForm extends Form
{
/**
* Return content of the resources.ini or previously set resources
* The database resource names the user can choose from
*
* @return array
* @var array
*/
public function getResources()
protected $resources;
/**
* Initialize this form
*/
public function init()
{
if ($this->resources === null) {
$res = ResourceFactory::getResourceConfigs('db')->toArray();
$this->setName('form_config_authbackend_db');
}
foreach (array_keys($res) as $key) {
$res[$key] = $key;
}
/**
* Set the resource names the user can choose from
*
* @param array $resources The resources to choose from
*
* @return self
*/
public function setResources(array $resources)
{
$this->resources = $resources;
return $this;
}
return $res;
} else {
return $this->resources;
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Backend Name'),
'description' => t('The name of this authentication provider'),
)
);
$this->addElement(
'select',
'resource',
array(
'required' => true,
'label' => t('Database Connection'),
'description' => t('The database connection to use for authenticating with this provider'),
'multiOptions' => false === empty($this->resources)
? array_combine($this->resources, $this->resources)
: array()
)
);
$this->addElement(
'hidden',
'backend',
array(
'required' => true,
'value' => 'db'
)
);
return $this;
}
/**
* Validate that the selected resource is a valid database authentication backend
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
if (false === $this->isValidAuthenticationBackend($this)) {
return false;
}
}
/**
* Create this form and add all required elements
* Validate the configuration by creating a backend and requesting the user count
*
* @see Form::create()
* @param Form $form The form to fetch the configuration values from
*
* @return bool Whether validation succeeded or not
*/
public function create()
public function isValidAuthenticationBackend(Form $form)
{
$this->setName('form_modify_backend');
$name = $this->filterName($this->getBackendName());
$this->addElement(
'text',
'backend_' . $name . '_name',
array(
'required' => true,
'allowEmpty' => false,
'label' => t('Backend Name'),
'helptext' => t('The name of this authentication provider'),
'value' => $this->getBackendName()
)
);
$element = $form->getElement('resource');
$this->addElement(
'select',
'backend_' . $name . '_resource',
array(
'required' => true,
'allowEmpty' => false,
'label' => t('Database Connection'),
'helptext' => t('The database connection to use for authenticating with this provider'),
'value' => $this->getBackend()->get('resource'),
'multiOptions' => $this->getResources()
)
);
$this->addElement(
'button',
'btn_submit',
array(
'type' => 'submit',
'value' => '1',
'escape' => false,
'class' => 'btn btn-cta btn-wide',
'label' => '<i class="icinga-icon-save"></i> Save Backend'
)
);
}
/**
* Return the datatbase authentication backend configuration for this form
*
* @return array
*
* @see BaseBackendForm::getConfig()
*/
public function getConfig()
{
$prefix = 'backend_' . $this->filterName($this->getBackendName()) . '_';
$section = $this->getValue($prefix . 'name');
$cfg = array(
'backend' => 'db',
'resource' => $this->getValue($prefix . 'resource'),
);
return array($section => $cfg);
}
/**
* Validate the current configuration by creating a backend and requesting the user count
*
* @return bool Whether validation succeeded or not
*
* @see BaseBackendForm::isValidAuthenticationBackend
*/
public function isValidAuthenticationBackend()
{
try {
$dbUserBackend = new DbUserBackend(ResourceFactory::create(
$this->getValue('backend_' . $this->filterName($this->getBackendName()) . '_resource')
));
$dbUserBackend = new DbUserBackend(ResourceFactory::create($element->getValue()));
if ($dbUserBackend->count() < 1) {
$this->addErrorMessage(t("No users found under the specified database backend"));
$element->addError(t('No users found under the specified database backend'));
return false;
}
} catch (Exception $e) {
$this->addErrorMessage(sprintf(t('Using the specified backend failed: %s'), $e->getMessage()));
$element->addError(sprintf(t('Using the specified backend failed: %s'), $e->getMessage()));
return false;
}
return true;
}
}

View File

@ -5,166 +5,134 @@
namespace Icinga\Form\Config\Authentication;
use Exception;
use Icinga\Application\Platform;
use Zend_Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Data\ResourceFactory;
use Icinga\Authentication\Backend\LdapUserBackend;
/**
* Form for adding or modifying LDAP authentication backends
* Form class for adding/modifying LDAP authentication backends
*/
class LdapBackendForm extends BaseBackendForm
class LdapBackendForm extends Form
{
/**
* Return content of the resources.ini or previously set resources
* The ldap resource names the user can choose from
*
* @return array
* @var array
*/
public function getResources()
protected $resources;
/**
* Initialize this form
*/
public function init()
{
if ($this->resources === null) {
$res = ResourceFactory::getResourceConfigs('ldap')->toArray();
foreach (array_keys($res) as $key) {
$res[$key] = $key;
}
return $res;
} else {
return $this->resources;
}
$this->setName('form_config_authbackend_ldap');
}
/**
* Create this form and add all required elements
* Set the resource names the user can choose from
*
* @see Form::create()
* @param array $resources The resources to choose from
*
* @return self
*/
public function create()
public function setResources(array $resources)
{
$this->setName('form_modify_backend');
$name = $this->filterName($this->getBackendName());
$backend = $this->getBackend();
$this->resources = $resources;
return $this;
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'backend_' . $name . '_name',
'name',
array(
'required' => true,
'allowEmpty' => false,
'label' => t('Backend Name'),
'helptext' => t('The name of this authentication backend'),
'value' => $this->getBackendName()
'description' => t('The name of this authentication backend')
)
);
$this->addElement(
'select',
'backend_' . $name . '_resource',
'resource',
array(
'required' => true,
'allowEmpty' => false,
'label' => t('LDAP Resource'),
'helptext' => t('The resource to use for authenticating with this provider'),
'value' => $this->getBackend()->get('resource'),
'multiOptions' => $this->getResources()
'description' => t('The resource to use for authenticating with this provider'),
'multiOptions' => false === empty($this->resources)
? array_combine($this->resources, $this->resources)
: array()
)
);
$this->addElement(
'text',
'backend_' . $name . '_user_class',
'user_class',
array(
'required' => true,
'label' => t('LDAP User Object Class'),
'helptext' => t('The object class used for storing users on the ldap server'),
'value' => $backend->get('user_class', 'inetOrgPerson')
'required' => true,
'label' => t('LDAP User Object Class'),
'description' => t('The object class used for storing users on the ldap server'),
'value' => 'inetOrgPerson'
)
);
$this->addElement(
'text',
'backend_' . $name . '_user_name_attribute',
'user_name_attribute',
array(
'required' => true,
'label' => t('LDAP User Name Attribute'),
'description' => t('The attribute name used for storing the user name on the ldap server'),
'value' => 'uid'
)
);
$this->addElement(
'hidden',
'backend',
array(
'required' => true,
'label' => t('LDAP User Name Attribute'),
'helptext' => t('The attribute name used for storing the user name on the ldap server'),
'value' => $backend->get('user_name_attribute', 'uid')
'value' => 'ldap'
)
);
$this->addElement(
'button',
'btn_submit',
array(
'type' => 'submit',
'value' => '1',
'escape' => false,
'class' => 'btn btn-cta btn-wide',
'label' => '<i class="icinga-icon-save"></i> Save Backend'
)
);
return $this;
}
/**
* Return the ldap authentication backend configuration for this form
* Validate that the selected resource is a valid ldap authentication backend
*
* @return array
*
* @see BaseBackendForm::getConfig()
* @see Form::onSuccess()
*/
public function getConfig()
public function onSuccess(Request $request)
{
$prefix = 'backend_' . $this->filterName($this->getBackendName()) . '_';
$section = $this->getValue($prefix . 'name');
$cfg = array(
'backend' => 'ldap',
'resource' => $this->getValue($prefix . 'resource'),
'user_class' => $this->getValue($prefix . 'user_class'),
'user_name_attribute' => $this->getValue($prefix . 'user_name_attribute')
);
return array($section => $cfg);
}
/**
* Validate the current configuration by creating a backend and requesting the user count
*
* @return bool Whether validation succeeded or not
*
* @see BaseBackendForm::isValidAuthenticationBacken
*/
public function isValidAuthenticationBackend()
{
if (! Platform::extensionLoaded('ldap')) {
/*
* It should be possible to run icingaweb without the php ldap extension, when
* no ldap backends are needed. When the user tries to create an ldap backend
* without ldap installed we need to show him an error.
*/
$this->addErrorMessage(t('Using ldap is not possible, the php extension "ldap" is not installed.'));
if (false === $this->isValidAuthenticationBackend($this)) {
return false;
}
}
/**
* Validate the configuration by creating a backend and requesting the user count
*
* @param Form $form The form to fetch the configuration values from
*
* @return bool Whether validation succeeded or not
*/
public function isValidAuthenticationBackend(Form $form)
{
$element = $form->getElement('resource');
try {
$cfg = $this->getConfig();
$backendName = 'backend_' . $this->filterName($this->getBackendName()) . '_name';
$backendConfig = new Zend_Config($cfg[$this->getValue($backendName)]);
$backend = ResourceFactory::create($backendConfig->resource);
$testConn = new LdapUserBackend(
$backend,
$backendConfig->user_class,
$backendConfig->user_name_attribute
);
$testConn->assertAuthenticationPossible();
/*
if ($testConn->count() === 0) {
throw new IcingaException('No Users Found On Directory Server');
}
*/
} catch (Exception $exc) {
$this->addErrorMessage(
t('Connection Validation Failed: ' . $exc->getMessage())
$ldapUserBackend = new LdapUserBackend(
ResourceFactory::create($element->getValue()),
$form->getElement('user_class')->getValue(),
$form->getElement('user_name_attribute')->getValue()
);
$ldapUserBackend->assertAuthenticationPossible();
} catch (Exception $e) {
$element->addError(sprintf(t('Connection validation failed: %s'), $e->getMessage()));
return false;
}

View File

@ -1,233 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Authentication;
use Zend_Config;
use Icinga\Web\Form;
/**
* Form for modifying the authentication provider order
*/
class ReorderForm extends Form
{
/**
* The name of the current backend which will get action buttons for up and down movement
*
* @var string
*/
protected $backend;
/**
* The current ordering of all backends, required to determine possible changes
*
* @var array
*/
protected $currentOrder = array();
/**
* Set an array with the current order of all backends
*
* @param array $order An array containing backend names in the order
* they are defined in the authentication.ini
*/
public function setCurrentOrder(array $order)
{
$this->currentOrder = $order;
}
/**
* Set the name of the authentication backend for which to create the form
*
* @param string $backend The name of the authentication backend
*/
public function setBackendName($backend)
{
$this->backend = $backend;
}
/**
* Return the name of the currently set backend as it will appear in the form
*
* @return string The name of the backend
*/
public function getBackendName()
{
return $this->filterName($this->backend);
}
/**
* Create this form
*
* @see Form::create
*/
public function create()
{
if ($this->moveElementUp($this->backend, $this->currentOrder) !== $this->currentOrder) {
$upForm = new Form();
$upForm->addElement(
'hidden',
'form_backend_order',
array(
'required' => true,
'value' => join(',', $this->moveElementUp($this->backend, $this->currentOrder))
)
);
$upForm->addElement(
'button',
'btn_' . $this->getBackendName() . '_reorder_up',
array(
'type' => 'submit',
'escape' => false,
'value' => 'btn_' . $this->getBackendName() . '_reorder_up',
'name' => 'btn_' . $this->getBackendName() . '_reorder_up',
'label' => $this->getView()->icon('up.png', t('Move up in authentication order'))
)
);
$this->addSubForm($upForm, 'btn_reorder_up');
}
if ($this->moveElementDown($this->backend, $this->currentOrder) !== $this->currentOrder) {
$downForm = new Form();
$downForm->addElement(
'hidden',
'form_backend_order',
array(
'required' => true,
'value' => join(',', $this->moveElementDown($this->backend, $this->currentOrder))
)
);
$downForm->addElement(
'button',
'btn_' . $this->getBackendName() . '_reorder_down',
array(
'type' => 'submit',
'escape' => false,
'value' => 'btn_' . $this->getBackendName() . '_reorder_down',
'name' => 'btn_' . $this->getBackendName() . '_reorder_down',
'label' => $this->getView()->icon('down.png', t('Move down in authentication order'))
)
);
$this->addSubForm($downForm, 'btn_reorder_down');
}
}
/**
* Return the flattened result of $this->getValues
*
* @return array The currently set values
*
* @see Form::getValues()
*/
protected function getFlattenedValues()
{
$result = array();
foreach (parent::getValues() as $key => $value) {
if (is_array($value)) {
$result += $value;
} else {
$result[$key] = $value;
}
}
return $result;
}
/**
* Determine whether this form is submitted by testing the submit buttons of both subforms
*
* @return bool Whether the form has been submitted or not
*/
public function isSubmitted()
{
$checkData = $this->getRequest()->getParams();
return isset($checkData['btn_' . $this->getBackendName() . '_reorder_up']) ||
isset($checkData['btn_' . $this->getBackendName() . '_reorder_down']);
}
/**
* Return the reordered configuration after a reorder button has been submitted
*
* @param Zend_Config $config The configuration to reorder
*
* @return array An array containing the reordered configuration
*/
public function getReorderedConfig(Zend_Config $config)
{
$originalConfig = $config->toArray();
$newOrder = $this->getFlattenedValues();
$order = explode(',', $newOrder['form_backend_order']);
$reordered = array();
foreach ($order as $key) {
if (isset($originalConfig[$key])) {
$reordered[$key] = $originalConfig[$key];
}
}
return $reordered;
}
/**
* Static helper for moving an element in an array one slot up, if possible
*
* Example:
*
* <pre>
* $array = array('first', 'second', 'third');
* moveElementUp('third', $array); // returns ['first', 'third', 'second']
* </pre>
*
* @param string $key The key to bubble up one slot
* @param array $array The array to work with
*
* @return array The modified array
*/
protected static function moveElementUp($key, array $array)
{
for ($i = 0; $i < count($array) - 1; $i++) {
if ($array[$i + 1] === $key) {
$swap = $array[$i];
$array[$i] = $array[$i + 1];
$array[$i + 1] = $swap;
return $array;
}
}
return $array;
}
/**
* Static helper for moving an element in an array one slot down, if possible
*
* Example:
*
* <pre>
* $array = array('first', 'second', 'third');
* moveElementDown('first', $array); // returns ['second', 'first', 'third']
* </pre>
*
* @param string $key The key to bubble up one slot
* @param array $array The array to work with
*
* @return array The modified array
*/
protected static function moveElementDown($key, array $array)
{
for ($i = 0; $i < count($array) - 1; $i++) {
if ($array[$i] === $key) {
$swap = $array[$i + 1];
$array[$i + 1] = $array[$i];
$array[$i] = $swap;
return $array;
}
}
return $array;
}
}

View File

@ -0,0 +1,322 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Form\ConfigForm;
use Icinga\Web\Notification;
use Icinga\Application\Config;
use Icinga\Application\Platform;
use Icinga\Exception\ConfigurationError;
use Icinga\Form\Config\Authentication\DbBackendForm;
use Icinga\Form\Config\Authentication\LdapBackendForm;
use Icinga\Form\Config\Authentication\AutologinBackendForm;
class AuthenticationBackendConfigForm extends ConfigForm
{
/**
* The available resources split by type
*
* @var array
*/
protected $resources;
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_authbackend');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* Set the resource configuration to use
*
* @param Config $resources The resource configuration
*
* @return self
*
* @throws ConfigurationError In case no resources are available for authentication
*/
public function setResourceConfig(Config $resourceConfig)
{
$resources = array();
foreach ($resourceConfig as $name => $resource) {
$resources[strtolower($resource->type)][] = $name;
}
if (empty($resources)) {
throw new ConfigurationError(t('Could not find any resources for authentication'));
}
$this->resources = $resources;
return $this;
}
/**
* Return a form object for the given backend type
*
* @param string $type The backend type for which to return a form
*
* @return Form
*/
public function getBackendForm($type)
{
if ($type === 'db') {
$form = new DbBackendForm();
$form->setResources(isset($this->resources['db']) ? $this->resources['db'] : array());
} elseif ($type === 'ldap') {
$form = new LdapBackendForm();
$form->setResources(isset($this->resources['ldap']) ? $this->resources['ldap'] : array());
} elseif ($type === 'autologin') {
$form = new AutologinBackendForm();
} else {
throw new InvalidArgumentException(sprintf(t('Invalid backend type "%s" provided'), $type));
}
return $form;
}
/**
* Add a particular authentication 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('Authentication backend name missing'));
} elseif ($this->config->get($name) !== null) {
throw new InvalidArgumentException(t('Authentication backend already exists'));
}
unset($values['name']);
$this->config->{$name} = $values;
return $this;
}
/**
* Edit a particular authentication 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 authentication backend name missing'));
} elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) {
throw new InvalidArgumentException(t('New authentication backend name missing'));
} elseif (($backendConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown authentication backend provided'));
}
if ($newName !== $name) {
// Only remove the old entry if it has changed as the order gets screwed when editing backend names
unset($this->config->{$name});
}
unset($values['name']);
$this->config->{$newName} = array_merge($backendConfig->toArray(), $values);
return $this->config->{$newName};
}
/**
* Remove the given authentication 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('Authentication backend name missing'));
} elseif (($backendConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown authentication backend provided'));
}
unset($this->config->{$name});
return $backendConfig;
}
/**
* Move the given authentication backend up or down in order
*
* @param string $name The name of the backend to be moved
* @param int $position The new (absolute) position of the backend
*
* @return self
*
* @throws InvalidArgumentException In case the backend does not exist
*/
public function move($name, $position)
{
if (! $name) {
throw new InvalidArgumentException(t('Authentication backend name missing'));
} elseif ($this->config->get($name) === null) {
throw new InvalidArgumentException(t('Unknown authentication backend provided'));
}
$backendOrder = $this->config->keys();
array_splice($backendOrder, array_search($name, $backendOrder), 1);
array_splice($backendOrder, $position, 0, $name);
$newConfig = array();
foreach ($backendOrder as $backendName) {
$newConfig[$backendName] = $this->config->get($backendName);
}
$config = new Config($newConfig);
$this->config = $config->setConfigFile($this->config->getConfigFile());
return $this;
}
/**
* Add or edit an authentication backend and save the configuration
*
* Performs a connectivity validation using the submitted values. A checkbox is
* added to the form to skip the check if it fails and redirection is aborted.
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) {
$backendForm = $this->getBackendForm($this->getElement('type')->getValue());
if (false === $backendForm->isValidAuthenticationBackend($this)) {
$this->addElement($this->getForceCreationCheckbox());
return false;
}
}
$authBackend = $request->getQuery('auth_backend');
try {
if ($authBackend === null) { // create new backend
$this->add($this->getValues());
$message = t('Authentication backend "%s" has been successfully created');
} else { // edit existing backend
$this->edit($authBackend, $this->getValues());
$message = t('Authentication 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 an authentication 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)
{
$authBackend = $request->getQuery('auth_backend');
if ($authBackend !== null) {
if ($authBackend === '') {
throw new ConfigurationError(t('Authentication backend name missing'));
} elseif (false === isset($this->config->{$authBackend})) {
throw new ConfigurationError(t('Unknown authentication backend provided'));
} elseif (false === isset($this->config->{$authBackend}->backend)) {
throw new ConfigurationError(sprintf(t('Backend "%s" has no `backend\' setting'), $authBackend));
}
$configValues = $this->config->{$authBackend}->toArray();
$configValues['type'] = $configValues['backend'];
$configValues['name'] = $authBackend;
$this->populate($configValues);
}
}
/**
* Return a checkbox to be displayed at the beginning of the form
* which allows the user to skip the connection validation
*
* @return Zend_Form_Element
*/
protected function getForceCreationCheckbox()
{
return $this->createElement(
'checkbox',
'force_creation',
array(
'order' => 0,
'ignore' => true,
'label' => t('Force Changes'),
'description' => t('Check this box to enforce changes without connectivity validation')
)
);
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$backendTypes = array();
$backendType = isset($formData['type']) ? $formData['type'] : 'db';
if (isset($this->resources['db'])) {
$backendTypes['db'] = t('Database');
}
if (isset($this->resources['ldap']) && ($backendType === 'ldap' || Platform::extensionLoaded('ldap'))) {
$backendTypes['ldap'] = 'LDAP';
}
$autologinBackends = array_filter(
$this->config->toArray(),
function ($authBackendCfg) {
return isset($authBackendCfg['backend']) && $authBackendCfg['backend'] === 'autologin';
}
);
if ($backendType === 'autologin' || empty($autologinBackends)) {
$backendTypes['autologin'] = t('Autologin');
}
$this->addElement(
'select',
'type',
array(
'ignore' => true,
'required' => true,
'autosubmit' => true,
'label' => t('Backend Type'),
'description' => t('The type of the resource to use for this authenticaton backend'),
'multiOptions' => $backendTypes
)
);
if (isset($formData['force_creation']) && $formData['force_creation']) {
// In case another error occured and the checkbox was displayed before
$this->addElement($this->getForceCreationCheckbox());
}
$this->addElements($this->getBackendForm($backendType)->createElements($formData)->getElements());
}
}

View File

@ -0,0 +1,68 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
class AuthenticationBackendReorderForm extends ConfigForm
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_reorder_authbackend');
$this->setViewScript('form/reorder-authbackend.phtml');
}
/**
* Return the ordered backend names
*
* @return array
*/
public function getBackendOrder()
{
return $this->config->keys();
}
/**
* Update the authentication backend order and save the configuration
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
$formData = $this->getRequestData($request);
if (isset($formData['backend_newpos'])) {
$configForm = $this->getConfigForm();
list($backendName, $position) = explode('|', $formData['backend_newpos'], 2);
try {
if ($configForm->move($backendName, $position)->save()) {
Notification::success(t('Authentication order updated!'));
} else {
return false;
}
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
}
}
}
/**
* Return the config form for authentication backends
*
* @return ConfigForm
*/
protected function getConfigForm()
{
$form = new AuthenticationBackendConfigForm();
$form->setIniConfig($this->config);
return $form;
}
}

View File

@ -1,69 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use Icinga\Web\Form;
/**
* Form for confirming removal of an object
*/
class ConfirmRemovalForm extends Form
{
/**
* The value of the target to remove
*
* @var string
*/
private $removeTarget;
/**
* The name of the target parameter to remove
*
* @var string
*/
private $targetName;
/**
* Set the remove target in this field to be a hidden field with $name and value $target
*
* @param string $name The name to be set in the hidden field
* @param string $target The value to be set in the hidden field
*/
public function setRemoveTarget($name, $target)
{
$this->targetName = $name;
$this->removeTarget = $target;
}
/**
* Create the confirmation form
*
* @see Form::create()
*/
public function create()
{
$this->setName('form_confirm_removal');
$this->addElement(
'hidden',
$this->targetName,
array(
'value' => $this->removeTarget,
'required' => true
)
);
$this->addElement(
'button',
'btn_submit',
array(
'type' => 'submit',
'escape' => false,
'value' => '1',
'class' => 'btn btn-cta btn-common',
'label' => '<i class="icinga-icon-remove"></i> Confirm Removal'
)
);
}
}

View File

@ -0,0 +1,118 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\General;
use DateTimeZone;
use Icinga\Web\Form;
use Icinga\Util\Translator;
use Icinga\Data\ResourceFactory;
/**
* Form class to modify the general application configuration
*/
class ApplicationConfigForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_general_application');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$languages = array();
foreach (Translator::getAvailableLocaleCodes() as $language) {
$languages[$language] = $language;
}
$this->addElement(
'select',
'global_language',
array(
'label' => t('Default Language'),
'required' => true,
'multiOptions' => $languages,
'description' => t(
'Select the language to use by default. Can be overwritten by a user in his preferences.'
)
)
);
$tzList = array();
foreach (DateTimeZone::listIdentifiers() as $tz) {
$tzList[$tz] = $tz;
}
$this->addElement(
'select',
'global_timezone',
array(
'label' => t('Default Application Timezone'),
'required' => true,
'multiOptions' => $tzList,
'description' => t(
'Select the timezone to be used as the default. User\'s can set their own timezone if'
. ' they like to, but this is the timezone to be used as the default setting .'
),
'value' => date_default_timezone_get()
)
);
$this->addElement(
'text',
'global_modulePath',
array(
'label' => t('Module Path'),
'required' => true,
'description' => t(
'Contains the directories that will be searched for available modules, separated by '
. 'colons. Modules that don\'t exist in these directories can still be symlinked in '
. 'the module folder, but won\'t show up in the list of disabled modules.'
),
'value' => realpath(ICINGAWEB_APPDIR . '/../modules')
)
);
$this->addElement(
'select',
'preferences_type',
array(
'required' => true,
'autosubmit' => true,
'label' => t('User Preference Storage Type'),
'multiOptions' => array(
'ini' => t('File System (INI Files)'),
'db' => t('Database'),
'null' => t('Don\'t Store Preferences')
)
)
);
if (isset($formData['preferences_type']) && $formData['preferences_type'] === 'db') {
$backends = array();
foreach (ResourceFactory::getResourceConfigs()->toArray() as $name => $resource) {
if ($resource['type'] === 'db') {
$backends[$name] = $name;
}
}
$this->addElement(
'select',
'preferences_resource',
array(
'required' => true,
'multiOptions' => $backends,
'label' => t('Database Connection')
)
);
}
return $this;
}
}

View File

@ -0,0 +1,118 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\General;
use Icinga\Application\Icinga;
use Icinga\Web\Form;
use Icinga\Web\Form\Validator\WritablePathValidator;
class LoggingConfigForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_general_logging');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'select',
'logging_level',
array(
'required' => true,
'label' => t('Logging Level'),
'description' => t('The maximum loglevel to emit.'),
'multiOptions' => array(
0 => t('None'),
1 => t('Error'),
2 => t('Warning'),
3 => t('Information'),
4 => t('Debug')
)
)
);
$this->addElement(
'select',
'logging_type',
array(
'required' => true,
'class' => 'autosubmit',
'label' => t('Logging Type'),
'description' => t('The type of logging to utilize.'),
'multiOptions' => array(
'syslog' => 'Syslog',
'file' => t('File')
)
)
);
if (false === isset($formData['logging_type']) || $formData['logging_type'] === 'syslog') {
$this->addElement(
'text',
'logging_application',
array(
'required' => true,
'label' => t('Application Prefix'),
'description' => t('The name of the application by which to prefix syslog messages.'),
'value' => 'icingaweb',
'validators' => array(
array(
'Regex',
false,
array(
'pattern' => '/^[^\W]+$/',
'messages' => array(
'regexNotMatch' => 'The application prefix cannot contain any whitespaces.'
)
)
)
)
)
);
$this->addElement(
'select',
'logging_facility',
array(
'required' => true,
'label' => t('Facility'),
'description' => t('The Syslog facility to utilize.'),
'multiOptions' => array(
'LOG_USER' => 'LOG_USER'
)
)
);
} elseif ($formData['logging_type'] === 'file') {
$this->addElement(
'text',
'logging_target',
array(
'required' => true,
'label' => t('Filepath'),
'description' => t('The logfile to write messages to.'),
'value' => $this->getDefaultLogDir(),
'validators' => array(new WritablePathValidator())
)
);
}
return $this;
}
/**
* Return the default logging directory for type "file"
*
* @return string
*/
protected function getDefaultLogDir()
{
return realpath(Icinga::app()->getApplicationDir('../var/log/icingaweb.log'));
}
}

View File

@ -0,0 +1,73 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
use Icinga\Form\Config\General\LoggingConfigForm;
use Icinga\Form\Config\General\ApplicationConfigForm;
/**
* Form class for application-wide and logging specific settings
*/
class GeneralConfigForm extends ConfigForm
{
/**
* Initialize this configuration form
*/
public function init()
{
$this->setName('form_config_general');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$appConfigForm = new ApplicationConfigForm();
$loggingConfigForm = new LoggingConfigForm();
$this->addElements($appConfigForm->createElements($formData)->getElements());
$this->addElements($loggingConfigForm->createElements($formData)->getElements());
}
/**
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
foreach ($this->getValues() as $sectionAndPropertyName => $value) {
list($section, $property) = explode('_', $sectionAndPropertyName);
if (isset($this->config->{$section})) {
$this->config->{$section}->{$property} = $value;
} else {
$this->config->{$section} = array($property => $value);
}
}
if ($this->save()) {
Notification::success(t('New configuration has successfully been stored'));
} else {
return false;
}
}
/**
* @see Form::onRequest()
*/
public function onRequest(Request $request)
{
$values = array();
foreach ($this->config as $section => $properties) {
foreach ($properties as $name => $value) {
$values[$section . '_' . $name] = $value;
}
}
$this->populate($values);
}
}

View File

@ -1,270 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use Icinga\Application\Config as IcingaConfig;
use Icinga\Data\ResourceFactory;
use Icinga\Web\Form;
use Icinga\Util\Translator;
use Icinga\Web\Form\Validator\WritablePathValidator;
use Icinga\Web\Form\Decorator\ConditionalHidden;
use DateTimeZone;
use Zend_Form_Element_Select;
use Zend_Config;
/**
* Configuration form for general, application-wide settings
*/
class GeneralForm extends Form
{
/**
* The base directory of the icingaweb configuration
*
* @var string
*/
private $configDir = null;
/**
* The resources to use instead of the factory provided ones (use for testing)
*
* @var null
*/
private $resources;
/**
* Set a specific configuration directory to use for configuration specific default paths
*
* @param string $dir
*/
public function setConfigDir($dir)
{
$this->configDir = $dir;
}
/**
* Return the config path set for this form or the application wide config path if none is set
*
* @return string
*
* @see IcingaConfig::configDir
*/
public function getConfigDir()
{
return $this->configDir === null ? IcingaConfig::$configDir : $this->configDir;
}
/**
* Set an alternative array of resources that should be used instead of the DBFactory resource set
* (used for testing)
*
* @param array $resources The resources to use for populating the db selection field
*/
public function setResources(array $resources)
{
$this->resources = $resources;
}
/**
* Return content of the resources.ini or previously set resources for displaying in the database selection field
*
* @return array
*/
public function getResources()
{
if ($this->resources === null) {
return ResourceFactory::getResourceConfigs()->toArray();
} else {
return $this->resources;
}
}
/**
* Add a select field for setting the default language
*
* Possible values are determined by Translator::getAvailableLocaleCodes.
*
* @param Zend_Config $cfg The "global" section of the config.ini
*/
private function addLanguageSelection(Zend_Config $cfg)
{
$languages = array();
foreach (Translator::getAvailableLocaleCodes() as $language) {
$languages[$language] = $language;
}
$this->addElement(
'select',
'language',
array(
'label' => t('Default Language'),
'required' => true,
'multiOptions' => $languages,
'helptext' => t(
'Select the language to use by default. Can be overwritten by a user in his preferences.'
),
'value' => $cfg->get('language', Translator::DEFAULT_LOCALE)
)
);
}
/**
* Add a select field for setting the default timezone.
*
* Possible values are determined by DateTimeZone::listIdentifiers
*
* @param Zend_Config $cfg The "global" section of the config.ini
*/
private function addTimezoneSelection(Zend_Config $cfg)
{
$tzList = array();
foreach (DateTimeZone::listIdentifiers() as $tz) {
$tzList[$tz] = $tz;
}
$helptext = 'Select the timezone to be used as the default. User\'s can set their own timezone if'
. ' they like to, but this is the timezone to be used as the default setting .';
$this->addElement(
'select',
'timezone',
array(
'label' => 'Default Application Timezone',
'required' => true,
'multiOptions' => $tzList,
'helptext' => $helptext,
'value' => $cfg->get('timezone', date_default_timezone_get())
)
);
}
/**
* Add configuration settings for module paths
*
* @param Zend_Config $cfg The "global" section of the config.ini
*/
private function addModuleSettings(Zend_Config $cfg)
{
$this->addElement(
'text',
'module_path',
array(
'label' => 'Module Path',
'required' => true,
'helptext' => 'Contains the directories that will be searched for available modules, separated by ' .
' colons. Modules that don\'t exist in these directories can still be symlinked in the module ' .
' folder, but won\'t show up in the list of disabled modules.',
'value' => $cfg->get('modulePath', realpath(ICINGAWEB_APPDIR . '/../modules'))
)
);
}
/**
* Add form elements for setting the user preference storage backend
*
* @param Zend_Config $cfg The Zend_config object of preference section
*/
public function addUserPreferencesDialog(Zend_Config $cfg)
{
$backend = $cfg->get('type', 'ini');
if ($this->getRequest()->get('preferences_type', null) !== null) {
$backend = $this->getRequest()->get('preferences_type');
}
$this->addElement(
'select',
'preferences_type',
array(
'label' => 'User Preference Storage Type',
'required' => true,
'value' => $backend,
'multiOptions' => array(
'ini' => 'File System (INI Files)',
'db' => 'Database',
'null' => 'Don\'t Store Preferences'
)
)
);
$backends = array();
foreach ($this->getResources() as $name => $resource) {
if ($resource['type'] !== 'db') {
continue;
}
$backends[$name] = $name;
}
$txtPreferencesDbResource = new Zend_Form_Element_Select(
array(
'name' => 'preferences_db_resource',
'label' => 'Database Connection',
'required' => $backend === 'db',
'condition' => $backend === 'db',
'value' => $cfg->get('resource'),
'multiOptions' => $backends
)
);
$validator = new WritablePathValidator();
$validator->setRequireExistence();
$this->addElement($txtPreferencesDbResource);
$txtPreferencesDbResource->addDecorator(new ConditionalHidden());
$this->enableAutoSubmit(
array(
'preferences_type'
)
);
}
/**
* Create the general form, using the provided configuration
*
* @see Form::create()
*/
public function create()
{
$config = $this->getConfiguration();
$global = $config->global;
if ($global === null) {
$global = new Zend_Config(array());
}
$preferences = $config->preferences;
if ($preferences === null) {
$preferences = new Zend_Config(array());
}
$this->setName('form_config_general');
$this->addLanguageSelection($global);
$this->addTimezoneSelection($global);
$this->addModuleSettings($global);
$this->addUserPreferencesDialog($preferences);
$this->setSubmitLabel('Save Changes');
}
/**
* Return an Zend_Config object containing the configuration set in this form
*
* @return Zend_Config
*/
public function getConfig()
{
$config = $this->getConfiguration();
if ($config->global === null) {
$config->global = new Zend_Config(array(), true);
}
if ($config->preferences === null) {
$config->preferences = new Zend_Config(array(), true);
}
$values = $this->getValues();
$cfg = clone $config;
$cfg->global->language = $values['language'];
$cfg->global->timezone = $values['timezone'];
$cfg->global->modulePath = $values['module_path'];
$cfg->preferences->type = $values['preferences_type'];
if ($cfg->preferences->type === 'db') {
$cfg->preferences->resource = $values['preferences_db_resource'];
}
return $cfg;
}
}

View File

@ -1,178 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use Zend_Config;
use Icinga\Web\Form;
use Icinga\Application\Icinga;
use Icinga\Web\Form\Validator\WritablePathValidator;
/**
* Form class for setting the application wide logging configuration
*/
class LoggingForm extends Form
{
/**
* Return the default logging directory for type "file"
*
* @return string
*/
protected function getDefaultLogDir()
{
return realpath(Icinga::app()->getApplicationDir() . '/../var/log/icingaweb.log');
}
/**
* Create this logging configuration form
*
* @see Form::create()
*/
public function create()
{
$this->setName('form_config_logging');
$config = $this->getConfiguration();
if (($loggingConfig = $config->logging) === null) {
$loggingConfig = new Zend_Config(array());
}
$this->addElement(
'checkbox',
'logging_enable',
array(
'required' => true,
'label' => t('Logging Enabled'),
'helptext' => t('Check this to enable logging.'),
'value' => $loggingConfig->enable ? 1 : 0
)
);
$this->addElement(
'select',
'logging_level',
array(
'required' => true,
'label' => t('Logging Level'),
'helptext' => t('The maximum loglevel to emit.'),
'value' => intval($loggingConfig->get('level', 0)),
'multiOptions' => array(
0 => t('Error'),
1 => t('Warning'),
2 => t('Information'),
3 => t('Debug')
)
)
);
$this->addElement(
'select',
'logging_type',
array(
'required' => true,
'label' => t('Logging Type'),
'helptext' => t('The type of logging to utilize.'),
'value' => $loggingConfig->get('type', 'file'),
'multiOptions' => array(
'file' => t('File'),
'syslog' => 'Syslog'
)
)
);
$this->enableAutoSubmit(array('logging_type'));
switch ($this->getRequest()->getParam('logging_type', $loggingConfig->get('type', 'file')))
{
case 'syslog':
$this->addElement(
'text',
'logging_application',
array(
'required' => true,
'label' => t('Application Prefix'),
'helptext' => t('The name of the application by which to prefix syslog messages.'),
'value' => $loggingConfig->get('application', 'icingaweb'),
'validators' => array(
array(
'Regex',
false,
array(
'pattern' => '/^[^\W]+$/',
'messages' => array(
'regexNotMatch' => 'The application prefix cannot contain any whitespaces.'
)
)
)
)
)
);
$this->addElement(
'select',
'logging_facility',
array(
'required' => true,
'label' => t('Facility'),
'helptext' => t('The Syslog facility to utilize.'),
'value' => $loggingConfig->get('facility', 'LOG_USER'),
'multiOptions' => array(
'LOG_USER' => 'LOG_USER'
)
)
);
break;
case 'file':
default:
$this->addElement(
'text',
'logging_target',
array(
'required' => true,
'label' => t('Filepath'),
'helptext' => t('The logfile to write messages to.'),
'value' => $loggingConfig->target ? $loggingConfig->target : $this->getDefaultLogDir(),
'validators' => array(new WritablePathValidator())
)
);
}
$this->setSubmitLabel('{{SAVE_ICON}} Save Changes');
}
public function isValid($data) {
foreach ($this->getElements() as $key => $element) {
// Initialize all empty elements with their default values.
if (!isset($data[$key])) {
$data[$key] = $element->getValue();
}
}
return parent::isValid($data);
}
/**
* Return a Zend_Config object containing the state defined in this form
*
* @return Zend_Config The config defined in this form
*/
public function getConfig()
{
$values = $this->getValues();
$cfg = $this->getConfiguration()->toArray();
$cfg['logging']['enable'] = $values['logging_enable'] == 1;
$cfg['logging']['level'] = $values['logging_level'];
switch ($values['logging_type'])
{
case 'file':
$cfg['logging']['type'] = 'file';
$cfg['logging']['target'] = $values['logging_target'];
break;
case 'syslog':
$cfg['logging']['type'] = 'syslog';
$cfg['logging']['application'] = $values['logging_application'];
$cfg['logging']['facility'] = $values['logging_facility'];
break;
}
return new Zend_Config($cfg);
}
}

View File

@ -0,0 +1,130 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Resource;
use Exception;
use Zend_Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Web\Form\Element\Number;
use Icinga\Data\ResourceFactory;
/**
* Form class for adding/modifying database resources
*/
class DbResourceForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_resource_db');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'select',
'db',
array(
'required' => true,
'label' => t('Database Type'),
'description' => t('The type of SQL database'),
'multiOptions' => array(
'mysql' => 'MySQL',
'pgsql' => 'PostgreSQL'
//'oracle' => 'Oracle'
)
)
);
$this->addElement(
'text',
'host',
array (
'required' => true,
'label' => t('Host'),
'description' => t('The hostname of the database'),
'value' => 'localhost'
)
);
$this->addElement(
new Number(
array(
'required' => true,
'name' => 'port',
'label' => t('Port'),
'description' => t('The port to use'),
'value' => 3306
)
)
);
$this->addElement(
'text',
'dbname',
array(
'required' => true,
'label' => t('Database Name'),
'description' => t('The name of the database to use')
)
);
$this->addElement(
'text',
'username',
array (
'required' => true,
'label' => t('Username'),
'description' => t('The user name to use for authentication')
)
);
$this->addElement(
'password',
'password',
array(
'required' => true,
'renderPassword' => true,
'label' => t('Password'),
'description' => t('The password to use for authentication')
)
);
return $this;
}
/**
* Validate that the current configuration points to a valid resource
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
if (false === $this->isValidResource($this)) {
return false;
}
}
/**
* Validate the resource configuration by trying to connect with it
*
* @param Form $form The form to fetch the configuration values from
*
* @return bool Whether validation succeeded or not
*/
public function isValidResource(Form $form)
{
try {
$resource = ResourceFactory::createResource(new Zend_Config($form->getValues()));
$resource->getConnection()->getConnection();
} catch (Exception $e) {
$form->addError(t('Connectivity validation failed, connection to the given resource not possible.'));
return false;
}
return true;
}
}

View File

@ -0,0 +1,50 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Resource;
use Icinga\Web\Form;
use Icinga\Web\Form\Validator\ReadablePathValidator;
/**
* Form class for adding/modifying file resources
*/
class FileResourceForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_resource_file');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'filename',
array(
'required' => true,
'label' => t('Filepath'),
'description' => t('The filename to fetch information from'),
'validators' => array(new ReadablePathValidator())
)
);
$this->addElement(
'text',
'fields',
array(
'required' => true,
'label' => t('Pattern'),
'description' => t('The regular expression by which to identify columns')
)
);
return $this;
}
}

View File

@ -0,0 +1,116 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Resource;
use Exception;
use Zend_Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Web\Form\Element\Number;
use Icinga\Data\ResourceFactory;
/**
* Form class for adding/modifying ldap resources
*/
class LdapResourceForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_resource_ldap');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'hostname',
array(
'required' => true,
'label' => t('Host'),
'description' => t('The hostname or address of the LDAP server to use for authentication'),
'value' => 'localhost'
)
);
$this->addElement(
new Number(
array(
'required' => true,
'name' => 'port',
'label' => t('Port'),
'description' => t('The port of the LDAP server to use for authentication'),
'value' => 389
)
)
);
$this->addElement(
'text',
'root_dn',
array(
'required' => true,
'label' => t('Root DN'),
'description' => t('The path where users can be found on the ldap server')
)
);
$this->addElement(
'text',
'bind_dn',
array(
'required' => true,
'label' => t('Bind DN'),
'description' => t('The user dn to use for querying the ldap server')
)
);
$this->addElement(
'password',
'bind_pw',
array(
'required' => true,
'renderPassword' => true,
'label' => t('Bind Password'),
'description' => t('The password to use for querying the ldap server')
)
);
return $this;
}
/**
* Validate that the current configuration points to a valid resource
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
if (false === $this->isValidResource($this)) {
return false;
}
}
/**
* Validate the resource configuration by trying to connect with it
*
* @param Form $form The form to fetch the configuration values from
*
* @return bool Whether validation succeeded or not
*/
public function isValidResource(Form $form)
{
try {
$resource = ResourceFactory::createResource(new Zend_Config($form->getValues()));
$resource->connect();
} catch (Exception $e) {
$form->addError(t('Connectivity validation failed, connection to the given resource not possible.'));
return false;
}
return true;
}
}

View File

@ -0,0 +1,77 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Resource;
use Exception;
use Zend_Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Application\Icinga;
use Icinga\Data\ResourceFactory;
/**
* Form class for adding/modifying livestatus resources
*/
class LivestatusResourceForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_resource_livestatus');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'socket',
array(
'required' => true,
'label' => t('Socket'),
'description' => t('The path to your livestatus socket used for querying monitoring data'),
'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/rw/livestatus')
)
);
return $this;
}
/**
* Validate that the current configuration points to a valid resource
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
if (false === $this->isValidResource($this)) {
return false;
}
}
/**
* Validate the resource configuration by trying to connect with it
*
* @param Form $form The form to fetch the configuration values from
*
* @return bool Whether validation succeeded or not
*/
public function isValidResource(Form $form)
{
try {
$resource = ResourceFactory::createResource(new Zend_Config($form->getValues()));
$resource->connect()->disconnect();
} catch (Exception $e) {
$form->addError(t('Connectivity validation failed, connection to the given resource not possible.'));
return false;
}
return true;
}
}

View File

@ -0,0 +1,54 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Resource;
use Icinga\Web\Form;
use Icinga\Application\Icinga;
use Icinga\Web\Form\Validator\ReadablePathValidator;
/**
* Form class for adding/modifying statusdat resources
*/
class StatusdatResourceForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_resource_statusdat');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'status_file',
array(
'required' => true,
'label' => t('Filepath'),
'description' => t('Location of your icinga status.dat file'),
'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/status.dat'),
'validators' => array(new ReadablePathValidator())
)
);
$this->addElement(
'text',
'object_file',
array(
'required' => true,
'label' => t('Filepath'),
'description' => t('Location of your icinga objects.cache file'),
'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/objects.cache'),
'validators' => array(new ReadablePathValidator())
)
);
return $this;
}
}

View File

@ -0,0 +1,256 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
use Icinga\Form\Config\Resource\DbResourceForm;
use Icinga\Form\Config\Resource\FileResourceForm;
use Icinga\Form\Config\Resource\LdapResourceForm;
use Icinga\Form\Config\Resource\LivestatusResourceForm;
use Icinga\Form\Config\Resource\StatusdatResourceForm;
use Icinga\Application\Platform;
use Icinga\Exception\ConfigurationError;
class ResourceConfigForm extends ConfigForm
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_resource');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* Return a form object for the given resource type
*
* @param string $type The resource type for which to return a form
*
* @return Form
*/
public function getResourceForm($type)
{
if ($type === 'db') {
return new DbResourceForm();
} elseif ($type === 'ldap') {
return new LdapResourceForm();
} elseif ($type === 'livestatus') {
return new LivestatusResourceForm();
} elseif ($type === 'statusdat') {
return new StatusdatResourceForm();
} elseif ($type === 'file') {
return new FileResourceForm();
} else {
throw new InvalidArgumentException(sprintf(t('Invalid resource type "%s" provided'), $type));
}
}
/**
* Add a particular resource
*
* The backend to add is identified by the array-key `name'.
*
* @param array $values The values to extend the configuration with
*
* @return self
*
* @thrwos InvalidArgumentException In case the resource does already exist
*/
public function add(array $values)
{
$name = isset($values['name']) ? $values['name'] : '';
if (! $name) {
throw new InvalidArgumentException(t('Resource name missing'));
} elseif ($this->config->{$name} !== null) {
throw new InvalidArgumentException(t('Resource already exists'));
}
unset($values['name']);
$this->config->{$name} = $values;
return $this;
}
/**
* Edit a particular resource
*
* @param string $name The name of the resource to edit
* @param array $values The values to edit the configuration with
*
* @return array The edited configuration
*
* @throws InvalidArgumentException In case the resource does not exist
*/
public function edit($name, array $values)
{
if (! $name) {
throw new InvalidArgumentException(t('Old resource name missing'));
} elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) {
throw new InvalidArgumentException(t('New resource name missing'));
} elseif (($resourceConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown resource provided'));
}
unset($values['name']);
unset($this->config->{$name});
$this->config->{$newName} = array_merge($resourceConfig->toArray(), $values);
return $this->config->{$newName};
}
/**
* Remove a particular resource
*
* @param string $name The name of the resource to remove
*
* @return array The removed resource configuration
*
* @throws InvalidArgumentException In case the resource does not exist
*/
public function remove($name)
{
if (! $name) {
throw new InvalidArgumentException(t('Resource name missing'));
} elseif (($resourceConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown resource provided'));
}
unset($this->config->{$name});
return $resourceConfig;
}
/**
* Add or edit a resource and save the configuration
*
* Performs a connectivity validation using the submitted values. A checkbox is
* added to the form to skip the check if it fails and redirection is aborted.
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) {
$resourceForm = $this->getResourceForm($this->getElement('type')->getValue());
if (method_exists($resourceForm, 'isValidResource') && false === $resourceForm->isValidResource($this)) {
$this->addElement($this->getForceCreationCheckbox());
return false;
}
}
$resource = $request->getQuery('resource');
try {
if ($resource === null) { // create new resource
$this->add($this->getValues());
$message = t('Resource "%s" has been successfully created');
} else { // edit existing resource
$this->edit($resource, $this->getValues());
$message = t('Resource "%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 resource 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)
{
$resource = $request->getQuery('resource');
if ($resource !== null) {
if ($resource === '') {
throw new ConfigurationError(t('Resource name missing'));
} elseif (false === isset($this->config->{$resource})) {
throw new ConfigurationError(t('Unknown resource provided'));
}
$configValues = $this->config->{$resource}->toArray();
$configValues['name'] = $resource;
$this->populate($configValues);
}
}
/**
* Return a checkbox to be displayed at the beginning of the form
* which allows the user to skip the connection validation
*
* @return Zend_Form_Element
*/
protected function getForceCreationCheckbox()
{
return $this->createElement(
'checkbox',
'force_creation',
array(
'order' => 0,
'ignore' => true,
'label' => t('Force Changes'),
'description' => t('Check this box to enforce changes without connectivity validation')
)
);
}
/**
* @see Form::createElemeents()
*/
public function createElements(array $formData)
{
$resourceType = isset($formData['type']) ? $formData['type'] : 'db';
$resourceTypes = array(
'file' => t('File'),
'statusdat' => 'Status.dat',
'livestatus' => 'Livestatus',
);
if ($resourceType === 'ldap' || Platform::extensionLoaded('ldap')) {
$resourceTypes['ldap'] = 'LDAP';
}
if ($resourceType === 'db' || Platform::extensionLoaded('mysql') || Platform::extensionLoaded('pgsql')) {
$resourceTypes['db'] = t('SQL Database');
}
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Resource Name'),
'description' => t('The unique name of this resource')
)
);
$this->addElement(
'select',
'type',
array(
'required' => true,
'autosubmit' => true,
'label' => t('Resource Type'),
'description' => t('The type of resource'),
'multiOptions' => $resourceTypes,
'value' => $resourceType
)
);
if (isset($formData['force_creation']) && $formData['force_creation']) {
// In case another error occured and the checkbox was displayed before
$this->addElement($this->getForceCreationCheckbox());
}
$this->addElements($this->getResourceForm($resourceType)->createElements($formData)->getElements());
}
}

View File

@ -1,507 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use Exception;
use Icinga\Application\Platform;
use Zend_Config;
use Zend_Form_Element_Checkbox;
use Icinga\Web\Form;
use Icinga\Data\ResourceFactory;
use Icinga\Web\Form\Element\Number;
use Icinga\Web\Form\Decorator\HelpText;
class ResourceForm extends Form
{
/**
* The resource
*
* @var Zend_Config
*/
protected $resource;
/**
* The (new) name of the resource
*
* @var string
*/
protected $name;
/**
* The old name of the resource
*
* @var string
*/
protected $oldName;
/**
* Set the current resource name
*
* @param string $name The name to set
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get the current resource name
*
* @return null|string
*/
public function getName()
{
$name = $this->getValue('resource_all_name');
if (!$name) {
return $this->name;
}
return $name;
}
/**
* Set the original name of the resource
*
* @param string $name The name to set
*/
public function setOldName($name)
{
$this->oldName = $name;
}
/**
* Get the resource name that was initially set
*
* @return null|string
*/
public function getOldName()
{
$oldName = $this->getValue('resource_all_name_old');
if (!$oldName) {
return $this->oldName;
}
return $oldName;
}
/**
* Set the resource configuration to edit.
*
* @param Zend_Config $resource The config to set
*/
public function setResource(Zend_Config $resource)
{
$this->resource = $resource;
}
/**
* Get the current resource configuration.
*
* @return Zend_Config
*/
public function getResource()
{
if (!isset($this->resource)) {
$this->resource = new Zend_Config(array('type' => 'db'));
}
return $this->resource;
}
protected function addDbForm()
{
$this->addElement(
'select',
'resource_db_db',
array(
'required' => true,
'label' => t('Database Type'),
'helptext' => t('The type of SQL database you want to create.'),
'value' => $this->getResource()->get('db', 'mysql'),
'multiOptions' => array(
'mysql' => 'MySQL',
'pgsql' => 'PostgreSQL'
//'oracle' => 'Oracle'
)
)
);
$this->addElement(
'text',
'resource_db_host',
array (
'required' => true,
'label' => t('Host'),
'helptext' => t('The hostname of the database.'),
'value' => $this->getResource()->get('host', 'localhost')
)
);
$this->addElement(
new Number(
array(
'name' => 'resource_db_port',
'required' => true,
'label' => t('Port'),
'helptext' => t('The port to use.'),
'value' => $this->getResource()->get('port', 3306)
)
)
);
$this->addElement(
'text',
'resource_db_dbname',
array(
'required' => true,
'label' => t('Database Name'),
'helptext' => t('The name of the database to use'),
'value' => $this->getResource()->get('dbname', '')
)
);
$this->addElement(
'text',
'resource_db_username',
array (
'required' => true,
'label' => t('Username'),
'helptext' => t('The user name to use for authentication.'),
'value' => $this->getResource()->get('username', '')
)
);
$this->addElement(
'password',
'resource_db_password',
array(
'required' => true,
'renderPassword' => true,
'label' => t('Password'),
'helptext' => t('The password to use for authentication'),
'value' => $this->getResource()->get('password', '')
)
);
}
protected function addStatusdatForm()
{
$this->addElement(
'text',
'resource_statusdat_status_file',
array(
'required' => true,
'label' => t('Filepath'),
'helptext' => t('Location of your icinga status.dat file'),
'value' => $this->getResource()->get('status_file', '/usr/local/icinga/var/status.dat')
)
);
$this->addElement(
'text',
'resource_statusdat_object_file',
array(
'required' => true,
'label' => t('Filepath'),
'helptext' => t('Location of your icinga objects.cache file'),
'value' => $this->getResource()->get('status_file', '/usr/local/icinga/var/objects.cache')
)
);
}
protected function addLivestatusForm()
{
$this->addElement(
'text',
'resource_livestatus_socket',
array(
'required' => true,
'label' => t('Socket'),
'helptext' => t('The path to your livestatus socket used for querying monitoring data'),
'value' => $this->getResource()->get('socket', '/usr/local/icinga/var/rw/livestatus')
)
);
}
protected function addLdapForm()
{
$this->addElement(
'text',
'resource_ldap_hostname',
array(
'required' => true,
'allowEmpty' => false,
'label' => t('Host'),
'helptext' => t('The hostname or address of the LDAP server to use for authentication'),
'value' => $this->getResource()->get('hostname', 'localhost')
)
);
$this->addElement(
'text',
'resource_ldap_root_dn',
array(
'required' => true,
'label' => t('Root DN'),
'helptext' => t('The path where users can be found on the ldap server'),
'value' => $this->getResource()->get('root_dn', 'ou=people,dc=icinga,dc=org')
)
);
$this->addElement(
'text',
'resource_ldap_bind_dn',
array(
'required' => true,
'label' => t('Bind DN'),
'helptext' => t('The user dn to use for querying the ldap server'),
'value' => $this->getResource()->get('bind_dn', 'cn=admin,cn=config')
)
);
$this->addElement(
'password',
'resource_ldap_bind_pw',
array(
'required' => true,
'renderPassword' => true,
'label' => t('Bind Password'),
'helptext' => t('The password to use for querying the ldap server'),
'value' => $this->getResource()->get('bind_pw', '')
)
);
}
protected function addFileForm()
{
$this->addElement(
'text',
'resource_file_filename',
array(
'required' => true,
'label' => t('Filepath'),
'helptext' => t('The filename to fetch information from'),
'value' => $this->getResource()->get('filename', '')
)
);
$this->addElement(
'text',
'resource_file_fields',
array(
'required' => true,
'label' => t('Pattern'),
'helptext' => t('The regular expression by which to identify columns'),
'value' => $this->getResource()->get('fields', '')
)
);
}
protected function addNameFields()
{
$this->addElement(
'text',
'resource_all_name',
array(
'required' => true,
'label' => t('Resource Name'),
'helptext' => t('The unique name of this resource'),
'value' => $this->getName()
)
);
$this->addElement(
'hidden',
'resource_all_name_old',
array(
'value' => $this->getOldName()
)
);
}
/**
* Add checkbox at the beginning of the form which allows to skip connection validation
*/
protected function addForceCreationCheckbox()
{
$checkbox = new Zend_Form_Element_Checkbox(
array(
'order' => 0,
'name' => 'resource_force_creation',
'label' => t('Force Changes'),
'helptext' => t('Check this box to enforce changes without connectivity validation')
)
);
$checkbox->addDecorator(new HelpText());
$this->addElement($checkbox);
}
/**
* Add a select box for choosing the type to use for this backend
*/
protected function addTypeSelectionBox()
{
$this->addElement(
'select',
'resource_type',
array(
'required' => true,
'label' => t('Resource Type'),
'helptext' => t('The type of resource'),
'value' => $this->getResource()->type,
'multiOptions' => array(
'db' => t('SQL Database'),
'ldap' => 'LDAP',
'statusdat' => 'Status.dat',
'livestatus' => 'Livestatus',
'file' => t('File')
)
)
);
$this->enableAutoSubmit(array('resource_type'));
}
/**
* Validate this form with the Zend validation mechanism and perform a validation of the connection
*
* If validation fails, the 'resource_force_creation' checkbox is prepended to the form to allow users to
* skip the connection validation
*
* @param array $data The form input to validate
*
* @return bool True when validation succeeded, false if not
*/
public function isValid($data)
{
if (!parent::isValid($data)) {
return false;
}
if (isset($data['resource_force_creation']) && $data['resource_force_creation']) {
return true;
}
if (!$this->isValidResource()) {
$this->addForceCreationCheckbox();
return false;
}
return true;
}
/**
* Test if the changed resource is a valid resource, by instantiating it and
* checking if a connection is possible
*
* @return bool True when a connection to the resource is possible
*/
public function isValidResource()
{
$config = $this->getConfig();
try {
switch ($config->type) {
case 'db':
/*
* It should be possible to run icingaweb without the pgsql or mysql extension or Zend-Pdo-Classes,
* in case they aren't actually used. When the user tries to create a resource that depends on an
* uninstalled extension, an error should be displayed.
*/
if ($config->db === 'mysql' && ! Platform::extensionLoaded('mysql')) {
$this->addErrorMessage(
t('You need to install the php extension "mysql" and the ' .
'Zend_Pdo_Mysql classes to use MySQL database resources.')
);
return false;
}
if ($config->db === 'pgsql' && ! Platform::extensionLoaded('pgsql')) {
$this->addErrorMessage(
t('You need to install the php extension "pgsql" and the ' .
'Zend_Pdo_Pgsql classes to use PostgreSQL database resources.')
);
return false;
}
$resource = ResourceFactory::createResource($config);
$resource->getConnection()->getConnection();
break;
case 'statusdat':
if (!file_exists($config->object_file) || !file_exists($config->status_file)) {
$this->addErrorMessage(
t('Connectivity validation failed, the provided file does not exist.')
);
return false;
}
break;
case 'livestatus':
$resource = ResourceFactory::createResource($config);
$resource->connect()->disconnect();
break;
case 'ldap':
$resource = ResourceFactory::createResource($config);
$resource->connect();
break;
case 'file':
if (!file_exists($config->filename)) {
$this->addErrorMessage(
t('Connectivity validation failed, the provided file does not exist.')
);
return false;
}
break;
}
} catch (Exception $e) {
$this->addErrorMessage(t('Connectivity validation failed, connection to the given resource not possible.'));
return false;
}
return true;
}
public function create()
{
$this->addNameFields();
$this->addTypeSelectionBox();
switch ($this->getRequest()->getParam('resource_type', $this->getResource()->type)) {
case 'db':
$this->addDbForm();
break;
case 'statusdat':
$this->addStatusdatForm();
break;
case 'livestatus':
$this->addLivestatusForm();
break;
case 'ldap':
$this->addLdapForm();
break;
case 'file':
$this->addFileForm();
break;
}
$this->setSubmitLabel('{{SAVE_ICON}} Save Changes');
}
/**
* Return a configuration containing the backend settings entered in this form
*
* @return Zend_Config The updated configuration for this backend
*/
public function getConfig()
{
$values = $this->getValues();
$result = array('type' => $values['resource_type']);
foreach ($values as $key => $value) {
if ($key !== 'resource_type' && $key !== 'resource_all_name' && $key !== 'resource_all_name_old') {
$configKey = explode('_', $key, 3);
if (count($configKey) === 3) {
$result[$configKey[2]] = $value;
}
}
}
return new Zend_Config($result);
}
}

View File

@ -0,0 +1,68 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form;
use Exception;
use Icinga\Web\Form;
use Icinga\Application\Config;
use Icinga\Config\PreservingIniWriter;
/**
* Form base-class providing standard functionality for configuration forms
*/
class ConfigForm extends Form
{
/**
* The configuration to work with
*
* @var Config
*/
protected $config;
/**
* Set the configuration to use when populating the form or when saving the user's input
*
* @param Config $config The configuration to use
*
* @return self
*/
public function setIniConfig(Config $config)
{
$this->config = $config;
return $this;
}
/**
* Persist the current configuration to disk
*
* If an error occurs the user is shown a view describing the issue and displaying the raw INI configuration.
*
* @return bool Whether the configuration could be persisted
*/
public function save()
{
$writer = new PreservingIniWriter(
array(
'config' => $this->config,
'filename' => $this->config->getConfigFile()
)
);
try {
$writer->write();
} catch (Exception $e) {
$this->addDecorator('ViewScript', array(
'viewModule' => 'default',
'viewScript' => 'showConfiguration.phtml',
'errorMessage' => $e->getMessage(),
'configString' => $writer->render(),
'filePath' => $this->config->getConfigFile()
));
return false;
}
return true;
}
}

View File

@ -0,0 +1,22 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form;
use Icinga\Web\Form;
/**
* Form for confirming removal of an object
*/
class ConfirmRemovalForm extends Form
{
/**
* Initalize this form
*/
public function init()
{
$this->setName('form_confirm_removal');
$this->setSubmitLabel(t('Confirm Removal'));
}
}

View File

@ -5,12 +5,8 @@
namespace Icinga\Form\Dashboard;
use Icinga\Application\Config as IcingaConfig;
use Icinga\Web\Form;
use Icinga\Web\Widget\Dashboard;
use Zend_Form_Element_Text;
use Zend_Form_Element_Submit;
use Zend_Form_Element_Hidden;
use Zend_Form_Element_Select;
use Icinga\Web\Form;
/**
* Form to add an url a dashboard pane
@ -18,124 +14,103 @@ use Zend_Form_Element_Select;
class AddUrlForm extends Form
{
/**
* Add a selection box for different panes to the form
*
* @param Dashboard $dashboard The dashboard to retrieve the panes from
* Initialize this form
*/
private function addPaneSelectionBox(Dashboard $dashboard)
public function init()
{
$selectPane = new Zend_Form_Element_Select(
'pane',
array(
'label' => 'Dashboard',
'required' => true,
'style' => 'display:inline-block;',
'multiOptions' => $dashboard->getPaneKeyTitleArray()
)
);
$newDashboardBtn = new Zend_Form_Element_Submit(
'create_new_pane',
array(
'label' => 'Create A New Pane',
'required' => false,
'class' => 'btn btn-default',
'style' => 'display:inline-block'
)
);
$newDashboardBtn->removeDecorator('DtDdWrapper');
$selectPane->removeDecorator('DtDdWrapper');
$selectPane->removeDecorator('htmlTag');
$this->addElement($selectPane);
$this->addElement($newDashboardBtn);
$this->enableAutoSubmit(array('create_new_pane'));
$this->setName('form_dashboard_addurl');
$this->setSubmitLabel(t('Add To Dashboard'));
}
/**
* Add a textfield for creating a new pane to this form
* @see Form::createElements()
*/
private function addNewPaneTextField($showExistingButton = true)
public function createElements(array $formData)
{
$txtCreatePane = new Zend_Form_Element_Text(
'pane',
array(
'label' => 'New Dashboard Title',
'required' => true,
'style' => 'display:inline-block'
)
);
// Marks this field as a new pane (and prevents the checkbox being displayed when validation errors occur)
$markAsNewPane = new Zend_Form_Element_Hidden(
'create_new_pane',
array(
'required' => true,
'value' => 1
)
);
$cancelDashboardBtn = new Zend_Form_Element_Submit(
'use_existing_dashboard',
array(
'class' => 'btn',
'escape' => false,
'label' => 'Use An Existing Dashboard',
'required' => false
)
);
$cancelDashboardBtn->removeDecorator('DtDdWrapper');
$txtCreatePane->removeDecorator('DtDdWrapper');
$txtCreatePane->removeDecorator('htmlTag');
$this->addElement($txtCreatePane);
if ($showExistingButton) {
$this->addElement($cancelDashboardBtn);
}
$this->addElement($markAsNewPane);
}
/**
* Add elements to this form (used by extending classes)
*/
protected function create()
{
$dashboard = new Dashboard();
$this->setName('form_dashboard_add');
$dashboard->readConfig(IcingaConfig::app('dashboard/dashboard'));
$this->addElement(
'text',
'url',
array(
'label' => 'Url',
'required' => true,
'value' => htmlspecialchars_decode($this->getRequest()->getParam('url', ''))
'required' => true,
'label' => t('Url'),
'helptext' => t('The url being loaded in the dashlet')
)
);
$elems = $dashboard->getPaneKeyTitleArray();
if (empty($elems) || // show textfield instead of combobox when no pane is available
($this->getRequest()->getPost('create_new_pane', '0') && // or when a new pane should be created (+ button)
!$this->getRequest()->getPost('use_existing_dashboard', '0')) // and the user didn't click the 'use
// existing' button
$paneSelectionValues = $this->getDashboardPaneSelectionValues();
if (empty($paneSelectionValues) ||
((isset($formData['create_new_pane']) && $formData['create_new_pane'] != false) &&
(false === isset($formData['use_existing_dashboard']) || $formData['use_existing_dashboard'] != true))
) {
$this->addNewPaneTextField(!empty($elems));
$this->addElement(
'text',
'pane',
array(
'required' => true,
'label' => t("The New Pane's Title"),
'style' => 'display: inline-block'
)
);
$this->addElement( // Prevent the button from being displayed again on validation errors
'hidden',
'create_new_pane',
array(
'value' => 1
)
);
if (false === empty($paneSelectionValues)) {
$this->addElement(
'submit',
'use_existing_dashboard',
array(
'ignore' => true,
'label' => t('Use An Existing Pane'),
'style' => 'display: inline-block'
)
);
}
} else {
$this->addPaneSelectionBox($dashboard);
$this->addElement(
'select',
'pane',
array(
'required' => true,
'label' => t('Pane'),
'style' => 'display: inline-block;',
'multiOptions' => $paneSelectionValues
)
);
$this->addElement(
'submit',
'create_new_pane',
array(
'ignore' => true,
'label' => t('Create A New Pane'),
'style' => 'display: inline-block'
)
);
}
$this->addElement(
'text',
'component',
array(
'label' => 'Title',
'required' => true,
'required' => true,
'label' => t('Title'),
'helptext' => t('The title for the dashlet')
)
);
$this->setSubmitLabel("Add To Dashboard");
}
/**
* Return the names and titles of the available dashboard panes as key-value array
*
* @return array
*/
protected function getDashboardPaneSelectionValues()
{
$dashboard = new Dashboard();
$dashboard->readConfig(IcingaConfig::app('dashboard/dashboard'));
return $dashboard->getPaneKeyTitleArray();
}
}

View File

@ -1,65 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Install;
use Zend_Config;
use Icinga\Web\Wizard\Page;
use Icinga\Form\Config\LoggingForm;
class LoggingPage extends Page
{
/**
* The logging form
*
* @var LoggingForm
*/
protected $loggingForm;
/**
* Initialize this LoggingPage
*/
public function init()
{
$this->setName('logging');
}
/**
* Create and return the logging form
*
* @return LoggingForm
*/
protected function createForm()
{
if ($this->loggingForm === null) {
$this->loggingForm = new LoggingForm();
$this->loggingForm->hideButtons();
$this->loggingForm->setTokenDisabled();
$this->loggingForm->setRequest($this->getRequest());
$this->loggingForm->setConfiguration($this->getConfiguration());
}
return $this->loggingForm;
}
/**
* Create this wizard page
*/
protected function create()
{
$loggingForm = $this->createForm();
$loggingForm->buildForm(); // Needs to get called manually as it's nothing that Zend knows about
$this->addSubForm($loggingForm, $loggingForm->getName());
}
/**
* Return a config containing all values provided by the user
*
* @return Zend_Config
*/
public function getConfig()
{
return $this->createForm()->getConfig();
}
}

View File

@ -1,163 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Preference;
use DateTimeZone;
use Icinga\Util\TimezoneDetect;
use Zend_Config;
use Zend_Form_Element_Text;
use Zend_Form_Element_Select;
use Zend_View_Helper_DateFormat;
use Icinga\Web\Form;
use Icinga\Web\Form\Validator\TimeFormatValidator;
use Icinga\Web\Form\Validator\DateFormatValidator;
use Icinga\Util\Translator;
/**
* General user preferences
*/
class GeneralForm extends Form
{
/**
* Add a select field for setting the user's language
*
* Possible values are determined by Translator::getAvailableLocaleCodes.
* Also, a 'use default format' checkbox is added in order to allow a user to discard his overwritten setting
*
* @param Zend_Config $cfg The "global" section of the config.ini to be used as default value
*/
private function addLanguageSelection(Zend_Config $cfg)
{
$languages = array();
foreach (Translator::getAvailableLocaleCodes() as $language) {
$languages[$language] = $language;
}
$prefs = $this->getUserPreferences();
$useDefaultLanguage = $this->getRequest()->getParam('default_language', !$prefs->has('app.language'));
$this->addElement(
'checkbox',
'default_language',
array(
'label' => t('Use Default Language'),
'value' => $useDefaultLanguage,
'required' => true
)
);
$selectOptions = array(
'label' => t('Your Current Language'),
'required' => !$useDefaultLanguage,
'multiOptions' => $languages,
'helptext' => t('Use the following language to display texts and messages'),
'value' => $prefs->get('app.language', $cfg->get('language', Translator::DEFAULT_LOCALE))
);
if ($useDefaultLanguage) {
$selectOptions['disabled'] = 'disabled';
}
$this->addElement('select', 'language', $selectOptions);
$this->enableAutoSubmit(array('default_language'));
}
/**
* Add a select field for setting the user's timezone.
*
* Possible values are determined by DateTimeZone::listIdentifiers
* Also, a 'use default format' checkbox is added in order to allow a user to discard his overwritten setting
*
* @param Zend_Config $cfg The "global" section of the config.ini to be used as default value
*/
private function addTimezoneSelection(Zend_Config $cfg)
{
$prefs = $this->getUserPreferences();
$useGlobalTimezone = $this->getRequest()->getParam('default_timezone', !$prefs->has('app.timezone'));
$detect = new TimezoneDetect();
$tzList = array();
foreach (DateTimeZone::listIdentifiers() as $tz) {
$tzList[$tz] = $tz;
}
$helptext = 'Use the following timezone for dates and times';
if ($useGlobalTimezone && $detect->success() === true) {
$helptext .= '<br />' . t('Currently your time was detected to be')
. ': '
. '<strong>' . $detect->getTimezoneName() . '</strong>';
}
$selectTimezone = new Zend_Form_Element_Select(
array(
'name' => 'timezone',
'label' => 'Your Current Timezone',
'required' => !$useGlobalTimezone,
'multiOptions' => $tzList,
'helptext' => $helptext,
'value' => $prefs->get('app.timezone', $cfg->get('timezone', date_default_timezone_get()))
)
);
$this->addElement(
'checkbox',
'default_timezone',
array(
'label' => 'Use Default Timezone',
'value' => $useGlobalTimezone,
'required' => true
)
);
if ($useGlobalTimezone) {
$selectTimezone->setAttrib('disabled', 1);
}
$this->addElement($selectTimezone);
$this->enableAutoSubmit(array('default_timezone'));
}
/**
* Create the general form, using the global configuration as fallback values for preferences
*
* @see Form::create()
*/
public function create()
{
$this->setName('form_preference_set');
$config = $this->getConfiguration();
$global = $config->global;
if ($global === null) {
$global = new Zend_Config(array());
}
$this->addLanguageSelection($global);
$this->addTimezoneSelection($global);
$this->setSubmitLabel('Save Changes');
$this->addElement(
'checkbox',
'show_benchmark',
array(
'label' => 'Use benchmark',
'value' => $this->getUserPreferences()->get('app.show_benchmark')
)
);
}
/**
* Return an array containing the preferences set in this form
*
* @return array
*/
public function getPreferences()
{
$values = $this->getValues();
return array(
'app.language' => $values['default_language'] ? null : $values['language'],
'app.timezone' => $values['default_timezone'] ? null : $values['timezone'],
'app.show_benchmark' => $values['show_benchmark'] === '1' ? true : false
);
}
}

View File

@ -0,0 +1,225 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form;
use Exception;
use DateTimeZone;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Web\Session;
use Icinga\Web\Notification;
use Icinga\Util\Translator;
use Icinga\Util\TimezoneDetect;
use Icinga\User\Preferences;
use Icinga\User\Preferences\PreferencesStore;
/**
* Form class to adjust user preferences
*/
class PreferenceForm extends Form
{
/**
* The preferences to work with
*
* @var Preferences
*/
protected $preferences;
/**
* The preference store to use
*
* @var PreferencesStore
*/
protected $store;
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_preferences');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* Set preferences to work with
*
* @param Preferences $preferences The preferences to work with
*
* @return self
*/
public function setPreferences(Preferences $preferences)
{
$this->preferences = $preferences;
return $this;
}
/**
* Set the preference store to use
*
* @param PreferencesStore $store The preference store to use
*
* @return self
*/
public function setStore(PreferencesStore $store)
{
$this->store = $store;
}
/**
* Persist preferences
*
* @return self
*/
public function save()
{
$this->store->load(); // Necessary for patching existing preferences
$this->store->save($this->preferences);
return $this;
}
/**
* Adjust preferences and persist them
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
$webPreferences = $this->preferences->get('icingaweb', array());
foreach ($this->getValues() as $key => $value) {
if ($value === null) {
if (isset($webPreferences[$key])) {
unset($webPreferences[$key]);
}
} else {
$webPreferences[$key] = $value;
}
}
$this->preferences->icingaweb = $webPreferences;
// TODO: Is this even necessary in case the session is written on response?
$session = Session::getSession();
$session->user->setPreferences($this->preferences);
$session->write();
try {
$this->save();
Notification::success(t('Preferences successfully saved'));
} catch (Exception $e) {
Notification::error($e->getMessage());
}
}
/**
* Populate preferences
*
* @see Form::onRequest()
*/
public function onRequest(Request $request)
{
$values = $this->preferences->get('icingaweb', array());
$values['browser_language'] = false === isset($values['language']);
$values['local_timezone'] = false === isset($values['timezone']);
$this->populate($values);
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$languages = array();
foreach (Translator::getAvailableLocaleCodes() as $language) {
$languages[$language] = $language;
}
$tzList = array();
foreach (DateTimeZone::listIdentifiers() as $tz) {
$tzList[$tz] = $tz;
}
$this->addElement(
'checkbox',
'browser_language',
array(
'ignore' => true,
'required' => true,
'autosubmit' => true,
'value' => true,
'label' => t('Use your browser\'s language suggestions')
)
);
$useBrowserLanguage = isset($formData['browser_language']) ? $formData['browser_language'] == 1 : true;
$languageSelection = $this->createElement(
'select',
'language',
array(
'required' => false === $useBrowserLanguage,
'label' => t('Your Current Language'),
'description' => t('Use the following language to display texts and messages'),
'multiOptions' => $languages,
'value' => substr(setlocale(LC_ALL, 0), 0, 5)
)
);
if ($useBrowserLanguage) {
$languageSelection->setAttrib('disabled', 'disabled');
}
$this->addElement($languageSelection);
$this->addElement(
'checkbox',
'local_timezone',
array(
'ignore' => true,
'required' => true,
'autosubmit' => true,
'value' => true,
'label' => t('Use your local timezone')
)
);
$useLocalTimezone = isset($formData['local_timezone']) ? $formData['local_timezone'] == 1 : true;
$timezoneSelection = $this->createElement(
'select',
'timezone',
array(
'required' => false === $useLocalTimezone,
'label' => t('Your Current Timezone'),
'description' => t('Use the following timezone for dates and times'),
'multiOptions' => $tzList,
'value' => $this->getDefaultTimezone()
)
);
if ($useLocalTimezone) {
$timezoneSelection->setAttrib('disabled', 'disabled');
}
$this->addElement($timezoneSelection);
$this->addElement(
'checkbox',
'show_benchmark',
array(
'required' => true,
'label' => t('Use benchmark')
)
);
}
/**
* Return the current default timezone
*
* @return string
*/
protected function getDefaultTimezone()
{
$detect = new TimezoneDetect();
if ($detect->success()) {
return $detect->getTimezoneName();
} else {
return date_default_timezone_get();
}
}
}

View File

@ -486,7 +486,7 @@ msgstr "Die Objekt-Klasse welche benutzt wird, um Benutzer auf diesem LDAP-Serve
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:182
msgid "The password to use for authentication"
msgstr "Das Kennwort welche zur Authentifizierung benutzt werden soll"
msgstr "Das Kennwort welches zur Authentifizierung benutzt werden soll"
#: /usr/local/src/bugfix.master/application/forms/Config/ResourceForm.php:270
msgid "The password to use for querying the ldap server"

View File

@ -4,7 +4,6 @@
use Icinga\Application\Icinga;
use Icinga\Util\DateTimeFactory;
use Icinga\Web\Form\Validator\DateTimeValidator;
/**
* Helper to format date and time. Utilizes DateTimeFactory to ensure time zone awareness
@ -57,7 +56,7 @@ class Zend_View_Helper_DateFormat extends Zend_View_Helper_Abstract
public function format($timestamp, $format)
{
$dt = DateTimeFactory::create();
if (DateTimeValidator::isUnixTimestamp($timestamp)) {
if (DateTimeFactory::isUnixTimestamp($timestamp)) {
$dt->setTimestamp($timestamp);
} else {
return $timestamp;

View File

@ -2,18 +2,30 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use \Zend_View_Helper_FormElement;
/**
* Helper to generate a "datetime" element
* Render date-and-time input controls
*/
class Zend_View_Helper_FormDateTime extends Zend_View_Helper_FormElement
{
/**
* Generate a 'datetime' element
* Format date and time
*
* @param DateTime $dateTime
* @param bool $local
*
* @return string
*/
public function formatDate(DateTime $dateTime, $local)
{
$format = (bool) $local === true ? 'Y-m-d\TH:i:s' : DateTime::RFC3339;
return $dateTime->format($format);
}
/**
* Render the date-and-time input control
*
* @param string $name The element name
* @param int $value The default timestamp
* @param DateTime $value The default timestamp
* @param array $attribs Attributes for the element tag
*
* @return string The element XHTML
@ -21,50 +33,41 @@ class Zend_View_Helper_FormDateTime extends Zend_View_Helper_FormElement
public function formDateTime($name, $value = null, $attribs = null)
{
$info = $this->_getInfo($name, $value, $attribs);
extract($info); // name, value, attribs, options, listsep, disable
// Is it disabled?
extract($info); // name, id, value, attribs, options, listsep, disable
/** @var string $id */
/** @var bool $disable */
$disabled = '';
if ($disabled) {
if ($disable) {
$disabled = ' disabled="disabled"';
}
$jspicker = (isset($attribs['jspicker']) && $attribs['jspicker'] === true) ? true : false;
if (isset($value) && !empty($value)) {
if ($jspicker) {
$value = ' value="' . $this->view->dateFormat()->format($value, $attribs['defaultFormat']) . '"';
} else {
$value = ' value="' . $this->view->dateFormat()->formatDateTime($value) . '"';
}
} else {
$value = '';
if ($value instanceof DateTime) {
// If value was valid, it's a DateTime object
$value = $this->formatDate($value, $attribs['local']);
}
// Build the element
$xhtml = '<div class="datetime' . (($jspicker === true) ? ' input-group' : ''). '">';
$xhtml .= '<input type="text" name="' . $name . '"'
. ' id="' . $name . '"'
. $value
. $disabled
. $this->_htmlAttribs($attribs);
if ($jspicker === true) {
$xhtml .= 'data-icinga-component="app/datetime"';
$min = '';
if (! empty($attribs['min'])) {
$min = sprintf(' min="%s"', $this->formatDate($attribs['min'], $attribs['local']));
}
$xhtml .= $this->getClosingBracket();
if ($jspicker === true) {
$xhtml .= '<span class="input-group-addon">'
. '<a href="#">'
. '<i class="icinga-icon-reschedule"></i>'
. '</a>'
. '</span>';
unset($attribs['min']); // Unset min to not render it again in $this->_htmlAttribs($attribs)
$max = '';
if (! empty($attribs['max'])) {
$max = sprintf(' max="%s"', $this->formatDate($attribs['max'], $attribs['local']));
}
$xhtml .= '</div>';
return $xhtml;
unset($attribs['max']); // Unset max to not render it again in $this->_htmlAttribs($attribs)
$type = $attribs['local'] === true ? 'datetime-local' : 'datetime';
unset($attribs['local']); // Unset local to not render it again in $this->_htmlAttribs($attribs)
$html5 = sprintf(
'<input type="%s" name="%s" id="%s" value="%s"%s%s%s%s%s',
$type,
$this->view->escape($name),
$this->view->escape($id),
$this->view->escape($value),
$min,
$max,
$disabled,
$this->_htmlAttribs($attribs),
$this->getClosingBracket()
);
return $html5;
}
}

View File

@ -2,29 +2,79 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use \Zend_View_Helper_FormElement;
/**
* Helper to generate a number input
* Render number input controls
*/
class Zend_View_Helper_FormNumber extends \Zend_View_Helper_FormText
class Zend_View_Helper_FormNumber extends Zend_View_Helper_FormElement
{
/**
* Generates a html number input
* Format a number
*
* @access public
* @param $number
*
* @param string $name The element name.
* @param string $value The default value.
* @param array $attribs Attributes which should be added to the input tag.
* @return string
*/
public function formatNumber($number)
{
if (empty($number)) {
return $number;
}
return $this->view->escape(
sprintf(
ctype_digit((string) $number) ? '%d' : '%F',
$number
)
);
}
/**
* Render the number input control
*
* @return string The input tag and options XHTML.
* @param string $name
* @param int $value
* @param array $attribs
*
* @return string The rendered number input control
*/
public function formNumber($name, $value = null, $attribs = null)
{
return '<input type="number"'
. ' name="' . $this->view->escape($name) . '"'
. ' value="' . $this->view->escape($value) . '"'
. ' id="' . $this->view->escape($name) . '"'
. $this->_htmlAttribs($attribs)
. $this->getClosingBracket();
$info = $this->_getInfo($name, $value, $attribs);
extract($info); // name, id, value, attribs, options, listsep, disable
/** @var string $id */
/** @var bool $disable */
$disabled = '';
if ($disable) {
$disabled = ' disabled="disabled"';
}
$min = '';
if (isset($attribs['min'])) {
$min = sprintf(' min="%s"', $this->formatNumber($attribs['min']));
}
unset($attribs['min']); // Unset min to not render it again in $this->_htmlAttribs($attribs)
$max = '';
if (isset($attribs['max'])) {
$max = sprintf(' max="%s"', $this->formatNumber($attribs['max']));
}
unset($attribs['max']); // Unset max to not render it again in $this->_htmlAttribs($attribs)
$step = '';
if (isset($attribs['step'])) {
$step = sprintf(' step="%s"', $attribs['step'] === 'any' ? 'any' : $this->formatNumber($attribs['step']));
}
unset($attribs['step']); // Unset step to not render it again in $this->_htmlAttribs($attribs)
$html5 = sprintf(
'<input type="number" name="%s" id="%s" value="%s"%s%s%s%s%s%s',
$this->view->escape($name),
$this->view->escape($id),
$this->view->escape($this->formatNumber($value)),
$min,
$max,
$step,
$disabled,
$this->_htmlAttribs($attribs),
$this->getClosingBracket()
);
return $html5;
}
}

View File

@ -64,6 +64,9 @@ class Zend_View_Helper_Util extends Zend_View_Helper_Abstract
return date('H:i d.m.Y', $timestamp);
}
/**
* @deprecated Not used. This is monitoring module stuff.
*/
public static function getHostStateClassName($state)
{
$class = 'unknown';
@ -82,6 +85,9 @@ class Zend_View_Helper_Util extends Zend_View_Helper_Abstract
return $class;
}
/**
* @deprecated Crap. This is monitoring module stuff.
*/
public static function getHostStateName($state)
{
$states = array(
@ -98,6 +104,9 @@ class Zend_View_Helper_Util extends Zend_View_Helper_Abstract
return sprintf('OUT OF BOUNDS (%s)', var_export($state, 1));
}
/**
* @deprecated Crap. This is monitoring module stuff.
*/
public static function getServiceStateName($state)
{
if ($state === null) { $state = 3; } // really?

View File

@ -1,45 +0,0 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content" data-base-target="_next">
<?php
if (isset($this->messageBox)) {
// TODO: Get rid of such boxes -> notifications?
echo $this->messageBox->render();
}
?>
<p>
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'ldap')) ?>"><?= $this->icon('create.png'); ?> Create A New LDAP Authentication Backend</a>
<br />
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'db')) ?>"><?= $this->icon('create.png'); ?> Create A New DB Authentication Backend</a>
</p>
<table class="action">
<thead>
<th>Resource</th>
<th style="width: 5em">Remove</th>
<th style="width: 5em">Order</th>
</thead>
<tbody>
<?php foreach ($this->backends as $backend): ?>
<tr>
<td class="action">
<a href="<?= $this->href('config/editAuthenticationBackend', array('auth_backend' => $backend->name)) ?>">
<?= $this->icon('edit.png') ?> <?= $this->escape($backend->name); ?>
</a>
</td>
<td>
<a href="<?= $this->href('config/removeAuthenticationBackend', array('auth_backend' => $backend->name)) ?>">
<?= $this->icon('remove.png', 'Remove') ?>
</a>
</td>
<td>
<?= $backend->reorderForm; ?>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>

View File

@ -1,15 +1,7 @@
<h4>
<i class="icinga-icon-create"></i>
Create New Authentication Backend
</h4>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<h4><?= $this->translate('Create New Authentication Backend'); ?></h4>
<p>
Create a new backend for authenticating your users. This backend will be added at the end of your authentication order.
<?= $this->translate(
'Create a new backend for authenticating your users. This backend will be added at the end of your authentication order.'
); ?>
</p>
<?= $this->form ?>
<?= $form; ?>

View File

@ -1,18 +1,2 @@
<h4>
<i class="icinga-icon-edit"></i>
Edit Backend "<?= $this->escape($this->name); ?>"
</h4>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<?php if ($this->form->getErrorMessages()): ?>
<div>
<?php foreach ($this->form->getErrorMessages() as $error): ?>
<?= $this->escape($error); ?><br/>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?= $this->form ?>
<h4><?= $this->translate('Edit Backend'); ?></h4>
<?= $form; ?>

View File

@ -1,10 +1,2 @@
<h4>
<i class="icinga-icon-remove"></i>
Remove Backend "<?= $this->escape($this->name); ?>"
</h4>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<?= $this->form ?>
<h4><?= $this->translate('Remove Backend'); ?></h4>
<?= $form; ?>

View File

@ -0,0 +1,11 @@
<div class="controls">
<?= $tabs; ?>
</div>
<div class="content" data-base-target="_next">
<p>
<a href="<?= $this->href('/config/createAuthenticationBackend'); ?>">
<?= $this->icon('create.png'); ?><?= $this->translate('Create A New Authentication Backend'); ?>
</a>
</p>
<?= $form; ?>
</div>

View File

@ -1,30 +1,32 @@
<div class="controls">
<?= $this->tabs ?>
<?= $tabs; ?>
</div>
<div class="content" data-base-target="_next">
<?php
if (isset($this->messageBox)) {
// TODO: Get rid of messageBoxes in favour of notifications
echo $this->messageBox->render();
}
?>
<p><a href="<?= $this->href('/config/createresource') ?>"><?= $this->icon('create.png'); ?> Create A New Resource</a></p>
<table class="action">
<thead>
<th>Resource</th>
<th style="width: 5em">Remove</th>
</thead>
<tbody>
<p>
<a href="<?= $this->href('/config/createresource'); ?>">
<?= $this->icon('create.png'); ?> <?= $this->translate('Create A New Resource'); ?>
</a>
</p>
<table class="action">
<thead>
<th><?= $this->translate('Resource'); ?></th>
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
</thead>
<tbody>
<?php foreach ($this->resources as $name => $resource): ?>
<tr>
<td><a href="<?= $this->href('config/editresource', array('resource' => $name)) ?>"><?= $this->icon('edit.png') ?> <?= $this->escape($name); ?></td>
<td style="text-align: center"><a href="<?= $this->href('config/removeresource', array('resource' => $name)) ?>"><?= $this->icon('remove.png'); ?></a></td>
</tr>
<tr>
<td>
<a href="<?= $this->href('config/editresource', array('resource' => $name)); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($name); ?>
</a>
</td>
<td style="text-align: center">
<a href="<?= $this->href('config/removeresource', array('resource' => $name)); ?>">
<?= $this->icon('remove.png'); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
</tbody>
</table>
</div>

View File

@ -1,14 +1,3 @@
<h4>
<i class="icinga-icon-create"></i>
Create New Resource
</h4>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<p>
Resources are entities that provide data to Icingaweb.
</p>
<?= $this->form ?>
<h4><?= $this->translate('Create A New Resource'); ?></h4>
<p><?= $this->translate('Resources are entities that provide data to Icinga Web 2.'); ?></p>
<?= $form; ?>

View File

@ -1,18 +1,2 @@
<h4>
<i class="icinga-icon-edit"></i>
Edit Resource "<?= $this->escape($this->name); ?>"
</h4>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<?php if ($this->form->getErrorMessages()): ?>
<div>
<?php foreach ($this->form->getErrorMessages() as $error): ?>
<?= $this->escape($error); ?><br/>
<?php endforeach; ?>
</div>
<?php endif ?>
<?= $this->form ?>
<h4><?= $this->translate('Edit Existing Resource'); ?></h4>
<?= $form; ?>

View File

@ -1,10 +1,2 @@
<h4>
<i class="icinga-icon-remove"></i>
Remove Resource "<?= $this->escape($this->name); ?>"
</h4>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<?= $this->form ?>
<h4><?= $this->translate('Remove Existing Resource'); ?></h4>
<?= $form; ?>

View File

@ -1,31 +0,0 @@
<?= $this->tabs->render($this); ?>
<br/>
<div>
<h4><i>WARNING ICON</i>Saving "<?= $this->escape($this->file); ?>.ini" Failed</h4>
<br/>
<p>
Your <?= $this->escape($this->file); ?> configuration couldn't be stored (error: "<?= $this->exceptionMessage; ?>").<br/>
This could have one or more of the following reasons:
</p>
<ul>
<li>You don't have file-system permissions to write to the <?= $this->escape($this->file); ?>.ini file</li>
<li>Something went wrong while writing the file</li>
<li>There's an application error preventing you from persisting the configuration</li>
</ul>
</div>
<p>
Details can be seen in your application log (if you don't have access to this file, call your administrator in this case).
<br/>
In case you can access the configuration file (config/<?= $this->escape($this->file); ?>.ini) by yourself, you can open it and
insert the config manually:
</p>
<p>
<pre>
<code>
<?= $this->escape($this->iniConfigurationString); ?>
</code>
</pre>
</p>

View File

@ -11,7 +11,4 @@
<hr />
<pre><?= $this->escape($stackTrace) ?></pre>
<?php endif ?>
<?php if (isset($this->messageBox)) : ?>
<?= $this->messageBox->render(); ?>
<? endif ?>
</div>

View File

@ -0,0 +1,40 @@
<form id="<?= $form->getName(); ?>" name="<?= $form->getName(); ?>" enctype="<?= $form->getEncType(); ?>" method="<?= $form->getMethod(); ?>">
<table class="action">
<thead>
<th>Backend</th>
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
<th style="width: 5em"><?= $this->translate('Order'); ?></th>
</thead>
<tbody>
<?php $backendNames = $form->getBackendOrder(); ?>
<?php for ($i = 0; $i < count($backendNames); $i++): ?>
<tr>
<td class="action">
<a href="<?= $this->href('config/editAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($backendNames[$i]); ?>
</a>
</td>
<td>
<a href="<?= $this->href('config/removeAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
<?= $this->icon('remove.png', $this->translate('Remove')); ?>
</a>
</td>
<td>
<?php if ($i > 0): ?>
<button type="submit" name="backend_newpos" value="<?= sprintf('%s|%s', $backendNames[$i], $i - 1); ?>">
<?= $this->icon('up.png', $this->translate('Move up in authentication order')); ?>
</button>
<?php endif; ?>
<?php if ($i + 1 < count($backendNames)): ?>
<button type="submit" name="backend_newpos" value="<?= sprintf('%s|%s', $backendNames[$i], $i + 1); ?>">
<?= $this->icon('down.png', $this->translate('Move down in authentication order')); ?>
</button>
<?php endif; ?>
</td>
</tr>
<?php endfor; ?>
</tbody>
</table>
<?= $form->getElement($form->getTokenElementName()); ?>
<?= $form->getElement($form->getUidElementName()); ?>
</form>

View File

@ -1,7 +1,7 @@
<div class="controls">
<?= $this->tabs->render($this); ?>
<?= $tabs; ?>
</div>
<div class="content">
<?= $this->form ?>
</div>
<?= $form; ?>
</div>

View File

@ -0,0 +1,28 @@
<div>
<h4><?= $this->translate('Saving Configuration Failed'); ?></h4>
<br>
<p>
<?= sprintf(
$this->translate('The file %s couldn\'t be stored. (Error: "%s")'),
$this->escape($filePath),
$this->escape($errorMessage)
); ?>
<br>
<?= $this->translate('This could have one or more of the following reasons:'); ?>
</p>
<ul>
<li><?= $this->translate('You don\'t have file-system permissions to write to the file'); ?></li>
<li><?= $this->translate('Something went wrong while writing the file'); ?></li>
<li><?= $this->translate('There\'s an application error preventing you from persisting the configuration'); ?></li>
</ul>
</div>
<p>
<?= $this->translate('Details can be found in the application log. (If you don\'t have access to this log, call your administrator in this case)'); ?>
<br>
<?= $this->translate('In case you can access the file by yourself, you can open it and insert the config manually:'); ?>
</p>
<p>
<pre>
<code><?= $this->escape($configString); ?></code>
</pre>
</p>

View File

@ -383,7 +383,7 @@ abstract class ApplicationBootstrap
*/
protected function setupErrorHandling()
{
error_reporting(E_ALL | E_NOTICE);
error_reporting(E_ALL | E_STRICT);
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
return $this;

View File

@ -7,7 +7,6 @@ namespace Icinga\Application;
use Zend_Config;
use Zend_Config_Ini;
use Icinga\Exception\NotReadableError;
use Icinga\Exception\ProgrammingError;
/**
* Global registry of application and module configuration.
@ -22,11 +21,11 @@ class Config extends Zend_Config
public static $configDir;
/**
* The INI file this configuration has been loaded from
* The INI file this configuration has been loaded from or should be written to
*
* @var string
*/
private $configFile;
protected $configFile;
/**
* Application config instances per file
@ -42,30 +41,28 @@ class Config extends Zend_Config
*/
protected static $modules = array();
private $instance;
/**
* Load configuration from the config file $filename
* Load configuration from the given INI file
*
* @param string $file The file to parse
*
* @param string $filename The filename to parse
* @throws NotReadableError When the file does not exist or cannot be read
*/
public function __construct($filename)
public static function fromIni($file)
{
parent::__construct(array(), true);
$filepath = realpath($filename);
$config = new static(array(), true);
$filepath = realpath($file);
if ($filepath === false) {
$this->configFile = $filename;
$config->setConfigFile($file);
} elseif (is_readable($filepath)) {
$this->configFile = $filepath;
$this->merge(new Zend_Config_Ini($filepath));
$config->setConfigFile($filepath);
$config->merge(new Zend_Config_Ini($filepath));
} else {
throw new NotReadableError(
'Cannot read config file "%s". Permission denied',
$filename
);
throw new NotReadableError('Cannot read config file "%s". Permission denied', $filepath);
}
return $config;
}
/**
@ -80,7 +77,7 @@ class Config extends Zend_Config
public static function app($configname = 'config', $fromDisk = false)
{
if (!isset(self::$app[$configname]) || $fromDisk) {
self::$app[$configname] = new Config(self::resolvePath($configname . '.ini'));
self::$app[$configname] = Config::fromIni(self::resolvePath($configname . '.ini'));
}
return self::$app[$configname];
}
@ -113,7 +110,7 @@ class Config extends Zend_Config
}
$moduleConfigs = self::$modules[$modulename];
if (!isset($moduleConfigs[$configname]) || $fromDisk) {
$moduleConfigs[$configname] = new Config(
$moduleConfigs[$configname] = Config::fromIni(
self::resolvePath('modules/' . $modulename . '/' . $configname . '.ini')
);
}
@ -138,15 +135,28 @@ class Config extends Zend_Config
}
/**
* Return the application wide config file
* Return this config's file path
*
* @return string
* @return string
*/
public function getConfigFile()
{
return $this->configFile;
}
/**
* Set this config's file path
*
* @param string $filepath The path to the config file
*
* @return self
*/
public function setConfigFile($filepath)
{
$this->configFile = $filepath;
return $this;
}
/**
* Prepend configuration base dir if input is relative
*

View File

@ -223,7 +223,7 @@ class DbQuery extends SimpleQuery
*/
public function isTimestamp($field)
{
return $this;
return false;
}
public function whereToSql($col, $sign, $expression)

View File

@ -0,0 +1,10 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Exception;
/**
* Exception thrown if a property does not exist
*/
class InvalidPropertyException extends IcingaException {}

View File

@ -6,6 +6,7 @@ namespace Icinga\Logger;
use Exception;
use Zend_Config;
use LogicException;
use Icinga\Exception\ConfigurationError;
/**
@ -44,10 +45,11 @@ class Logger
/**
* The supported severities
*/
public static $ERROR = 0;
public static $WARNING = 1;
public static $INFO = 2;
public static $DEBUG = 3;
public static $NONE = 0;
public static $ERROR = 1;
public static $WARNING = 2;
public static $INFO = 3;
public static $DEBUG = 4;
/**
* Create a new logger object
@ -100,9 +102,15 @@ class Logger
*
* @param string $message The message to write
* @param int $severity The severity to use
*
* @throws LogicException In case $severity equals self::$NONE
*/
public function log($message, $severity)
{
if ($severity === static::$NONE) {
throw new LogicException("`None' (0) is not a valid severity to log messages");
}
if ($this->writer !== null && $this->verbosity >= $severity) {
$this->writer->log($severity, $message);
}

View File

@ -1,177 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe;
use Icinga\Exception\ProgrammingError;
/**
* Base class for any concrete command implementation
*/
abstract class Command
{
/**
* Whether hosts are ignored in case of a host- or servicegroup
*
* @var bool
*/
protected $withoutHosts = false;
/**
* Whether services are ignored in case of a host- or servicegroup
*
* @var bool
*/
protected $withoutServices = false;
/**
* Whether child hosts are going to be included in case of a host command
*
* @var bool
*/
protected $withChildren = false;
/**
* Whether only services are going to be included in case of a host command
*
* @var bool
*/
protected $onlyServices = false;
/**
* Whether it is a global command or not
*
* @var bool
*/
protected $globalCommand = false;
/**
* Set whether this command should only affect the services of a host- or servicegroup
*
* @param bool $state
* @return self
*/
public function excludeHosts($state = true)
{
$this->withoutHosts = (bool) $state;
return $this;
}
/**
* Set whether this command should only affect the hosts of a host- or servicegroup
*
* @param bool $state
* @return self
*/
public function excludeServices($state = true)
{
$this->withoutServices = (bool) $state;
return $this;
}
/**
* Set whether this command should also affect all children hosts of a host
*
* @param bool $state
* @return self
*/
public function includeChildren($state = true)
{
$this->withChildren = (bool) $state;
return $this;
}
/**
* Set whether this command only affects the services associated with a particular host
*
* @param bool $state
* @return self
*/
public function excludeHost($state = true)
{
$this->onlyServices = (bool) $state;
return $this;
}
/**
* Getter for flag whether a command is global
* @return bool
*/
public function provideGlobalCommand()
{
return (bool) $this->globalCommand;
}
/**
* Return this command's arguments in the order expected by the actual command definition
*
* @return array
*/
abstract public function getArguments();
/**
* Return the command as a string with the given host being inserted
*
* @param string $hostname The name of the host to insert
*
* @return string The string representation of the command
*/
abstract public function getHostCommand($hostname);
/**
* Return the command as a string with the given host and service being inserted
*
* @param string $hostname The name of the host to insert
* @param string $servicename The name of the service to insert
*
* @return string The string representation of the command
*/
abstract public function getServiceCommand($hostname, $servicename);
/**
* Return the command as a string with the given hostgroup being inserted
*
* @param string $hostgroup The name of the hostgroup to insert
*
* @return string The string representation of the command
*/
public function getHostgroupCommand($hostgroup)
{
throw new ProgrammingError(
'%s does not provide a hostgroup command',
get_class($this)
);
}
/**
* Return the command as a string with the given servicegroup being inserted
*
* @param string $servicegroup The name of the servicegroup to insert
*
* @return string The string representation of the command
*/
public function getServicegroupCommand($servicegroup)
{
throw new ProgrammingError(
'%s does not provide a servicegroup command',
get_class($this)
);
}
/**
* Return the command as a string for the whole instance
*
* @param string $instance
*
* @return string
* @throws ProgrammingError
*/
public function getGlobalCommand($instance = null)
{
throw new ProgrammingError(
'%s does not provide a global command',
getclass($this)
);
}
}

View File

@ -1,603 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe;
use Icinga\Protocol\Commandpipe\Transport\Transport;
use Icinga\Protocol\Commandpipe\Transport\LocalPipe;
use Icinga\Protocol\Commandpipe\Transport\SecureShell;
/**
* Class to the access icinga CommandPipe via a @see Icinga\Protocol\Commandpipe\Transport.php
*
* Will be configured using the instances.ini
*/
class CommandPipe
{
/**
* The name of this class as defined in the instances.ini
*
* @var string
*/
private $name = "";
/**
* The underlying @see Icinga\Protocol\Commandpipe\Transport.php class handling communication with icinga
*
* @var Icinga\Protocol\Commandpipe\Transport
*/
private $transport = null;
/**
* Constant identifying a monitoring object as host
*/
const TYPE_HOST = "HOST";
/**
* Constant identifying a monitoring object as service
*/
const TYPE_SERVICE = "SVC";
/**
* Constant identifying a monitoring object as hostgroup
*/
const TYPE_HOSTGROUP = "HOSTGROUP";
/**
* Constant identifying a monitoring object as servicegroups
*/
const TYPE_SERVICEGROUP = "SERVICEGROUP";
/**
* Notification option (use logical OR for combination)
*
* Broadcast (send notification to all normal and all escalated contacts for the service)
*/
const NOTIFY_BROADCAST = 1;
/**
* Notification option (use logical OR for combination)
*
* notification is sent out regardless of current time, whether or not notifications are enabled, etc.
*/
const NOTIFY_FORCED = 2;
/**
* Notification option (use logical OR for combination)
*
* Increment current notification # for the service(this is not done by default for custom notifications)
*/
const NOTIFY_INCREMENT = 4;
/**
* Create a new CommandPipe class which accesses the icinga.cmd pipe as defined in $config
*
* @param \Zend_Config $config
*/
public function __construct(\Zend_Config $config)
{
$this->getTransportForConfiguration($config);
$this->name = $config->name;
}
/**
* Setup the @see Icinga\Protocol\Commandpipe\Transport.php class that will be used for accessing the command pipe
*
* Currently this method uses SecureShell when a host is given, otherwise it assumes the pipe is accessible
* via the machines filesystem
*
* @param \Zend_Config $config The configuration as defined in the instances.ini
*/
private function getTransportForConfiguration(\Zend_Config $config)
{
if (isset($config->host)) {
$this->transport = new SecureShell();
$this->transport->setEndpoint($config);
} else {
$this->transport = new LocalPipe();
$this->transport->setEndpoint($config);
}
}
/**
* Send the command string $command to the icinga pipe
*
* This method just delegates the send command to the underlying transport
*
* @param String $command The command string to send, without the timestamp
*/
public function send($command)
{
$this->transport->send($this->escape($command));
}
/**
* Return the given command string with escaped newlines
*
* @param string $command The command string to escape
*
* @return string The escaped command string
*/
public function escape($command)
{
return str_replace(array("\r", "\n"), array('\r', '\n'), $command);
}
/**
* Send a command to the icinga pipe
*
* @param Command $command
* @param array $objects
*/
public function sendCommand(Command $command, array $objects = array())
{
if ($command->provideGlobalCommand() === true) {
$this->send($command->getGlobalCommand());
} else {
foreach ($objects as $object) {
$objectType = $this->getObjectType($object);
if ($objectType === self::TYPE_SERVICE) {
$this->send($command->getServiceCommand($object->host_name, $object->service_description));
} else {
$this->send($command->getHostCommand($object->host_name));
}
}
}
}
/**
* Remove the acknowledgements of the provided objects
*
* @param array $objects An array of mixed service and host objects whose acknowledgments will be removed
*/
public function removeAcknowledge($objects)
{
foreach ($objects as $object) {
if (isset($object->service_description)) {
$this->send("REMOVE_SVC_ACKNOWLEDGEMENT;$object->host_name;$object->service_description");
} else {
$this->send("REMOVE_HOST_ACKNOWLEDGEMENT;$object->host_name");
}
}
}
/**
* Removes the submitted comments
*
* @param array $objectsOrComments An array of hosts and services (to remove all their comments)
* or single comment objects to remove
*/
public function removeComment($objectsOrComments)
{
foreach ($objectsOrComments as $object) {
if (isset($object->comment_id)) {
if (isset($object->service_description)) {
$type = "SERVICE_COMMENT";
} else {
$type = "HOST_COMMENT";
}
$this->send("DEL_{$type};" . intval($object->comment_id));
} else {
if (isset($object->service_description)) {
$type = "SERVICE_COMMENT";
} else {
$type = "HOST_COMMENT";
}
$cmd = "DEL_ALL_{$type}S;" . $object->host_name;
if ($type == "SERVICE_COMMENT") {
$cmd .= ";" . $object->service_description;
}
$this->send($cmd);
}
}
}
/**
* Globally enable notifications for this instance
*
*/
public function enableGlobalNotifications()
{
$this->send("ENABLE_NOTIFICATIONS");
}
/**
* Globally disable notifications for this instance
*
*/
public function disableGlobalNotifications()
{
$this->send("DISABLE_NOTIFICATIONS");
}
/**
* Return the object type of the provided object (TYPE_SERVICE or TYPE_HOST)
*
* @param $object The object to identify
* @return string TYPE_SERVICE or TYPE_HOST
*/
private function getObjectType($object)
{
//@TODO: This must be refactored once more commands are supported
if (isset($object->service_description)) {
return self::TYPE_SERVICE;
}
return self::TYPE_HOST;
}
/**
* Remove downtimes for objects
*
* @param array $objects An array containing hosts, service or downtime objects
* @param int $starttime An optional starttime to use for the DEL_DOWNTIME_BY_HOST_NAME command
*/
public function removeDowntime($objects, $starttime = 0)
{
foreach ($objects as $object) {
$type = $this->getObjectType($object);
if (isset($object->downtime_id)) {
$this->send("DEL_" . $type . "_DOWNTIME;" . $object->downtime_id);
continue;
}
$cmd = "DEL_DOWNTIME_BY_HOST_NAME;" . $object->host_name;
if ($type == self::TYPE_SERVICE) {
$cmd .= ";" . $object->service_description;
}
if ($starttime != 0) {
$cmd .= ";" . $starttime;
}
$this->send($cmd);
}
}
/**
* Restart the icinga instance
*
*/
public function restartIcinga()
{
$this->send("RESTART_PROCESS");
}
/**
* Modify monitoring flags for the provided objects
*
* @param array $objects An arry of service and/or host objects to modify
* @param PropertyModifier $flags The Monitoring attributes to modify
*/
public function setMonitoringProperties($objects, PropertyModifier $flags)
{
foreach ($objects as $object) {
$type = $this->getObjectType($object);
$formatArray = $flags->getFormatString($type);
foreach ($formatArray as $format) {
$format .= ";"
. $object->host_name
. ($type == self::TYPE_SERVICE ? ";" . $object->service_description : "");
$this->send($format);
}
}
}
/**
* Enable active checks for all provided objects
*
* @param array $objects An array containing services and hosts to enable active checks for
*/
public function enableActiveChecks($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::ACTIVE => PropertyModifier::STATE_ENABLE
)
)
);
}
/**
* Disable active checks for all provided objects
*
* @param array $objects An array containing services and hosts to disable active checks
*/
public function disableActiveChecks($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::ACTIVE => PropertyModifier::STATE_DISABLE
)
)
);
}
/**
* Enable passive checks for all provided objects
*
* @param array $objects An array containing services and hosts to enable passive checks for
*/
public function enablePassiveChecks($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::PASSIVE => PropertyModifier::STATE_ENABLE
)
)
);
}
/**
* Enable passive checks for all provided objects
*
* @param array $objects An array containing services and hosts to enable passive checks for
*/
public function disablePassiveChecks($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::PASSIVE => PropertyModifier::STATE_DISABLE
)
)
);
}
/**
* Enable flap detection for all provided objects
*
* @param array $objects An array containing services and hosts to enable flap detection
*
*/
public function enableFlappingDetection($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::FLAPPING => PropertyModifier::STATE_ENABLE
)
)
);
}
/**
* Disable flap detection for all provided objects
*
* @param array $objects An array containing services and hosts to disable flap detection
*
*/
public function disableFlappingDetection($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::FLAPPING => PropertyModifier::STATE_DISABLE
)
)
);
}
/**
* Enable notifications for all provided objects
*
* @param array $objects An array containing services and hosts to enable notification
*
*/
public function enableNotifications($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::NOTIFICATIONS => PropertyModifier::STATE_ENABLE
)
)
);
}
/**
* Disable flap detection for all provided objects
*
* @param array $objects An array containing services and hosts to disable notifications
*
*/
public function disableNotifications($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::NOTIFICATIONS => PropertyModifier::STATE_DISABLE
)
)
);
}
/**
* Enable freshness checks for all provided objects
*
* @param array $objects An array of hosts and/or services
*/
public function enableFreshnessChecks($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::FRESHNESS => PropertyModifier::STATE_ENABLE
)
)
);
}
/**
* Disable freshness checks for all provided objects
*
* @param array $objects An array of hosts and/or services
*/
public function disableFreshnessChecks($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::FRESHNESS => PropertyModifier::STATE_DISABLE
)
)
);
}
/**
* Enable event handler for all provided objects
*
* @param array $objects An array of hosts and/or services
*/
public function enableEventHandler($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::EVENTHANDLER => PropertyModifier::STATE_ENABLE
)
)
);
}
/**
* Disable event handler for all provided objects
*
* @param array $objects An array of hosts and/or services
*/
public function disableEventHandler($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::EVENTHANDLER => PropertyModifier::STATE_DISABLE
)
)
);
}
/**
* Enable performance data parsing for all provided objects
*
* @param array $objects An array of hosts and/or services
*/
public function enablePerfdata($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::PERFDATA => PropertyModifier::STATE_ENABLE
)
)
);
}
/**
* Disable performance data parsing for all provided objects
*
* @param array $objects An array of hosts and/or services
*/
public function disablePerfdata($objects)
{
$this->setMonitoringProperties(
$objects,
new PropertyModifier(
array(
PropertyModifier::PERFDATA => PropertyModifier::STATE_DISABLE
)
)
);
}
/**
* Disable notifications for all services of the provided hosts
*
* @param array $objects An array of hosts
*/
public function disableNotificationsForServices($objects)
{
foreach ($objects as $host) {
$msg = 'DISABLE_HOST_SVC_NOTIFICATIONS;'.$host->host_name;
$this->send($msg);
}
}
/**
* Enable notifications for all services of the provided hosts
*
* @param array $objects An array of hosts
*/
public function enableNotificationsForServices($objects)
{
foreach ($objects as $host) {
$msg = 'ENABLE_HOST_SVC_NOTIFICATIONS;'.$host->host_name;
$this->send($msg);
}
}
/**
* Disable active checks for all services of the provided hosts
*
* @param array $objects An array of hosts
*/
public function disableActiveChecksWithChildren($objects)
{
foreach ($objects as $host) {
$msg = 'DISABLE_HOST_SVC_CHECKS;'.$host->host_name;
$this->send($msg);
}
}
/**
* Enable active checks for all services of the provided hosts
*
* @param array $objects An array of hosts
*/
public function enableActiveChecksWithChildren($objects)
{
foreach ($objects as $host) {
$msg = 'ENABLE_HOST_SVC_CHECKS;'.$host->host_name;
$this->send($msg);
}
}
/**
* Reset modified attributes for all provided objects
*
* @param array $objects An array of hosts and services
*/
public function resetAttributes($objects)
{
foreach ($objects as $object) {
$type = $this->getObjectType($object);
if ($type === self::TYPE_SERVICE) {
$this->send('CHANGE_SVC_MODATTR;'.$object->host_name.';'.$object->service_description.';0');
} else {
$this->send('CHANGE_HOST_MODATTR;'.$object->host_name.';0');
}
}
}
/**
* Return the transport handler that handles actual sending of commands
*
* @return Transport
*/
public function getTransport()
{
return $this->transport;
}
}

View File

@ -1,61 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe;
/**
* Container for comment information that can be send to Icinga's external command pipe
*/
class Comment
{
/**
* Whether this comment is persistent or not
*
* @var bool
*/
public $persistent;
/**
* The author of this comment
*
* @var string
*/
public $author;
/**
* The text of this comment
*
* @var string
*/
public $content;
/**
* Create a new comment object
*
* @param string $author The name of the comment's author
* @param string $content The text for this comment
* @param bool $persistent Whether this comment should be persistent or not
*/
public function __construct($author, $content, $persistent = false)
{
$this->author = $author;
$this->content = $content;
$this->persistent = $persistent;
}
/**
* Return this comment's properties as list of command parameters
*
* @param bool $ignorePersistentFlag Whether the persistent flag should be included or not
* @return array
*/
public function getArguments($ignorePersistentFlag = false)
{
if ($ignorePersistentFlag) {
return array($this->author, $this->content);
} else {
return array($this->persistent ? '1' : '0', $this->author, $this->content);
}
}
}

View File

@ -1,12 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe\Exception;
/**
* Exception class for unknown/invalid external commands
*/
class InvalidCommandException extends \Exception
{
}

View File

@ -1,110 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe;
/**
* Container class to modify a few monitoring attributes at oncee
*
*/
class PropertyModifier
{
/**
* Set an attribute to be enabled in the command
*/
const STATE_ENABLE = 1;
/**
* Set an attribute to be disabled in the command
*/
const STATE_DISABLE = 0;
/**
* Set an attribute to not be modified in the command
*/
const STATE_KEEP = -1;
/**
* Template for enabling/disabling flap detection
*/
const FLAPPING = "%s_FLAP_DETECTION";
/**
* Template for enabling/disabling active checks
*/
const ACTIVE = "%s_CHECK";
/**
* Template for enabling/disabling passive checks
*/
const PASSIVE = "PASSIVE_%s_CHECKS";
/**
* Template for enabling/disabling notification
*/
const NOTIFICATIONS = "%s_NOTIFICATIONS";
/**
* Template for enabling/disabling freshness checks
*/
const FRESHNESS = "%s_FRESHNESS_CHECKS";
/**
* Template for enabling/disabling event handler
*/
const EVENTHANDLER = "%s_EVENT_HANDLER";
/**
* The state that will be applied when fetching this container for an object
*
* @var array
*/
private $flags = array(
self::FLAPPING => self::STATE_KEEP,
self::ACTIVE => self::STATE_KEEP,
self::PASSIVE => self::STATE_KEEP,
self::NOTIFICATIONS => self::STATE_KEEP,
self::FRESHNESS => self::STATE_KEEP,
self::EVENTHANDLER => self::STATE_KEEP
);
/**
* Create a new PropertyModified object using the given flags
*
* @param array $flags Flags to enable/disable/keep different monitoring attributes
*/
public function __construct(array $flags)
{
foreach ($flags as $type => $value) {
if (isset($this->flags[$type])) {
$this->flags[$type] = $value;
}
}
}
/**
* Return this object as a template for the given object type
*
* @param $type Either CommandPipe::TYPE_HOST or CommandPipe::TYPE_SERVICE
* @return array An array of external command templates for the given type representing the containers state
*/
public function getFormatString($type)
{
$cmd = array();
foreach ($this->flags as $cmdTemplate => $setting) {
if ($setting == self::STATE_KEEP) {
continue;
}
$commandString = ($setting == self::STATE_ENABLE ? "ENABLE_" : "DISABLE_");
$targetString = $type;
if ($type == CommandPipe::TYPE_SERVICE && $cmdTemplate == self::FRESHNESS) {
// the external command definition is inconsistent here..
$targetString = "SERVICE";
}
$commandString .= sprintf($cmdTemplate, $targetString);
$cmd[] = $commandString;
}
return $cmd;
}
}

View File

@ -1,70 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe\Transport;
use Exception;
use Icinga\Util\File;
use Icinga\Logger\Logger;
use Icinga\Exception\ConfigurationError;
/**
* CommandPipe Transport class that writes to a file accessible by the filesystem
*/
class LocalPipe implements Transport
{
/**
* The path of the icinga commandpipe
*
* @var String
*/
private $path;
/**
* The mode to use to access the pipe
*
* @var string
*/
private $openMode = "wn";
/**
* @see Transport::setEndpoint()
*/
public function setEndpoint(\Zend_Config $config)
{
$this->path = isset($config->path) ? $config->path : '/usr/local/icinga/var/rw/icinga.cmd';
}
/**
* @see Transport::send()
*/
public function send($message)
{
Logger::debug('Attempting to send external icinga command %s to local command file ', $message, $this->path);
try {
$file = new File($this->path, $this->openMode);
$file->fwrite('[' . time() . '] ' . $message . PHP_EOL);
$file->fflush();
} catch (Exception $e) {
throw new ConfigurationError(
'Could not open icinga command pipe at "%s" (%s)',
$this->path,
$e->getMessage()
);
}
Logger::debug('Command sent: [' . time() . '] ' . $message . PHP_EOL);
}
/**
* Overwrite the open mode (useful for testing)
*
* @param string $mode The mode to use to access the pipe
*/
public function setOpenMode($mode)
{
$this->openMode = $mode;
}
}

View File

@ -1,102 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe\Transport;
use RuntimeException;
use Zend_Config;
use Icinga\Logger\Logger;
/**
* Command pipe transport class that uses ssh for connecting to a remote filesystem with the icinga.cmd pipe
*
* The remote host must have KeyAuth enabled for this user
*/
class SecureShell implements Transport
{
/**
* The remote host to connect to
*
* @var string
*/
private $host = 'localhost';
/**
* The location of the icinga pipe on the remote host
*
* @var string
*/
private $path = "/usr/local/icinga/var/rw/icinga.cmd";
/**
* The SSH port of the remote host
*
* @var int
*/
private $port = 22;
/**
* The user to authenticate with on the remote host
*
* @var String
*/
private $user = null;
/**
* Overwrite the target file of this Transport class using the given config from instances.ini
*
* @param Zend_Config $config
*
* @see Transport::setEndpoint()
*/
public function setEndpoint(Zend_Config $config)
{
$this->host = isset($config->host) ? $config->host : 'localhost';
$this->port = isset($config->port) ? $config->port : 22;
$this->user = isset($config->user) ? $config->user : null;
$this->path = isset($config->path) ? $config->path : '/usr/local/icinga/var/rw/icinga.cmd';
}
/**
* Write the given external command to the command pipe
*
* @param string $command
*
* @throws RuntimeException When the command could not be sent to the remote Icinga host
* @see Transport::send()
*/
public function send($command)
{
$retCode = 0;
$output = array();
Logger::debug(
'Icinga instance is on different host, attempting to send command %s via ssh to %s:%s/%s',
$command,
$this->host,
$this->port,
$this->path
);
$hostConnector = $this->user ? $this->user . "@" . $this->host : $this->host;
$command = escapeshellarg('['. time() .'] ' . $command);
$sshCommand = sprintf(
'ssh -o BatchMode=yes -o KbdInteractiveAuthentication=no %s -p %d'
. ' "echo %s > %s" 2>&1',
$hostConnector,
$this->port,
$command,
$this->path
);
exec($sshCommand, $output, $retCode);
Logger::debug("Command '%s' exited with %d: %s", $sshCommand, $retCode, $output);
if ($retCode != 0) {
$msg = 'Could not send command to remote Icinga host: '
. implode(PHP_EOL, $output)
. " (returncode $retCode)";
Logger::error($msg);
throw new RuntimeException($msg);
}
}
}

View File

@ -1,27 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Protocol\Commandpipe\Transport;
use Zend_Config;
/**
* Interface for Transport classes handling the concrete access to the command pipe
*/
interface Transport
{
/**
* Overwrite the target file of this Transport class using the given config from instances.ini
*
* @param Zend_Config $config A configuration file containing a 'path' setting
*/
public function setEndpoint(Zend_Config $config);
/**
* Write the given external command to the command pipe
*
* @param string $message The command to send, without the timestamp (this will be added here)
*/
public function send($message);
}

View File

@ -25,20 +25,16 @@ namespace Icinga\Test {
use RuntimeException;
use Mockery;
use Zend_Config;
use Zend_Controller_Request_Abstract;
use Zend_Controller_Request_HttpTestCase;
use PHPUnit_Framework_TestCase;
use Icinga\Application\Icinga;
use Icinga\Util\DateTimeFactory;
use Icinga\Data\ResourceFactory;
use Icinga\Data\Db\DbConnection;
use Icinga\User\Preferences;
use Icinga\Web\Form;
/**
* Class BaseTestCase
*/
class BaseTestCase extends PHPUnit_Framework_TestCase implements DbTest, FormTest
class BaseTestCase extends PHPUnit_Framework_TestCase implements DbTest
{
/**
* Path to application/
@ -82,13 +78,6 @@ namespace Icinga\Test {
*/
public static $moduleDir;
/**
* Store request for form tests
*
* @var Zend_Controller_Request_HttpTestCase
*/
private $request;
/**
* Resource configuration for different database types
*
@ -151,28 +140,54 @@ namespace Icinga\Test {
public function setUp()
{
parent::setUp();
$requestMock = Mockery::mock('Icinga\Web\Request');
$requestMock->shouldReceive('getPathInfo')->andReturn('')
->shouldReceive('getBaseUrl')->andReturn('/')
->shouldReceive('getQuery')->andReturn(array());
$this->setupIcingaMock($requestMock);
$this->setupIcingaMock();
}
/**
* Setup mock object for the application's bootstrap
*
* @param Zend_Controller_Request_Abstract $request The request to be returned by
* Icinga::app()->getFrontController()->getRequest()
* @return Mockery\Mock
*/
protected function setupIcingaMock(Zend_Controller_Request_Abstract $request)
protected function setupIcingaMock()
{
$requestMock = Mockery::mock('Icinga\Web\Request')->shouldDeferMissing();
$requestMock->shouldReceive('getPathInfo')->andReturn('')->byDefault()
->shouldReceive('getBaseUrl')->andReturn('/')->byDefault()
->shouldReceive('getQuery')->andReturn(array())->byDefault()
->shouldReceive('getParam')->with(Mockery::type('string'), Mockery::type('string'))
->andReturnUsing(function ($name, $default) { return $default; })->byDefault();
$responseMock = Mockery::mock('Icinga\Web\Response')->shouldDeferMissing();
// Can't express this as demeter chains. See: https://github.com/padraic/mockery/issues/59
$bootstrapMock = Mockery::mock('Icinga\Application\ApplicationBootstrap')->shouldDeferMissing();
$bootstrapMock->shouldReceive('getFrontController->getRequest')->andReturnUsing(
function () use ($request) { return $request; }
)->shouldReceive('getApplicationDir')->andReturn(self::$appDir);
$bootstrapMock->shouldReceive('getFrontController')->andReturn($bootstrapMock)
->shouldReceive('getApplicationDir')->andReturn(self::$appDir)
->shouldReceive('getRequest')->andReturn($requestMock)
->shouldReceive('getResponse')->andReturn($responseMock);
Icinga::setApp($bootstrapMock, true);
return $bootstrapMock;
}
/**
* Return the currently active request mock object
*
* @return Icinga\Web\Request
*/
public function getRequestMock()
{
return Icinga::app()->getFrontController()->getRequest();
}
/**
* Return the currently active response mock object
*
* @return Icinga\Web\Response
*/
public function getResponseMock()
{
return Icinga::app()->getFrontController()->getResponse();
}
/**
@ -298,58 +313,6 @@ namespace Icinga\Test {
$adapter->exec('DROP TABLE ' . $table . ';');
}
}
/**
* Instantiate a form
*
* If the form has CSRF protection enabled, creates the form's token element and adds the generated token to the
* request data
*
* @param string $formClass Qualified class name of the form to create. Note that the class has to be
* defined as no attempt is made to require the class before instantiating.
* @param array $requestData Request data for the form
*
* @return Form
* @throws RuntimeException
*/
public function createForm($formClass, array $requestData = array())
{
$form = new $formClass;
// If the form has CSRF protection enabled, add the token to the request data, else all calls to
// isSubmittedAndValid will fail
$form->setSessionId('1234');
$form->initCsrfToken();
$token = $form->getValue($form->getTokenElementName());
if ($token !== null) {
$requestData[$form->getTokenElementName()] = $token;
}
$request = $this->getRequest();
$request->setMethod('POST');
$request->setPost($requestData);
$form->setRequest($request);
$form->setUserPreferences(
new Preferences(
array()
)
);
return $form;
}
/**
* Retrieve test case request object
*
* This is a mock methods borrowed from Zend Controller Test Case to handle form tests properly (#6106)
*
* @return Zend_Controller_Request_HttpTestCase
*/
public function getRequest()
{
if (null === $this->request) {
require_once 'Zend/Controller/Request/HttpTestCase.php';
$this->request = new Zend_Controller_Request_HttpTestCase;
}
return $this->request;
}
}
BaseTestCase::setupTimezone();

View File

@ -1,23 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Test;
use Icinga\Web\Form;
/**
* Interface to test form objects
*/
interface FormTest
{
/**
* Instantiate a new form object
*
* @param string $formClass Form class to instantiate
* @param array $requestData Request data for the form
*
* @return Form
*/
public function createForm($formClass, array $requestData = array());
}

View File

@ -7,7 +7,6 @@ namespace Icinga;
use DateTimeZone;
use InvalidArgumentException;
use Icinga\User\Preferences;
use Icinga\User\Message;
/**
* This class represents an authorized user
@ -98,13 +97,6 @@ class User
*/
protected $preferences;
/**
* Queued notifications for this user.
*
* @var array()
*/
protected $messages;
/**
* Creates a user object given the provided information
*
@ -386,38 +378,6 @@ class User
return new DateTimeZone($tz);
}
/**
* Add a message that can be accessed from future requests, to this user.
*
* This function does NOT automatically write to the session, messages will not be persisted until you do.
*
* @param Message $msg The message
*/
public function addMessage(Message $msg)
{
$this->messages[] = $msg;
}
/**
* Get all currently pending messages
*
* @return array The messages
*/
public function getMessages()
{
return isset($this->messages) ? $this->messages : array();
}
/**
* Remove all messages from this user
*
* This function does NOT automatically write the session, messages will not be persisted until you do.
*/
public function clearMessages()
{
$this->messages = null;
}
/**
* Set additional remote user information
*

View File

@ -1,59 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\User;
use Zend_Log;
/**
* Class Message
*
* A Message with an additional logging level to indicate the type.
*
* @package Icinga\User
*/
class Message
{
/**
* The content of this message
*
* @var string
*/
private $message;
/**
* The logging-level of this message
*/
private $level;
/**
* Create a new Message
*
* @param string $message The message content
* @param $level The status of the message
* * Zend_Log::INFO
* * Zend_Log::ERR
*/
public function __construct($message, $level = Zend_Log::INFO)
{
$this->message = $message;
$this->level = $level;
}
/**
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* @return The
*/
public function getLevel()
{
return $this->level;
}
}

View File

@ -76,4 +76,18 @@ class DateTimeFactory implements ConfigAwareFactory
{
return new DateTime($time, $timeZone !== null ? $timeZone : self::$timeZone);
}
/**
* Check whether a variable is a Unix timestamp
*
* @param mixed $timestamp
*
* @return bool
*/
public static function isUnixTimestamp($timestamp)
{
return (is_int($timestamp) || ctype_digit($timestamp))
&& ($timestamp <= PHP_INT_MAX)
&& ($timestamp >= ~PHP_INT_MAX);
}
}

View File

@ -39,10 +39,6 @@ class ActionController extends Zend_Controller_Action
*/
protected $requiresAuthentication = true;
private $config;
private $configs = array();
private $autorefreshInterval;
private $reloadCss = false;
@ -91,23 +87,29 @@ class ActionController extends Zend_Controller_Action
}
$this->view->tabs = new Tabs();
$this->prepareInit();
$this->init();
}
/**
* Prepare controller initialization
*
* As it should not be required for controllers to call the parent's init() method, base controllers should use
* prepareInit() in order to prepare the controller initialization.
*
* @see \Zend_Controller_Action::init() For the controller initialization method.
*/
protected function prepareInit()
{
}
public function Config($file = null)
{
if ($file === null) {
if ($this->config === null) {
$this->config = Config::app();
}
return $this->config;
return Config::app();
} else {
if (! array_key_exists($file, $this->configs)) {
$this->configs[$file] = Config::module($module, $file);
}
return $this->configs[$file];
return Config::app($file);
}
return $this->config;
}
public function Auth()

View File

@ -1,61 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Controller;
use Zend_Log;
use Icinga\Web\Session;
use Icinga\User\Message;
use Icinga\Authentication\Manager as AuthenticationManager;
/**
* Base class for Configuration Controllers
*
* Module preferences use this class to make sure they are automatically
* added to the application's configuration dialog. If you create a subclass of
* BasePreferenceController and overwrite @see init(), make sure you call
* parent::init(), otherwise you won't have the $tabs property in your view.
*/
class BaseConfigController extends ActionController
{
/**
* Send a message with the logging level Zend_Log::INFO to the current user and
* commit the changes to the underlying session.
*
* @param $msg The message content
*/
protected function addSuccessMessage($msg)
{
AuthenticationManager::getInstance()->getUser()->addMessage(
new Message($msg, Zend_Log::INFO)
);
Session::getSession()->write();
}
/**
* Send a message with the logging level Zend_Log::ERR to the current user and
* commit the changes to the underlying session.
*
* @param $msg The message content
*/
protected function addErrorMessage($msg)
{
AuthenticationManager::getInstance()->getUser()->addMessage(
new Message($msg, Zend_Log::ERR)
);
Session::getSession()->write();
}
/*
* Return an array of tabs provided by this configuration controller.
*
* Those tabs will automatically be added to the application's configuration dialog
*
* @return array
*/
public static function createProvidedTabs()
{
return array();
}
}

View File

@ -4,11 +4,6 @@
namespace Icinga\Web\Controller;
use Icinga\Application\Config as IcingaConfig;
use Icinga\Exception\ConfigurationError;
use Icinga\Web\Session;
use Icinga\User\Preferences\PreferencesStore;
/**
* Base class for Preference Controllers
*
@ -42,27 +37,4 @@ class BasePreferenceController extends ActionController
parent::init();
$this->view->tabs = ControllerTabCollector::collectControllerTabs('PreferenceController');
}
protected function savePreferences(array $preferences)
{
$session = Session::getSession();
$currentPreferences = $session->user->getPreferences();
foreach ($preferences as $key => $value) {
if ($value === null) {
$currentPreferences->remove($key);
} else {
$currentPreferences->{$key} = $value;
}
}
$session->write();
if (($preferencesConfig = IcingaConfig::app()->preferences) === null) {
throw new ConfigurationError(
'Cannot save preferences changes since you\'ve not configured a preferences backend'
);
}
$store = PreferencesStore::create($preferencesConfig, $session->user);
$store->load(); // Necessary for patching existing preferences
$store->save($currentPreferences);
}
}

View File

@ -6,9 +6,10 @@ namespace Icinga\Web\Controller;
use Icinga\Application\Config;
use Icinga\Application\Icinga;
use Zend_Controller_Request_Abstract as Request;
use Zend_Controller_Response_Abstract as Response;
/**
* Base class for module action controllers
*/
class ModuleActionController extends ActionController
{
private $config;
@ -17,34 +18,42 @@ class ModuleActionController extends ActionController
private $module;
/**
* Module name
*
* @var string
*/
protected $moduleName;
public function __construct(
Request $request,
Response $response,
array $invokeArgs = array()
) {
parent::__construct($request, $response, $invokeArgs);
$this->moduleName = $request->getModuleName();
/**
* (non-PHPDoc)
* @see \Icinga\Web\Controller\ActionController For the method documentation.
*/
protected function prepareInit()
{
$this->moduleName = $this->_request->getModuleName();
$this->_helper->layout()->moduleName = $this->moduleName;
$this->view->translationDomain = $this->moduleName;
$this->moduleInit();
}
/**
* Prepare module action controller initialization
*/
protected function moduleInit()
{
}
public function Config($file = null)
{
$module = $this->getRequest()->getModuleName();
$this->moduleName = $module;
if ($file === null) {
if ($this->config === null) {
$this->config = Config::module($module);
$this->config = Config::module($this->moduleName);
}
return $this->config;
} else {
if (! array_key_exists($file, $this->configs)) {
$this->configs[$file] = Config::module($module, $file);
$this->configs[$file] = Config::module($this->moduleName, $file);
}
return $this->configs[$file];
}
@ -58,19 +67,13 @@ class ModuleActionController extends ActionController
return $this->module;
}
public function postDispatch()
{
$req = $this->getRequest();
$resp = $this->getResponse();
if ($this->isXhr()) {
$resp->setHeader('X-Icinga-Module', $this->moduleName);
}
parent::postDispatch();
}
protected function moduleInit()
/**
* (non-PHPDoc)
* @see \Icinga\Web\Controller\ActionController::postDispatchXhr() For the method documentation.
*/
public function postDispatchXhr()
{
parent::postDispatchXhr();
$this->getResponse()->setHeader('X-Icinga-Module', $this->moduleName);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Form\Decorator;
use Zend_Form_Decorator_Abstract;
/**
* Decorator that styles forms in the DOM Bootstrap wants for it's forms
*
* This component replaces the dt/dd wrapping of elements with the approach used by bootstrap.
*
* Labels are drawn for all elements, except hidden, button and submit elements. If you want a
* placeholder for this elements, set the 'addLabelPlaceholder' property. This can be useful in
* cases where you want to put inputs with and inputs without labels on the same line and don't
* want buttons to 'jump'
*/
class BootstrapForm extends Zend_Form_Decorator_Abstract
{
/**
* An array of elements that won't get a <label> dom added per default
*
* @var array
*/
private static $noLabel = array(
'Zend_Form_Element_Hidden',
'Zend_Form_Element_Button',
'Zend_Form_Element_Submit'
);
/**
* Return the DOM for the element label
*
* @param String $elementName The name of the element
*
* @return String The DOM for the form element's label
*/
public function getLabel($elementName)
{
$label = $this->getElement()->getLabel();
if (!$label) {
$label = '&nbsp;';
}
if (in_array($this->getElement()->getType(), self::$noLabel)
&& !$this->getElement()->getAttrib('addLabelPlaceholder', false)) {
$label = '';
} else {
if (in_array($this->getElement()->getType(), self::$noLabel)) {
$label = '&nbsp;';
}
$label = '<label for="' . $elementName . '">' . $label . '</label>';
}
return $label;
}
/**
* Render this element
*
* Renders as the following:
* <div class="form-group">
* $dtLabel
* $dtElement
* </div>
*
* @param String $content The content of the form element
*
* @return String The decorated form element
*/
public function render($content)
{
$el = $this->getElement();
$elementName = $el->getName();
$label = $this->getLabel($elementName);
return '<div class="form-group" id="' . $elementName . '-element">'
. $label
. $content
. '</div>';
}
}

View File

@ -1,37 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Form\Decorator;
use Zend_Form_Decorator_Abstract;
/**
* Decorator that automatically adds a helptext to an input element
* when the 'helptext' attribute is set
*/
class HelpText extends Zend_Form_Decorator_Abstract
{
/**
* Add a helptext to an input field
*
* @param string $content The help text
*
* @return string The generated tag
*/
public function render($content = '')
{
$attributes = $this->getElement()->getAttribs();
$visible = true;
if (isset($attributes['condition'])) {
$visible = $attributes['condition'] == '1';
}
if (isset($attributes['helptext']) && $visible) {
$content = $content
. '<p class="help-block">'
. $attributes['helptext']
. '</p>';
}
return $content;
}
}

View File

@ -0,0 +1,35 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Form\Decorator;
use Zend_Form_Decorator_Abstract;
use Icinga\Application\Icinga;
/**
* Decorator to add a submit button encapsulated in noscript-tags
*
* This enables users in non-JS environments to update the contents
* of a form without the use of the main submit button.
*/
class NoScriptApply extends Zend_Form_Decorator_Abstract
{
/**
* Add a submit button encapsulated in noscript-tags to the element
*
* @param string $content The html rendered so far
*
* @return string The updated html
*/
public function render($content = '')
{
if ($content) {
$content .= '<noscript><button name="noscript_apply" style="margin-left: 0.5em;" type="submit" value="1">'
. Icinga::app()->getViewRenderer()->view->icon('refresh.png') . '&nbsp;' . t('Apply')
. '</button></noscript>';
}
return $content;
}
}

View File

@ -0,0 +1,88 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Form\Element;
use Zend_Form_Element_Xhtml;
use Icinga\Web\Session;
use Icinga\Web\Form\InvalidCSRFTokenException;
/**
* CSRF counter measure element
*
* You must not set a value to successfully use this element, just give it a name and you're good to go.
*/
class CsrfCounterMeasure extends Zend_Form_Element_Xhtml
{
/**
* Default form view helper to use for rendering
*
* @var string
*/
public $helper = 'formHidden';
/**
* Initialize this form element
*/
public function init()
{
$this->setRequired(true); // Not requiring this element would not make any sense
$this->setIgnore(true); // We do not want this element's value being retrieved by Form::getValues()
$this->setDecorators(array('ViewHelper'));
$this->setValue($this->generateCsrfToken());
}
/**
* Check whether $value is a valid CSRF token
*
* @param string $value The value to check
* @param mixed $context Context to use
*
* @return bool True, in case the CSRF token is valid
*
* @throws InvalidCSRFTokenException In case the CSRF token is not valid
*/
public function isValid($value, $context = null)
{
if (parent::isValid($value, $context) && $this->isValidCsrfToken($value)) {
return true;
}
throw new InvalidCSRFTokenException();
}
/**
* Check whether the given value is a valid CSRF token for the current session
*
* @param string $token The CSRF token
*
* @return bool
*/
protected function isValidCsrfToken($token)
{
if (strpos($token, '|') === false) {
return false;
}
list($seed, $hash) = explode('|', $token);
if (false === is_numeric($seed)) {
return false;
}
return $hash === hash('sha256', Session::getSession()->getId() . $seed);
}
/**
* Generate a new (seed, token) pair
*
* @return string
*/
protected function generateCsrfToken()
{
$seed = mt_rand();
$hash = hash('sha256', Session::getSession()->getId() . $seed);
return sprintf('%s|%s', $seed, $hash);
}
}

View File

@ -4,100 +4,145 @@
namespace Icinga\Web\Form\Element;
use Icinga\Web\Form\Validator\DateTimeValidator;
use Zend_Form_Element_Text;
use DateTime;
use Zend_Form_Element;
use Icinga\Util\DateTimeFactory;
use Icinga\Web\Form\Validator\DateTimeValidator;
/**
* Datetime form element which returns the input as Unix timestamp after the input has been proven valid. Utilizes
* DateTimeFactory to ensure time zone awareness
* A date-and-time input control
*
* @see isValid()
* @method DateTime getValue()
*/
class DateTimePicker extends Zend_Form_Element_Text
class DateTimePicker extends Zend_Form_Element
{
/**
* Default format used my js picker
* Disable default decorators
*
* \Icinga\Web\Form sets default decorators for elements.
*
* @var string
*/
public $defaultFormat = 'Y-m-d H:i:s';
/**
* JS picker support on or off
* @var bool
*
* @see \Icinga\Web\Form::__construct() For default element decorators.
*/
public $jspicker = true;
protected $_disableLoadDefaultDecorators = true;
/**
* View helper to use
* Form view helper to use for rendering
*
* @var string
*/
public $helper = 'formDateTime';
/**
* The validator used for datetime validation
* @var DateTimeValidator
* @var bool
*/
private $dateValidator;
protected $local = true;
/**
* Valid formats to check user input against
* @var array
*/
public $patterns = array();
/**
* Create a new DateTimePicker
* The expected lower bound for the elements value
*
* @param array|string|\Zend_Config $spec
* @param null $options
* @see Zend_Form_Element::__construct()
* @var DateTime|null
*/
public function __construct($spec, $options = null)
protected $min;
/**
* The expected upper bound for the elements
*
* @var DateTime|null
*/
protected $max;
/**
* (non-PHPDoc)
* @see \Zend_Form_Element::init() For the method documentation.
*/
public function init()
{
parent::__construct($spec, $options);
$this->addValidator(
new DateTimeValidator($this->local), true // true for breaking the validator chain on failure
);
if ($this->min !== null) {
$this->addValidator('GreaterThan', true, array('min' => $this->min));
}
if ($this->max !== null) {
$this->addValidator('LessThan', true, array('max' => $this->max));
}
}
$this->patterns[] = $this->defaultFormat;
public function setLocal($local)
{
$this->local = (bool) $local;
return $this;
}
$this->dateValidator = new DateTimeValidator($this->patterns);
$this->addValidator($this->dateValidator);
public function getLocal()
{
return $this->local;
}
/**
* Validate filtered date/time strings
* Set the expected lower bound for the elements value
*
* Expects one or more valid formats being set in $this->patterns. Sets element value as Unix timestamp
* if the input is considered valid. Utilizes DateTimeFactory to ensure time zone awareness.
* @param DateTime $min
*
* @return $this
*/
public function setMin(DateTime $min)
{
$this->min = $min;
return $this;
}
/**
* Get the expected lower bound for the elements value
*
* @return DateTime|null
*/
public function getMin()
{
return $this->min;
}
/**
* Set the expected upper bound for the elements value
*
* @param DateTime $max
*
* @return $this
*/
public function setMax(DateTime $max)
{
$this->max = $max;
return $this;
}
/**
* Get the expected upper bound for the elements value
*
* @return DateTime|null
*/
public function getMax()
{
return $this->max;
}
/**
* Is the date and time valid?
*
* @param string|DateTime $value
* @param mixed $context
*
* @param string $value
* @param mixed $context
* @return bool
*/
public function isValid($value, $context = null)
{
// Overwrite the internal validator to use
if (!parent::isValid($value, $context)) {
if (! parent::isValid($value, $context)) {
return false;
}
$pattern = $this->dateValidator->getValidPattern();
if (!$pattern) {
$this->setValue($value);
return true;
if (! $value instanceof DateTime) {
$format = $this->local === true ? 'Y-m-d\TH:i:s' : DateTime::RFC3339;
$this->setValue(DateTime::createFromFormat($format, $value));
}
$this->setValue(DateTimeFactory::parse($value, $pattern)->getTimestamp());
return true;
}
public function enableJsPicker()
{
$this->jspicker = true;
}
public function disableJsPicker()
{
$this->jspicker = false;
}
}

View File

@ -1,31 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Form\Element;
use Zend_Form_Element_Xhtml;
/**
* Implements note element for Zend forms
*/
class Note extends Zend_Form_Element_Xhtml
{
/**
* Name of the view helper
*
* @var string
*/
public $helper = 'formNote';
/**
* Return true to ensure redrawing
*
* @param mixed $value The value of to validate (ignored)
* @return bool Always true
*/
public function isValid($value)
{
return true;
}
}

View File

@ -4,38 +4,138 @@
namespace Icinga\Web\Form\Element;
use Zend_Form_Element_Xhtml;
use Zend_Form_Element;
/**
* Number form element
* A number input control
*/
class Number extends Zend_Form_Element_Xhtml
class Number extends Zend_Form_Element
{
/**
* Default form view helper to use for rendering
* Disable default decorators
*
* \Icinga\Web\Form sets default decorators for elements.
*
* @var bool
*
* @see \Icinga\Web\Form::__construct() For default element decorators.
*/
protected $_disableLoadDefaultDecorators = true;
/**
* Form view helper to use for rendering
*
* @var string
*/
public $helper = "formNumber";
public $helper = 'formNumber';
/**
* Check whether $value is of type integer
* The expected lower bound for the elements value
*
* @param string $value The value to check
* @param mixed $context Context to use
*
* @return bool
* @var float|null
*/
public function isValid($value, $context = null)
protected $min;
/**
* The expected upper bound for the elements
*
* @var float|null
*/
protected $max;
/**
* The value granularity of the elements value
*
* Normally, number input controls are limited to an accuracy of integer values.
*
* @var float|string|null
*/
protected $step;
/**
* (non-PHPDoc)
* @see \Zend_Form_Element::init() For the method documentation.
*/
public function init()
{
if (parent::isValid($value, $context)) {
if (is_numeric($value)) {
return true;
}
$this->addError(t('Please enter a number.'));
$this->addValidator('Float', true); // true for breaking the validator chain on failure
if ($this->min !== null) {
$this->addValidator('GreaterThan', true, array('min' => $this->min));
}
if ($this->max !== null) {
$this->addValidator('LessThan', true, array('max' => $this->max));
}
}
return false;
/**
* Set the expected lower bound for the elements value
*
* @param float $min
*
* @return $this
*/
public function setMin($min)
{
$this->min = (float) $min;
return $this;
}
/**
* Get the expected lower bound for the elements value
*
* @return float|null
*/
public function getMin()
{
return $this->min;
}
/**
* Set the expected upper bound for the elements value
*
* @param float $max
*
* @return $this
*/
public function setMax($max)
{
$this->max = (int) $max;
return $this;
}
/**
* Get the expected upper bound for the elements value
*
* @return float|null
*/
public function getMax()
{
return $this->max;
}
/**
* Set the value granularity of the elements value
*
* @param float|string $step
*
* @return $this
*/
public function setStep($step)
{
if ($step !== 'any') {
$step = (float) $step;
}
$this->step = $step;
return $this;
}
/**
* Get the value granularity of the elements value
*
* @return float|string|null
*/
public function getStep()
{
return $this->step;
}
}

View File

@ -4,127 +4,52 @@
namespace Icinga\Web\Form\Validator;
use Icinga\Util\DateTimeFactory;
use DateTime;
use Zend_Validate_Abstract;
use Icinga\Exception\ProgrammingError;
/**
* Validator that checks if a textfield contains a correct date format
* Validator for date-and-time input controls
*
* @see \Icinga\Web\Form\Element\DateTimePicker For the date-and-time input control.
*/
class DateTimeValidator extends Zend_Validate_Abstract
{
/**
* Array of allowed patterns for datetime input
*
* @var array
*/
private $patterns = array();
protected $local;
/**
* If the input is not a timestamp this contains the pattern that
* matched the input
* Create a new date-and-time input control validator
*
* @var string|bool
* @param bool $local
*/
private $validPattern = false;
/**
* Error templates
*
* @var array
*
* @see Zend_Validate_Abstract::$_messageTemplates
*/
protected $_messageTemplates = array();
/**
* Create this validator
*
* @param array $patterns Array containing all allowed patterns as strings
*/
public function __construct(array $patterns)
public function __construct($local)
{
$this->patterns = $patterns;
$this->_messageTemplates = array(
'INVALID_TYPE' => 'Invalid type given. Date/time string or Unix timestamp expected',
'NO_MATCHING_PATTERN' => 'Invalid format given, valid formats are ' . $this->getAllowedPatternList()
);
$this->local = (bool) $local;
}
/**
* Check whether a variable is a Unix timestamp
* Is the date and time valid?
*
* @param string|DateTime $value
* @param mixed $context
*
* @param mixed $timestamp
* @return bool
*/
public static function isUnixTimestamp($timestamp)
{
return (is_int($timestamp) || ctype_digit($timestamp))
&& ($timestamp <= PHP_INT_MAX)
&& ($timestamp >= ~PHP_INT_MAX);
}
/**
* Returns a printable string containing all configured patterns
*
* @return string
*/
private function getAllowedPatternList()
{
return '"' . join('","', $this->patterns) . '"';
}
/**
* Validate the input value and set the value of @see validPattern if the input machtes a pattern
*
* @param string $value The format string to validate
* @param null $context The form context (ignored)
*
* @return bool True when the input is valid, otherwise false
*
* @see Zend_Validate_Abstract::isValid()
* @see \Zend_Validate_Interface::isValid()
*/
public function isValid($value, $context = null)
{
$this->validPattern = false;
if (!is_string($value) && !is_int($value)) {
$this->error('INVALID_TYPE');
if (! $value instanceof DateTime && ! is_string($value)) {
$this->_error(t('Invalid type given. Instance of DateTime or date/time string expected'));
return false;
}
if ($this->isUnixTimestamp($value)) {
$dt = DateTimeFactory::create();
$dt->setTimestamp($value);
} else {
if (!isset($this->patterns)) {
throw new ProgrammingError('There are no allowed timeformats configured');
}
$match_found = false;
foreach ($this->patterns as $pattern) {
$dt = DateTimeFactory::parse($value, $pattern);
if ($dt !== false && $dt->format($pattern) === $value) {
$match_found = true;
$this->validPattern = $pattern;
break;
}
}
if (!$match_found) {
$this->_error('NO_MATCHING_PATTERN');
if (is_string($value)) {
$format = $this->local === true ? 'Y-m-d\TH:i:s' : DateTime::RFC3339;
$dateTime = DateTime::createFromFormat($format, $value);
if ($dateTime === false || $dateTime->format($format) !== $value) {
$this->_error(sprintf(t('Date/time string not in the expected format %s'), $format));
return false;
}
}
return true;
}
/**
* Return the matched pattern if any or false if input is a timestamp
*
* @return bool|string False if input was a timestamp otherwise string with the dateformat pattern
*/
public function getValidPattern()
{
return $this->validPattern;
}
}

View File

@ -0,0 +1,58 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Form\Validator;
use Zend_Validate_Abstract;
/**
* Validator that interprets the value as a filepath and checks if it's readable
*
* This validator should be preferred due to Zend_Validate_File_Exists is
* getting confused if there is another element in the form called `name'.
*/
class ReadablePathValidator extends Zend_Validate_Abstract
{
/**
* The messages to write on different error states
*
* @var array
*
* @see Zend_Validate_Abstract::$_messageTemplates
*/
protected $_messageTemplates;
/**
* Initialize this validator
*/
public function __construct()
{
$this->_messageTemplates = array(
'NOT_READABLE' => t('Path is not readable'),
'DOES_NOT_EXIST' => t('Path does not exist')
);
}
/**
* Check whether the given value is a readable filepath
*
* @param string $value The value submitted in the form
* @param mixed $context The context of the form
*
* @return bool Whether the value was successfully validated
*/
public function isValid($value, $context = null)
{
if (false === file_exists($value)) {
$this->_error('DOES_NOT_EXIST');
return false;
}
if (false === is_readable($value)) {
$this->_error('NOT_READABLE');
}
return true;
}
}

View File

@ -1,132 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Widget;
use Zend_Log;
use Zend_Form;
use Icinga\User;
use Icinga\User\Message;
use Icinga\Web\Session;
use Icinga\Authentication\Manager as AuthenticationManager;
/**
* Displays a set of alert messages to the user.
*
* The messages are fetched automatically from the current AuthenticationManager,
* but this is done lazily when render() is called, to ensure that messages will
* always be displayed before they are cleared.
*/
class AlertMessageBox extends AbstractWidget
{
/**
* Remove all messages from the current user, return them and commit
* changes to the underlying session.
*
* @return array The messages
*/
protected function getAndClearMessages()
{
$messages = $this->user->getMessages();
$this->user->clearMessages();
Session::getSession()->write();
return $messages;
}
/**
* The displayed alert messages
*
* @var array
*/
private $messages = array();
/**
* The user to fetch the messages from
*
* @var User
*/
private $user;
/**
* The available states.
*
* @var array
*/
private $states = array(
Zend_Log::INFO => array(
'state' => 'alert-success',
'icon' => 'success.png'
),
Zend_Log::NOTICE => array(
'state' => 'alert-info',
'icon' => 'info.png'
),
Zend_Log::WARN => array(
'state' => 'alert-warning',
'icon' => 'warning.png'
),
Zend_Log::ERR => array(
'state' => 'alert-danger',
'icon' => 'error.png'
)
);
/**
* Create a new AlertBox
*
* @param boolean showUserMessages If the current user messages should be displayed
* in this AlertMessageBox. Defaults to false
*/
public function __construct($showUserMessages = false)
{
if ($showUserMessages) {
$this->user = AuthenticationManager::getInstance()->getUser();
}
}
/**
* Add a new error
*
* @param $error
*/
public function addError($error)
{
$this->messages[] = new Message($error, Zend_Log::ERR);
}
/**
* Add the error messages of the given Zend_Form
*/
public function addForm(Zend_Form $form)
{
foreach ($form->getErrorMessages() as $error) {
$this->addError($error);
}
}
/**
* Output the HTML of the AlertBox
*
* @return string
*/
public function render(Zend_View_Abstract $view = null)
{
$html = '';
if (isset($this->user)) {
$this->messages = array_merge($this->messages, $this->getAndClearMessages());
}
foreach ($this->messages as $message) {
$level = $message->getLevel();
if (!array_key_exists($level, $this->states)) {
continue;
}
$alert = $this->states[$level];
$html .= '<div class="alert ' . $alert['state']. '">' .
$this->view()->icon($alert['icon']) .
'<strong>' . htmlspecialchars($message->getMessage()) . '</strong>' .
'</div>';
}
return $html;
}
}

View File

@ -24,7 +24,7 @@ class InlinePie extends AbstractWidget
const NUMBER_FORMAT_TIME = 'time';
const NUMBER_FORMAT_BYTES = 'bytes';
const NUMBER_FORMAT_RATIO = 'ratio';
/**
* The template string used for rendering this widget
* The template string used for rendering this widget
@ -137,7 +137,7 @@ EOD;
* @var string
*/
private $tooltipFormat = '<b>{{title}}</b></br> {{label}}: {{formatted}} ({{percent}}%)';
/**
* The number format used to render numeric values in tooltips
*
@ -148,30 +148,36 @@ EOD;
/**
* Set if the tooltip for the empty area should be hidden
*
* @param bool $hide Whether to hide the empty area
* @param bool $hide Whether to hide the empty area
*
* @return $this
*/
public function setHideEmptyLabel($hide = true)
{
$this->hideEmptyLabel = $hide;
return $this;
}
/**
* Set the data to be displayed.
*
* @param $data array
* @param $data array
*
* @return $this
*/
public function setData(array $data)
{
$this->data = $data;
$this->url->setParam('data', implode(',', $data));
return $this;
}
/**
* The labels to be displayed in the pie-chart
*
* @param mixed $label The label of the displayed value, or null for no labels
* @param mixed $label The label of the displayed value, or null for no labels
*
* @return $this Fluent interface
* @return $this
*/
public function setLabel($label)
{
@ -191,7 +197,9 @@ EOD;
/**
* Set the colors used by the slices of the pie chart.
*
* @param array $colors
* @param array $colors
*
* @return $this
*/
public function setColors(array $colors = null)
{
@ -201,18 +209,22 @@ EOD;
} else {
$this->url->setParam('colors', null);
}
return $this;
}
/**
* Set the used number format
*
* @param $format string 'bytes' or 'time'
* @param $format string 'bytes' or 'time'
*
* @return $this
*/
public function setNumberFormat($format)
{
$this->format = $format;
return $this;
}
/**
* A format string used to render the content of the piechart tooltips
*
@ -225,16 +237,23 @@ EOD;
* <li><b>percent</b>: The percentage of the current value </li>
* </ul>
* Note: Changes will only affect JavaScript sparklines and not the SVG charts used for fallback
*
* @param $format
*
* @return $this
*/
public function setTooltipFormat($format)
{
$this->tooltipFormat = $format;
return $this;
}
/**
* @param $height
* Set the height
*
* @return $this
* @param $height
*
* @return $this
*/
public function setHeight($height)
{
@ -245,17 +264,22 @@ EOD;
/**
* Set the border width of the pie chart
*
* @param float $width Width in px
* @param float $width Width in px
*
* @return $this
*/
public function setBorderWidth($width)
{
$this->borderWidth = $width;
return $this;
}
/**
* Set the color of the pie chart border
*
* @param string $col The color string
* @param string $col The color string
*
* @return $this
*/
public function setBorderColor($col)
{
@ -263,9 +287,11 @@ EOD;
}
/**
* @param $width
* Set the width
*
* @return $this
* @param $width
*
* @return $this
*/
public function setWidth($width)
{
@ -276,7 +302,9 @@ EOD;
/**
* Set the styling of the created HtmlElement
*
* @param string $style
* @param string $style
*
* @return $this
*/
public function setStyle($style)
{
@ -286,11 +314,14 @@ EOD;
/**
* Set the title of the displayed Data
*
* @param string $title
* @param string $title
*
* @return $this
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
@ -346,7 +377,7 @@ EOD;
{
$template = $this->template;
$template = str_replace('{url}', $this->url, $template);
// style
$template = str_replace('{width}', $this->width, $template);
$template = str_replace('{height}', $this->height, $template);

View File

@ -119,20 +119,19 @@ class SortBox extends AbstractWidget
'label' => 'Sort By',
'multiOptions' => $this->sortFields,
'style' => 'width: 12em',
'class' => 'autosubmit',
'autosubmit' => true
));
$form->addElement('select', 'dir', array(
'multiOptions' => array(
'asc' => 'Asc',
'desc' => 'Desc',
),
'style' => 'width: 5em',
'class' => 'autosubmit'
'style' => 'width: 5em',
'autosubmit' => true
));
$sort = $form->getElement('sort')->setDecorators(array('ViewHelper'));
$dir = $form->getElement('dir')->setDecorators(array('ViewHelper'));
if ($this->request) {
$form->setAction($this->request->getRequestUri());
$form->populate($this->request->getParams());
}
return $form;

View File

@ -2,15 +2,8 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Application\Icinga;
use Icinga\Application\Config;
use Icinga\Logger\Logger;
use Icinga\Web\Form;
use Icinga\Module\Monitoring\Controller;
use Icinga\Chart\SVGRenderer;
use Icinga\Chart\GridChart;
use Icinga\Chart\Palette;
use Icinga\Chart\Axis;
use Icinga\Chart\PieChart;
use Icinga\Chart\Unit\StaticAxis;
@ -151,7 +144,7 @@ class Monitoring_ChartController extends Controller
$this->view->chart = new GridChart();
$this->view->chart->alignTopLeft();
$this->view->chart->setAxisLabel('', t('Services'))
->setXAxis(new \Icinga\Chart\Unit\StaticAxis())
->setXAxis(new StaticAxis())
->setAxisMin(null, 0);
$tooltip = t('<b>{title}:</b><br>{value} of {sum} services are {label}');

View File

@ -2,42 +2,27 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Config\PreservingIniWriter;
use Icinga\Web\Controller\ModuleActionController;
use Icinga\Web\Notification;
use Icinga\Module\Monitoring\Form\Config\ConfirmRemovalForm;
use Icinga\Module\Monitoring\Form\Config\Backend\EditBackendForm;
use Icinga\Module\Monitoring\Form\Config\Backend\CreateBackendForm;
use Icinga\Module\Monitoring\Form\Config\Instance\EditInstanceForm;
use Icinga\Module\Monitoring\Form\Config\Instance\CreateInstanceForm;
use Icinga\Module\Monitoring\Form\Config\SecurityForm;
use Icinga\Exception\NotReadableError;
use Icinga\Data\ResourceFactory;
use Icinga\Form\ConfirmRemovalForm;
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;
/**
* Configuration controller for editing monitoring resources
*/
class Monitoring_ConfigController extends ModuleActionController
{
/**
* Display a list of available backends and instances
*/
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;
}
}
}
/**
@ -45,52 +30,27 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function editbackendAction()
{
$backend = $this->getParam('backend');
if (!$this->isExistingBackend($backend)) {
$this->view->error = 'Unknown backend ' . $backend;
return;
}
$backendForm = new EditBackendForm();
$backendForm->setRequest($this->getRequest());
$backendForm->setBackendConfiguration($this->Config('backends')->get($backend));
$form = new BackendConfigForm();
$form->setIniConfig($this->Config('backends'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
if ($backendForm->isSubmittedAndValid()) {
$newConfig = $backendForm->getConfig();
$config = $this->Config('backends');
$config->$backend = $newConfig;
if ($this->writeConfiguration($config, 'backends')) {
Notification::success('Backend ' . $backend . ' Modified.');
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
}
}
$this->view->name = $backend;
$this->view->form = $backendForm;
$this->view->form = $form;
}
/**
* Display a form to create a new backends
* Display a form to create a new backend
*/
public function createbackendAction()
{
$form = new CreateBackendForm();
$form->setRequest($this->getRequest());
if ($form->isSubmittedAndValid()) {
$configArray = $this->Config('backends')->toArray();
$configArray[$form->getBackendName()] = $form->getConfig();
$form = new BackendConfigForm();
$form->setIniConfig($this->Config('backends'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
if ($this->writeConfiguration(new Zend_Config($configArray), 'backends')) {
Notification::success('Backend Creation Succeeded');
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
}
return;
}
$this->view->form = $form;
$this->render('editbackend');
}
/**
@ -98,62 +58,63 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function removebackendAction()
{
$backend = $this->getParam('backend');
if (!$this->isExistingBackend($backend)) {
$this->view->error = 'Unknown backend ' . $backend;
return;
}
$form = new ConfirmRemovalForm();
$form->setRequest($this->getRequest());
$form->setRemoveTarget('backend', $backend);
$config = $this->Config('backends');
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) use ($config) {
$backendName = $request->getQuery('backend');
$configForm = new BackendConfigForm();
$configForm->setIniConfig($config);
if ($form->isSubmittedAndValid()) {
$configArray = $this->Config('backends')->toArray();
unset($configArray[$backend]);
try {
$configForm->remove($backendName);
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
if ($this->writeConfiguration(new Zend_Config($configArray), 'backends')) {
Notification::success('Backend "' . $backend . '" Removed');
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
if ($configForm->save()) {
Notification::success(sprintf(t('Backend "%s" successfully removed.'), $backendName));
} else {
return false;
}
}
return;
}
));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
$this->view->name = $backend;
}
/**
* Display a form to remove the instance identified by the 'instance' parameter
* Display a confirmation form to remove the instance identified by the 'instance' parameter
*/
public function removeinstanceAction()
{
$instance = $this->getParam('instance');
if (!$this->isExistingInstance($instance)) {
$this->view->error = 'Unknown instance ' . $instance;
return;
}
$config = $this->Config('instances');
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) use ($config) {
$instanceName = $request->getQuery('instance');
$configForm = new InstanceConfigForm();
$configForm->setIniConfig($config);
$form = new ConfirmRemovalForm();
$form->setRequest($this->getRequest());
$form->setRemoveTarget('instance', $instance);
try {
$configForm->remove($instanceName);
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
if ($form->isSubmittedAndValid()) {
$configArray = $this->Config('instances')->toArray();
unset($configArray[$instance]);
if ($this->writeConfiguration(new Zend_Config($configArray), 'instances')) {
Notification::success('Instance "' . $instance . '" Removed');
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
if ($configForm->save()) {
Notification::success(sprintf(t('Instance "%s" successfully removed.'), $instanceName));
} else {
return false;
}
}
return;
}
));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
$this->view->name = $instance;
}
/**
@ -161,25 +122,11 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function editinstanceAction()
{
$instance = $this->getParam('instance');
if (!$this->isExistingInstance($instance)) {
$this->view->error = 'Unknown instance ' . htmlentities($instance);
return;
}
$form = new EditInstanceForm();
$form->setInstanceConfiguration($this->Config('instances')->get($instance));
$form->setRequest($this->getRequest());
if ($form->isSubmittedAndValid()) {
$instanceConfig = $this->Config('instances')->toArray();
$instanceConfig[$instance] = $form->getConfig();
if ($this->writeConfiguration(new Zend_Config($instanceConfig), 'instances')) {
Notification::success('Instance Modified');
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
}
}
$form = new InstanceConfigForm();
$form->setIniConfig($this->Config('instances'));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
}
@ -188,92 +135,24 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function createinstanceAction()
{
$form = new CreateInstanceForm();
$form->setRequest($this->getRequest());
if ($form->isSubmittedAndValid()) {
$instanceConfig = $this->Config('instances');
if ($instanceConfig === null) {
$instanceConfig = array();
} else {
$instanceConfig = $instanceConfig->toArray();
}
$instanceConfig[$form->getInstanceName()] = $form->getConfig()->toArray();
if ($this->writeConfiguration(new Zend_Config($instanceConfig), 'instances')) {
Notification::success('Instance Creation Succeeded');
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
}
return;
}
$form = new InstanceConfigForm();
$form->setIniConfig($this->Config('instances'));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
$this->render('editinstance');
}
/**
* Display a form to remove the instance identified by the 'instance' parameter
* Display a form to adjust security relevant settings
*/
private function writeConfiguration($config, $file = null)
{
$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;
}
/**
* Return true if the backend exists in the current configuration
*
* @param string $backend The name of the backend to check for existence
*
* @return bool True if the backend name exists, otherwise false
*/
private function isExistingBackend($backend)
{
$backendCfg = $this->Config('backends');
return $backend && $backendCfg->get($backend);
}
/**
* Return true if the instance exists in the current configuration
*
* @param string $instance The name of the instance to check for existence
*
* @return bool True if the instance name exists, otherwise false
*/
private function isExistingInstance($instance)
{
$instanceCfg = $this->Config('instances');
return $instanceCfg && $instanceCfg->get($instance);
}
public function securityAction()
{
$this->view->tabs = $this->Module()->getConfigTabs()->activate('security');
$form = new SecurityConfigForm();
$form->setIniConfig($this->Config());
$form->handleRequest();
$form = new SecurityForm();
$form->setConfiguration($this->Config()->get('security'));
$form->setRequest($this->getRequest());
if ($form->isSubmittedAndValid()) {
$config = $this->Config()->toArray();
$config['security'] = $form->getConfig();
if ($this->writeConfiguration(new Zend_Config($config))) {
Notification::success('Configuration modified successfully');
$this->redirectNow('monitoring/config/security');
} else {
$this->render('show-configuration');
return;
}
}
$this->view->form = $form;
$this->view->tabs = $this->Module()->getConfigTabs()->activate('security');
}
}

View File

@ -0,0 +1,79 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Module\Monitoring\Form\Command\Object\AcknowledgeProblemCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\AddCommentCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleHostCheckCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleHostDowntimeCommandForm;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Web\Controller\MonitoredObjectController;
class Monitoring_HostController extends MonitoredObjectController
{
/**
* (non-PHPDoc)
* @see MonitoredObjectController::$commandRedirectUrl For the property documentation.
*/
protected $commandRedirectUrl = 'monitoring/host/show';
/**
* Fetch the requested host from the monitoring backend
*
* @throws Zend_Controller_Action_Exception If the host was not found
*/
public function init()
{
$host = new Host($this->backend, $this->params->get('host'));
if ($host->fetch() === false) {
throw new Zend_Controller_Action_Exception($this->translate('Host not found'));
}
$this->object = $host;
$this->createTabs();
}
/**
* Show a host
*/
public function showAction()
{
$this->getTabs()->activate('host');
parent::showAction();
}
/**
* Acknowledge a host problem
*/
public function acknowledgeProblemAction()
{
$this->view->title = $this->translate('Acknowledge Host Problem');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
}
/**
* Add a host comment
*/
public function addCommentAction()
{
$this->view->title = $this->translate('Add Host Comment');
$this->handleCommandForm(new AddCommentCommandForm());
}
/**
* Reschedule a host check
*/
public function rescheduleCheckAction()
{
$this->view->title = $this->translate('Reschedule Host Check');
$this->handleCommandForm(new ScheduleHostCheckCommandForm());
}
/**
* Schedule a host downtime
*/
public function scheduleDowntimeAction()
{
$this->view->title = $this->translate('Schedule Host Downtime');
$this->handleCommandForm(new ScheduleHostDowntimeCommandForm());
}
}

View File

@ -0,0 +1,157 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Data\Filter\Filter;
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Form\Command\Object\AcknowledgeProblemCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\CheckNowCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ObjectsCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\RemoveAcknowledgementCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleHostCheckCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleHostDowntimeCommandForm;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Module\Monitoring\Object\HostList;
use Icinga\Web\Url;
use Icinga\Web\Widget\Chart\InlinePie;
class Monitoring_HostsController extends Controller
{
/**
* @var HostList
*/
protected $hostList;
public function init()
{
$hostList = new HostList($this->backend);
$hostList->setFilter(Filter::fromQueryString((string) $this->params));
$this->hostList = $hostList;
}
protected function handleCommandForm(ObjectsCommandForm $form)
{
$form
->setObjects($this->hostList)
->setRedirectUrl(Url::fromPath('monitoring/hosts/show')->setParams($this->params))
->handleRequest();
$this->view->form = $form;
$this->_helper->viewRenderer('partials/command-form', null, true);
return $form;
}
public function showAction()
{
$this->setAutorefreshInterval(15);
$checkNowForm = new CheckNowCommandForm();
$checkNowForm
->setObjects($this->hostList)
->handleRequest();
$this->view->checkNowForm = $checkNowForm;
$this->hostList->setColumns(array(
'host_name',
'host_state',
'host_problem',
'host_handled',
'host_acknowledged',
'host_in_downtime'/*,
'host_passive_checks_enabled',
'host_notifications_enabled',
'host_event_handler_enabled',
'host_flap_detection_enabled',
'host_active_checks_enabled',
'host_obsessing'*/
));
$unhandledObjects = array();
$acknowledgedObjects = array();
$objectsInDowntime = array();
$hostStates = array(
Host::getStateText(Host::STATE_UP) => 0,
Host::getStateText(Host::STATE_DOWN) => 0,
Host::getStateText(Host::STATE_UNREACHABLE) => 0,
Host::getStateText(Host::STATE_PENDING) => 0,
);
foreach ($this->hostList as $host) {
/** @var Service $host */
if ((bool) $host->problem === true && (bool) $host->handled === false) {
$unhandledObjects[] = $host;
}
if ((bool) $host->acknowledged === true) {
$acknowledgedObjects[] = $host;
}
if ((bool) $host->in_downtime === true) {
$objectsInDowntime[] = $host;
}
++$hostStates[$host::getStateText($host->state)];
}
if (! empty($acknowledgedObjects)) {
$removeAckForm = new RemoveAcknowledgementCommandForm();
$removeAckForm
->setObjects($acknowledgedObjects)
->handleRequest();
$this->view->removeAckForm = $removeAckForm;
}
$this->setAutorefreshInterval(15);
$this->view->listAllLink = Url::fromRequest()->setPath('monitoring/list/hosts');
$this->view->rescheduleAllLink = Url::fromRequest()->setPath('monitoring/hosts/reschedule-check');
$this->view->downtimeAllLink = Url::fromRequest()->setPath('monitoring/hosts/schedule-downtime');
$this->view->hostStates = $hostStates;
$this->view->objects = $this->hostList;
$this->view->unhandledObjects = $unhandledObjects;
$this->view->acknowledgeUnhandledLink = Url::fromRequest()
->setPath('monitoring/hosts/acknowledge-problem')
->addParams(array('host_problem' => 1, 'host_handled' => 0));
$this->view->downtimeUnhandledLink = Url::fromRequest()
->setPath('monitoring/hosts/schedule-downtime')
->addParams(array('host_problem' => 1, 'host_handled' => 0));
$this->view->acknowledgedObjects = $acknowledgedObjects;
$this->view->objectsInDowntime = $objectsInDowntime;
$this->view->inDowntimeLink = Url::fromRequest()
->setPath('monitoring/list/downtimes');
$this->view->havingCommentsLink = Url::fromRequest()
->setPath('monitoring/list/comments');
$this->view->hostStatesPieChart = $this->createPieChart(
$hostStates,
$this->translate('Host State'),
array('#44bb77', '#FF5566', '#E066FF', '#77AAFF')
);
}
protected function createPieChart(array $states, $title, array $colors)
{
$chart = new InlinePie(array_values($states), $title, $colors);
return $chart
->setLabel(array_map('strtoupper', array_keys($states)))
->setHeight(100)
->setWidth(100)
->setTitle($title);
}
/**
* Acknowledge host problems
*/
public function acknowledgeProblemAction()
{
$this->view->title = $this->translate('Acknowledge Host Problems');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
}
/**
* Reschedule host checks
*/
public function rescheduleCheckAction()
{
$this->view->title = $this->translate('Reschedule Host Checks');
$this->handleCommandForm(new ScheduleHostCheckCommandForm());
}
/**
* Schedule host downtimes
*/
public function scheduleDowntimeAction()
{
$this->view->title = $this->translate('Schedule Host Downtimes');
$this->handleCommandForm(new ScheduleHostDowntimeCommandForm());
}
}

View File

@ -4,6 +4,8 @@
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Backend;
use Icinga\Module\Monitoring\Form\Command\Object\DeleteCommentCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\DeleteDowntimeCommandForm;
use Icinga\Web\Url;
use Icinga\Web\Hook;
use Icinga\Web\Widget\Tabextension\DashboardAction;
@ -299,6 +301,7 @@ class Monitoring_ListController extends Controller
'downtime_scheduled_end' => 'Scheduled End',
'downtime_duration' => 'Duration',
));
$this->view->delDowntimeForm = new DeleteDowntimeCommandForm();
}
/**
@ -456,6 +459,7 @@ class Monitoring_ListController extends Controller
'comment_expiration' => 'Expiration',
)
);
$this->view->delCommentForm = new DeleteCommentCommandForm();
}
public function servicegroupsAction()

View File

@ -1,75 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Module\Monitoring\Command\Meta;
/**
* Class MonitoringCommands
*
* Helper which produces a list of command buttons
* depending on object states
*/
class Zend_View_Helper_MonitoringCommands extends Zend_View_Helper_Abstract
{
/**
* Fetch all monitoring commands that are currently available for *all*
* given objects and render a html string that contains buttons to execute
* these commands.
*
* NOTE: This means that if you give multiple commands, the commands that
* are not available on every single host, will be left out.
*
* @param array|stdClass $object host or service object or something other
* @param string $type small or full
*
* @return string The rendered html
*/
public function monitoringCommands($object, $type)
{
$commands = new Meta();
$definitions = $commands->getCommandForObject($object, $type);
$out = '<div>';
$i = 0;
foreach ($definitions as $definition) {
if ($i % 5 === 0) {
$out .= '</div><div class="command-section pull-left">';
}
if ($type === Meta::TYPE_FULL) {
$out .= '<div>';
}
$out .= sprintf(
'<button type="button" data-target="command"'
. ' data-command-id="%1$s" class="btn %5$s"'
. ' title="%3$s">'
. '<i class="%4$s"></i> %2$s'
. '</button>',
$definition->id,
$definition->shortDescription,
$definition->longDescription,
$definition->iconCls,
($definition->btnCls) ? $definition->btnCls : 'btn-default'
);
if ($type === Meta::TYPE_FULL) {
$out .= '</div>';
}
$i++;
}
$out .= '</div>';
$out .= '<div style="clear: both;"></div>';
if ($type === Meta::TYPE_FULL) {
return '<div>'. $out. '</div>';
}
return $out;
}
}

View File

@ -2,10 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Web\Form;
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Backend;
use Icinga\Data\SimpleQuery;
use Icinga\Web\Widget\Chart\InlinePie;
use Icinga\Module\Monitoring\Form\Command\MultiCommandFlagForm;
use Icinga\Web\Widget;

View File

@ -2,66 +2,113 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Module\Monitoring\Controller as MonitoringController;
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Form\Command\Instance\DisableNotificationsExpireCommandForm;
use Icinga\Module\Monitoring\Form\Command\Instance\ToggleInstanceFeaturesCommandForm;
/**
* Display process information and global commands
* Display process and performance information of the monitoring host and program-wide commands
*/
class Monitoring_ProcessController extends MonitoringController
class Monitoring_ProcessController extends Controller
{
/**
* Retrieve backend and hooks for this controller
* Add tabs
*
* @see ActionController::init
* @see \Icinga\Web\Controller\ActionController::init()
*/
public function init()
{
$this->getTabs()->add('info', array(
'title' => 'Process Info',
'url' =>'monitoring/process/info'
))->add('performance', array(
'title' => 'Performance Info',
'url' =>'monitoring/process/performance'
));
$this
->getTabs()
->add(
'info',
array(
'title' => $this->translate('Process Info'),
'url' =>'monitoring/process/info'
)
)
->add(
'performance',
array(
'title' => $this->translate('Performance Info'),
'url' => 'monitoring/process/performance'
)
);
}
/**
* Display process information and program-wide commands
*/
public function infoAction()
{
$this->view->title = $this->translate('Process Info');
$this->getTabs()->activate('info');
$this->setAutorefreshInterval(10);
// TODO: This one is broken right now, doublecheck default columns
$this->view->programstatus = $this->backend->select()
->from('programstatus', array(
'id',
'status_update_time',
'program_start_time',
'program_end_time',
'is_currently_running',
'process_id',
'daemon_mode',
'last_command_check',
'last_log_rotation',
'notifications_enabled',
'disable_notif_expire_time',
'active_service_checks_enabled',
'passive_service_checks_enabled',
'active_host_checks_enabled',
'passive_host_checks_enabled',
'event_handlers_enabled',
'flap_detection_enabled',
'failure_prediction_enabled',
'process_performance_data',
'obsess_over_hosts',
'obsess_over_services',
'modified_host_attributes',
'modified_service_attributes',
'global_host_event_handler',
'global_service_event_handler'
))
->getQuery()->fetchRow();
$this->view->backendName = $this->backend->getName();
$programStatus = $this->backend
->select()
->from(
'programstatus',
array(
'is_currently_running',
'process_id',
'program_start_time',
'status_update_time',
'last_command_check',
'last_log_rotation',
'global_service_event_handler',
'global_host_event_handler',
'notifications_enabled',
'disable_notif_expire_time',
'active_service_checks_enabled',
'passive_service_checks_enabled',
'active_host_checks_enabled',
'passive_host_checks_enabled',
'event_handlers_enabled',
'obsess_over_services',
'obsess_over_hosts',
'flap_detection_enabled',
'process_performance_data'
)
)
->getQuery()
->fetchRow();
$this->view->programStatus = $programStatus;
$toggleFeaturesForm = new ToggleInstanceFeaturesCommandForm();
$toggleFeaturesForm
->setStatus($programStatus)
->load($programStatus)
->handleRequest();
$this->view->toggleFeaturesForm = $toggleFeaturesForm;
}
/**
* Disable notifications w/ an optional expire time
*/
public function disableNotificationsAction()
{
$this->view->title = $this->translate('Disable Notifications');
$programStatus = $this->backend
->select()
->from(
'programstatus',
array(
'notifications_enabled',
'disable_notif_expire_time'
)
)
->getQuery()
->fetchRow();
$this->view->programStatus = $programStatus;
if ((bool) $programStatus->notifications_enabled === false) {
return;
} else {
$form = new DisableNotificationsExpireCommandForm();
$form
->setRedirectUrl('monitoring/process/info')
->handleRequest();
$this->view->form = $form;
}
}
public function performanceAction()

View File

@ -0,0 +1,79 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Module\Monitoring\Form\Command\Object\AcknowledgeProblemCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\AddCommentCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleServiceCheckCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleServiceDowntimeCommandForm;
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Module\Monitoring\Web\Controller\MonitoredObjectController;
class Monitoring_ServiceController extends MonitoredObjectController
{
/**
* (non-PHPDoc)
* @see MonitoredObjectController::$commandRedirectUrl For the property documentation.
*/
protected $commandRedirectUrl = 'monitoring/service/show';
/**
* Fetch the requested service from the monitoring backend
*
* @throws Zend_Controller_Action_Exception If the service was not found
*/
public function init()
{
$service = new Service($this->backend, $this->params->get('host'), $this->params->get('service'));
if ($service->fetch() === false) {
throw new Zend_Controller_Action_Exception($this->translate('Service not found'));
}
$this->object = $service;
$this->createTabs();
}
/**
* Show a service
*/
public function showAction()
{
$this->getTabs()->activate('service');
parent::showAction();
}
/**
* Acknowledge a service problem
*/
public function acknowledgeProblemAction()
{
$this->view->title = $this->translate('Acknowledge Service Problem');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
}
/**
* Add a service comment
*/
public function addCommentAction()
{
$this->view->title = $this->translate('Add Service Comment');
$this->handleCommandForm(new AddCommentCommandForm());
}
/**
* Reschedule a service check
*/
public function rescheduleCheckAction()
{
$this->view->title = $this->translate('Reschedule Service Check');
$this->handleCommandForm(new ScheduleServiceCheckCommandForm());
}
/**
* Schedule a service downtime
*/
public function scheduleDowntimeAction()
{
$this->view->title = $this->translate('Schedule Service Downtime');
$this->handleCommandForm(new ScheduleServiceDowntimeCommandForm());
}
}

View File

@ -0,0 +1,177 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Data\Filter\Filter;
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Form\Command\Object\AcknowledgeProblemCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\CheckNowCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ObjectsCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\RemoveAcknowledgementCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleServiceCheckCommandForm;
use Icinga\Module\Monitoring\Form\Command\Object\ScheduleServiceDowntimeCommandForm;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Module\Monitoring\Object\ServiceList;
use Icinga\Web\Url;
use Icinga\Web\Widget\Chart\InlinePie;
class Monitoring_ServicesController extends Controller
{
/**
* @var ServiceList
*/
protected $serviceList;
public function init()
{
$serviceList = new ServiceList($this->backend);
$serviceList->setFilter(Filter::fromQueryString((string) $this->params));
$this->serviceList = $serviceList;
}
protected function handleCommandForm(ObjectsCommandForm $form)
{
$form
->setObjects($this->serviceList)
->setRedirectUrl(Url::fromPath('monitoring/services/show')->setParams($this->params))
->handleRequest();
$this->view->form = $form;
$this->_helper->viewRenderer('partials/command-form', null, true);
return $form;
}
public function showAction()
{
$this->setAutorefreshInterval(15);
$checkNowForm = new CheckNowCommandForm();
$checkNowForm
->setObjects($this->serviceList)
->handleRequest();
$this->view->checkNowForm = $checkNowForm;
$this->serviceList->setColumns(array(
'host_name',
'host_state',
'service_description',
'service_state',
'service_problem',
'service_handled',
'service_acknowledged',
'service_in_downtime'/*,
'service_passive_checks_enabled',
'service_notifications_enabled',
'service_event_handler_enabled',
'service_flap_detection_enabled',
'service_active_checks_enabled',
'service_obsessing'*/
));
$unhandledObjects = array();
$acknowledgedObjects = array();
$objectsInDowntime = array();
$serviceStates = array(
Service::getStateText(Service::STATE_OK) => 0,
Service::getStateText(Service::STATE_WARNING) => 0,
Service::getStateText(Service::STATE_CRITICAL) => 0,
Service::getStateText(Service::STATE_UNKNOWN) => 0,
Service::getStateText(Service::STATE_PENDING) => 0
);
$knownHostStates = array();
$hostStates = array(
Host::getStateText(Host::STATE_UP) => 0,
Host::getStateText(Host::STATE_DOWN) => 0,
Host::getStateText(Host::STATE_UNREACHABLE) => 0,
Host::getStateText(Host::STATE_PENDING) => 0,
);
foreach ($this->serviceList as $service) {
/** @var Service $service */
if ((bool) $service->problem === true && (bool) $service->handled === false) {
$unhandledObjects[] = $service;
}
if ((bool) $service->acknowledged === true) {
$acknowledgedObjects[] = $service;
}
if ((bool) $service->in_downtime === true) {
$objectsInDowntime[] = $service;
}
++$serviceStates[$service::getStateText($service->state)];
if (! isset($knownHostStates[$service->getHost()->getName()])) {
$knownHostStates[$service->getHost()->getName()] = true;
++$hostStates[$service->getHost()->getStateText($service->host_state)];
}
}
if (! empty($acknowledgedObjects)) {
$removeAckForm = new RemoveAcknowledgementCommandForm();
$removeAckForm
->setObjects($acknowledgedObjects)
->handleRequest();
$this->view->removeAckForm = $removeAckForm;
}
$this->setAutorefreshInterval(15);
$this->view->listAllLink = Url::fromRequest()->setPath('monitoring/list/services');
$this->view->rescheduleAllLink = Url::fromRequest()->setPath('monitoring/services/reschedule-check');
$this->view->downtimeAllLink = Url::fromRequest()->setPath('monitoring/services/schedule-downtime');
$this->view->hostStates = $hostStates;
$this->view->serviceStates = $serviceStates;
$this->view->objects = $this->serviceList;
$this->view->unhandledObjects = $unhandledObjects;
$this->view->acknowledgeUnhandledLink = Url::fromRequest()
->setPath('monitoring/services/acknowledge-problem')
->addParams(array('service_problem' => 1, 'service_handled' => 0));
$this->view->downtimeUnhandledLink = Url::fromRequest()
->setPath('monitoring/services/schedule-downtime')
->addParams(array('service_problem' => 1, 'service_handled' => 0));
$this->view->acknowledgedObjects = $acknowledgedObjects;
$this->view->objectsInDowntime = $objectsInDowntime;
$this->view->inDowntimeLink = Url::fromRequest()
->setPath('monitoring/list/downtimes');
$this->view->havingCommentsLink = Url::fromRequest()
->setPath('monitoring/list/comments');
$this->view->serviceStatesPieChart = $this->createPieChart(
$serviceStates,
$this->translate('Service State'),
array('#44bb77', '#FFCC66', '#FF5566', '#E066FF', '#77AAFF')
);
$this->view->hostStatesPieChart = $this->createPieChart(
$hostStates,
$this->translate('Host State'),
array('#44bb77', '#FF5566', '#E066FF', '#77AAFF')
);
}
protected function createPieChart(array $states, $title, array $colors)
{
$chart = new InlinePie(array_values($states), $title, $colors);
return $chart
->setLabel(array_map('strtoupper', array_keys($states)))
->setHeight(100)
->setWidth(100)
->setTitle($title);
}
/**
* Acknowledge service problems
*/
public function acknowledgeProblemAction()
{
$this->view->title = $this->translate('Acknowledge Service Problems');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
}
/**
* Reschedule service checks
*/
public function rescheduleCheckAction()
{
$this->view->title = $this->translate('Reschedule Service Checks');
$this->handleCommandForm(new ScheduleServiceCheckCommandForm());
}
/**
* Schedule service downtimes
*/
public function scheduleDowntimeAction()
{
$this->view->title = $this->translate('Schedule Service Downtimes');
$this->handleCommandForm(new ScheduleServiceDowntimeCommandForm());
}
}

View File

@ -5,6 +5,7 @@
use Icinga\Application\Benchmark;
use Icinga\Module\Monitoring\Object\MonitoredObject;
use Icinga\Web\Hook;
use Icinga\Web\Url;
use Icinga\Web\Widget\Tabs;
use Icinga\Web\Widget\Tabextension\OutputFormat;
use Icinga\Web\Widget\Tabextension\DashboardAction;
@ -35,14 +36,11 @@ class Monitoring_ShowController extends Controller
*/
public function init()
{
if ($this->getRequest()->getActionName() === 'host') {
$this->view->object = new Host($this->params);
} elseif ($this->getRequest()->getActionName() === 'service') {
$this->view->object = new Service($this->params);
} else {
// TODO: Well... this could be done better
$this->view->object = MonitoredObject::fromParams($this->params);
$this->view->object = MonitoredObject::fromParams($this->params);
if ($this->view->object->fetch() === false) {
throw new Zend_Controller_Action_Exception($this->translate('Host or service not found'));
}
if (Hook::has('ticket')) {
$this->view->tickets = Hook::first('ticket');
}
@ -57,36 +55,19 @@ class Monitoring_ShowController extends Controller
}
/**
* Service overview
* @deprecated
*/
public function serviceAction()
{
$o = $this->view->object;
$this->setAutorefreshInterval(10);
$this->view->title = $o->service_description
. ' on ' . $o->host_name;
$this->getTabs()->activate('service');
$o->populate();
if ($this->grapher) {
$this->view->grapherHtml = $this->grapher->getPreviewHtml($o);
}
$this->fetchHostStats();
$this->redirectNow(Url::fromRequest()->setPath('monitoring/service/show'));
}
/**
* Host overview
* @deprecated
*/
public function hostAction()
{
$o = $this->view->object;
$this->setAutorefreshInterval(10);
$this->getTabs()->activate('host');
$this->view->title = $o->host_name;
$o->populate();
if ($this->grapher) {
$this->view->grapherHtml = $this->grapher->getPreviewHtml($o);
}
$this->fetchHostStats();
$this->redirectNow(Url::fromRequest()->setPath('monitoring/host/show'));
}
public function historyAction()
@ -206,16 +187,17 @@ class Monitoring_ShowController extends Controller
if (($object = $this->view->object) === null) {
return;
}
$tabs = $this->getTabs();
$params = array(
'host' => $object->host_name,
);
if ($object instanceof Service) {
$params['service'] = $object->service_description;
} elseif ($service = $this->_getParam('service')) {
$params['service'] = $service;
if ($object->getType() === $object::TYPE_HOST) {
$params = array(
'host' => $object->getName()
);
} else {
$params = array(
'host' => $object->getHost()->getName(),
'service' => $object->getName()
);
}
$tabs = $this->getTabs();
$tabs->add(
'host',
array(

View File

@ -26,7 +26,7 @@ class Monitoring_TimelineController extends Controller
$detailUrl = Url::fromPath('monitoring/list/eventhistory');
$timeline = new TimeLine(
$this->backend->select()->from('eventHistory',
$this->backend->select()->from('eventHistory',
array(
'name' => 'type',
'time' => 'timestamp'

View File

@ -1,154 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Command;
use Icinga\Web\Form\Element\DateTimePicker;
use Icinga\Protocol\Commandpipe\Comment;
use Icinga\Util\DateTimeFactory;
use Icinga\Module\Monitoring\Command\AcknowledgeCommand;
/**
* Form for problem acknowledgements
*/
class AcknowledgeForm extends CommandForm
{
/**
* Create the form's elements
*/
protected function create()
{
$this->addNote(
t(
'This command is used to acknowledge host or service problems. When a problem is '
. 'acknowledged, future notifications about problems are temporarily disabled until the '
. 'host/service changes from its current state.'
)
);
$this->addElement($this->createAuthorField());
$this->addElement(
'textarea',
'comment',
array(
'label' => t('Comment'),
'rows' => 4,
'cols' => 72,
'required' => true,
'helptext' => t(
' If you work with other administrators you may find it useful to share information '
. 'about a host or service that is having problems if more than one of you may be working on '
. 'it. Make sure you enter a brief description of what you are doing.'
)
)
);
$this->addElement(
'checkbox',
'persistent',
array(
'label' => t('Persistent Comment'),
'value' => false,
'helptext' => t(
'If you would like the comment to remain even when the acknowledgement is removed, '
. 'check this option.'
)
)
);
$this->addElement(
'checkbox',
'expire',
array(
'label' => t('Use Expire Time'),
'helptext' => t('If the acknowledgement should expire, check this option.')
)
);
$this->enableAutoSubmit(array('expire'));
if ($this->getRequest()->getPost('expire', '0') === '1') {
$now = DateTimeFactory::create();
$this->addElement(
new DateTimePicker(
array(
'name' => 'expiretime',
'label' => t('Expire Time'),
'value' => $now->getTimestamp() + 3600,
'patterns' => $this->getValidDateTimeFormats(),
'helptext' => t(
'Enter the expire date/time for this acknowledgement here. Icinga will '
. ' delete the acknowledgement after this date expired.'
),
'jspicker' => true
)
)
);
}
$this->addElement(
'checkbox',
'sticky',
array(
'label' => t('Sticky Acknowledgement'),
'value' => true,
'helptext' => t(
'If you want the acknowledgement to disable notifications until the host/service '
. 'recovers, check this option.'
)
)
);
$this->addElement(
'checkbox',
'notify',
array(
'label' => t('Send Notification'),
'value' => true,
'helptext' => t(
'If you do not want an acknowledgement notification to be sent out to the appropriate '
. 'contacts, uncheck this option.'
)
)
);
$this->setSubmitLabel(t('Acknowledge Problem'));
parent::create();
}
/**
* Add validator for dependent fields
*
* @param array $data
*
* @see \Icinga\Web\Form::preValidation()
*/
protected function preValidation(array $data)
{
if (isset($data['expire']) && intval($data['expire']) === 1) {
$expireTime = $this->getElement('expiretime');
$expireTime->setRequired(true);
}
}
/**
* Create the acknowledgement command object
*
* @return AcknowledgeCommand
*/
public function createCommand()
{
return new AcknowledgeCommand(
new Comment(
$this->getAuthorName(),
$this->getValue('comment'),
$this->getValue('persistent')
),
$this->getValue('expire') ? $this->getValue('expire') : -1,
$this->getValue('notify'),
$this->getValue('sticky')
);
}
}

View File

@ -4,140 +4,61 @@
namespace Icinga\Module\Monitoring\Form\Command;
use Zend_Config;
use Zend_Controller_Request_Abstract;
use Zend_Form_Element_Hidden;
use Icinga\Module\Monitoring\Command\AcknowledgeCommand;
use Icinga\Module\Monitoring\Backend;
use Icinga\Module\Monitoring\Command\Transport\CommandTransport;
use Icinga\Web\Form;
use Icinga\Web\Request;
/**
* Simple confirmation command
* Base class for command forms
*/
abstract class CommandForm extends Form
{
/**
* If the form is for a global command
* Monitoring backend
*
* @var bool
* @var Backend
*/
protected $globalCommand = false;
protected $backend;
/**
* Set command program wide
* Set the monitoring backend
*
* @param bool $flag
* @param Backend $backend
*
* @return $this
*/
public function setProvideGlobalCommand($flag = true)
public function setBackend(Backend $backend)
{
$this->globalCommand = (boolean) $flag;
$this->backend = $backend;
return $this;
}
/**
* Getter for globalCommand
* Get the monitoring backend
*
* @return bool
* @return Backend
*/
public function provideGlobalCommand()
public function getBackend()
{
return (boolean) $this->globalCommand;
return $this->backend;
}
/**
* Create an instance name containing hidden field
* Get the transport used to send commands
*
* @return Zend_Form_Element_Hidden
*/
private function createInstanceHiddenField()
{
$field = new Zend_Form_Element_Hidden('instance');
$value = $this->getRequest()->getParam($field->getName());
$field->setValue($value);
return $field;
}
/**
* Add elements to this form (used by extending classes)
* @param Request $request
*
* @see Form::create
* @return \Icinga\Module\Monitoring\Command\Transport\CommandTransportInterface
*/
protected function create()
public function getTransport(Request $request)
{
$this->addElement($this->createInstanceHiddenField());
}
/**
* Get the author name
*
* @return string
*/
protected function getAuthorName()
{
if (is_a($this->getRequest(), "Zend_Controller_Request_HttpTestCase")) {
return "Test user";
$instance = $request->getParam('instance');
if ($instance !== null) {
$transport = CommandTransport::create($instance);
} else {
$transport = CommandTransport::first();
}
return $this->getRequest()->getUser()->getUsername();
return $transport;
}
/**
* Creator for author field
*
* @return Zend_Form_Element_Hidden
*/
protected function createAuthorField()
{
$authorName = $this->getAuthorName();
$authorField = new Zend_Form_Element_Hidden(
array(
'name' => 'author',
'label' => t('Author (Your Name)'),
'value' => $authorName,
'required' => true
)
);
$authorField->addDecorator(
'Callback',
array(
'callback' => function () use ($authorName) {
return sprintf('<strong>%s</strong>', $authorName);
}
)
);
return $authorField;
}
/**
* Get a list of valid datetime formats
*
* @return array
*/
public function getValidDateTimeFormats()
{
// TODO(mh): Missing localized format (#6077)
return array('d/m/Y g:i A');
}
/**
* Sets the form to global if we have data in the request
*
* @param Zend_Controller_Request_Abstract $request
*/
public function setRequest(Zend_Controller_Request_Abstract $request)
{
parent::setRequest($request);
if ($request->getParam('global')) {
$this->setProvideGlobalCommand(true);
}
}
/**
* Create command object for CommandPipe protocol
*
* @return AcknowledgeCommand
*/
abstract public function createCommand();
}

View File

@ -1,75 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Command;
use Icinga\Protocol\Commandpipe\Comment;
use Icinga\Module\Monitoring\Command\AddCommentCommand;
/**
* Form for adding comment commands
*/
class CommentForm extends CommandForm
{
/**
* Create the form's elements
*/
protected function create()
{
$this->setName('form_CommentForm');
$this->addNote(t('This command is used to add a comment to hosts or services.'));
$this->addElement($this->createAuthorField());
$this->addElement(
'textarea',
'comment',
array(
'label' => t('Comment'),
'rows' => 4,
'cols' => 72,
'required' => true,
'helptext' => t(
'If you work with other administrators, you may find it useful to share information '
. 'about a host or service that is having problems if more than one of you may be working on '
. 'it. Make sure you enter a brief description of what you are doing.'
)
)
);
$this->addElement(
'checkbox',
'persistent',
array(
'label' => t('Persistent'),
'value' => true,
'helptext' => t(
'If you uncheck this option, the comment will automatically be deleted the next time '
. 'Icinga is restarted.'
)
)
);
$this->setSubmitLabel(t('Post Comment'));
parent::create();
}
/**
* Create the command object to add comments
*
* @return AddCommentCommand
*/
public function createCommand()
{
return new AddCommentCommand(
new Comment(
$this->getAuthorName(),
$this->getValue('comment'),
$this->getValue('persistent')
)
);
}
}

Some files were not shown because too many files have changed in this diff Show More