diff --git a/application/controllers/GroupController.php b/application/controllers/GroupController.php
index ee692e109..0f0e9514d 100644
--- a/application/controllers/GroupController.php
+++ b/application/controllers/GroupController.php
@@ -131,7 +131,7 @@ class GroupController extends AuthBackendController
$removeForm->addElement('button', 'btn_submit', array(
'escape' => false,
'type' => 'submit',
- 'class' => 'link-like',
+ 'class' => 'link-like spinner',
'value' => 'btn_submit',
'decorators' => array('ViewHelper'),
'label' => $this->view->icon('trash'),
diff --git a/application/controllers/UserController.php b/application/controllers/UserController.php
index 46c1b5381..a5fec106a 100644
--- a/application/controllers/UserController.php
+++ b/application/controllers/UserController.php
@@ -137,7 +137,7 @@ class UserController extends AuthBackendController
$removeForm->addElement('button', 'btn_submit', array(
'escape' => false,
'type' => 'submit',
- 'class' => 'link-like',
+ 'class' => 'link-like spinner',
'value' => 'btn_submit',
'decorators' => array('ViewHelper'),
'label' => $this->view->icon('trash'),
diff --git a/application/forms/Authentication/LoginForm.php b/application/forms/Authentication/LoginForm.php
index f7bae3d1b..9646046f6 100644
--- a/application/forms/Authentication/LoginForm.php
+++ b/application/forms/Authentication/LoginForm.php
@@ -27,6 +27,7 @@ class LoginForm extends Form
$this->setRequiredCue(null);
$this->setName('form_login');
$this->setSubmitLabel($this->translate('Login'));
+ $this->setProgressLabel($this->translate('Logging in'));
}
/**
diff --git a/application/forms/Config/General/ApplicationConfigForm.php b/application/forms/Config/General/ApplicationConfigForm.php
index 618178344..4e431aab2 100644
--- a/application/forms/Config/General/ApplicationConfigForm.php
+++ b/application/forms/Config/General/ApplicationConfigForm.php
@@ -25,6 +25,20 @@ class ApplicationConfigForm extends Form
*/
public function createElements(array $formData)
{
+ $this->addElement(
+ 'checkbox',
+ 'global_show_stacktraces',
+ array(
+ 'required' => true,
+ 'value' => true,
+ 'label' => $this->translate('Show Stacktraces'),
+ 'description' => $this->translate(
+ 'Set whether to show an exception\'s stacktrace by default. This can also'
+ . ' be set in a user\'s preferences with the appropriate permission.'
+ )
+ )
+ );
+
$this->addElement(
'text',
'global_module_path',
diff --git a/application/forms/Config/Resource/LdapResourceForm.php b/application/forms/Config/Resource/LdapResourceForm.php
index c6e452d2c..d20ec55af 100644
--- a/application/forms/Config/Resource/LdapResourceForm.php
+++ b/application/forms/Config/Resource/LdapResourceForm.php
@@ -81,22 +81,6 @@ class LdapResourceForm extends Form
)
);
- if (isset($formData['encryption']) && $formData['encryption'] !== 'none') {
- // TODO(jom): Do not show this checkbox unless the connection is actually failing due to certificate errors
- $this->addElement(
- 'checkbox',
- 'reqcert',
- array(
- 'required' => true,
- 'label' => $this->translate('Require Certificate'),
- 'description' => $this->translate(
- 'When checked, the LDAP server must provide a valid and known (trusted) certificate.'
- ),
- 'value' => 1
- )
- );
- }
-
$this->addElement(
'text',
'root_dn',
diff --git a/application/forms/Config/ResourceConfigForm.php b/application/forms/Config/ResourceConfigForm.php
index 51e1b1bff..db951e67a 100644
--- a/application/forms/Config/ResourceConfigForm.php
+++ b/application/forms/Config/ResourceConfigForm.php
@@ -344,9 +344,10 @@ class ResourceConfigForm extends ConfigForm
'submit',
'resource_validation',
array(
- 'ignore' => true,
- 'label' => $this->translate('Validate Configuration'),
- 'decorators' => array('ViewHelper')
+ 'ignore' => true,
+ 'label' => $this->translate('Validate Configuration'),
+ 'data-progress-label' => $this->translate('Validation In Progress'),
+ 'decorators' => array('ViewHelper')
)
);
$this->addDisplayGroup(
diff --git a/application/forms/Config/UserBackendConfigForm.php b/application/forms/Config/UserBackendConfigForm.php
index 5ee4674bb..1183ae724 100644
--- a/application/forms/Config/UserBackendConfigForm.php
+++ b/application/forms/Config/UserBackendConfigForm.php
@@ -464,9 +464,10 @@ class UserBackendConfigForm extends ConfigForm
'submit',
'backend_validation',
array(
- 'ignore' => true,
- 'label' => $this->translate('Validate Configuration'),
- 'decorators' => array('ViewHelper')
+ 'ignore' => true,
+ 'label' => $this->translate('Validate Configuration'),
+ 'data-progress-label' => $this->translate('Validation In Progress'),
+ 'decorators' => array('ViewHelper')
)
);
$this->addDisplayGroup(
diff --git a/application/forms/PreferenceForm.php b/application/forms/PreferenceForm.php
index b329ae1d4..e9aca1d26 100644
--- a/application/forms/PreferenceForm.php
+++ b/application/forms/PreferenceForm.php
@@ -5,6 +5,7 @@ namespace Icinga\Forms;
use Exception;
use DateTimeZone;
+use Icinga\Application\Config;
use Icinga\Application\Logger;
use Icinga\Authentication\Auth;
use Icinga\User\Preferences;
@@ -178,6 +179,19 @@ class PreferenceForm extends Form
)
);
+ if (Auth::getInstance()->hasPermission('application/stacktraces')) {
+ $this->addElement(
+ 'checkbox',
+ 'show_stacktraces',
+ array(
+ 'required' => true,
+ 'value' => $this->getDefaultShowStacktraces(),
+ 'label' => $this->translate('Show Stacktraces'),
+ 'description' => $this->translate('Set whether to show an exception\'s stacktrace.')
+ )
+ );
+ }
+
$this->addElement(
'checkbox',
'show_benchmark',
@@ -220,8 +234,20 @@ class PreferenceForm extends Form
)
);
+ $this->setAttrib('data-progress-element', 'preferences-progress');
+ $this->addElement(
+ 'note',
+ 'preferences-progress',
+ array(
+ 'decorators' => array(
+ 'ViewHelper',
+ array('Spinner', array('id' => 'preferences-progress'))
+ )
+ )
+ );
+
$this->addDisplayGroup(
- array('btn_submit_preferences', 'btn_submit_session'),
+ array('btn_submit_preferences', 'btn_submit_session', 'preferences-progress'),
'submit_buttons',
array(
'decorators' => array(
@@ -257,4 +283,14 @@ class PreferenceForm extends Form
$locale = Translator::getPreferredLocaleCode($_SERVER['HTTP_ACCEPT_LANGUAGE']);
return $locale;
}
+
+ /**
+ * Return the default global setting for show_stacktraces
+ *
+ * @return bool
+ */
+ protected function getDefaultShowStacktraces()
+ {
+ return Config::app()->get('global', 'show_stacktraces', true);
+ }
}
diff --git a/application/forms/Security/RoleForm.php b/application/forms/Security/RoleForm.php
index dba7ebe9f..212776bac 100644
--- a/application/forms/Security/RoleForm.php
+++ b/application/forms/Security/RoleForm.php
@@ -20,35 +20,7 @@ class RoleForm extends ConfigForm
*
* @var array
*/
- protected $providedPermissions = array(
- '*' => 'Allow everything (*)',
- 'config/*' => 'Allow config access (config/*)',
-/*
- // [tg] seems excessive for me, hidden for rc1, tbd
- 'config/application/*' => 'config/application/*',
- 'config/application/general' => 'config/application/general',
- 'config/application/resources' => 'config/application/resources',
- 'config/application/userbackend' => 'config/application/userbackend',
- 'config/application/usergroupbackend' => 'config/application/usergroupbackend',
- 'config/authentication/*' => 'config/authentication/*',
- 'config/authentication/users/*' => 'config/authentication/users/*',
- 'config/authentication/users/show' => 'config/authentication/users/show',
- 'config/authentication/users/add' => 'config/authentication/users/add',
- 'config/authentication/users/edit' => 'config/authentication/users/edit',
- 'config/authentication/users/remove' => 'config/authentication/users/remove',
- 'config/authentication/groups/*' => 'config/authentication/groups/*',
- 'config/authentication/groups/show' => 'config/authentication/groups/show',
- 'config/authentication/groups/add' => 'config/authentication/groups/add',
- 'config/authentication/groups/edit' => 'config/authentication/groups/edit',
- 'config/authentication/groups/remove' => 'config/authentication/groups/remove',
- 'config/authentication/roles/*' => 'config/authentication/roles/*',
- 'config/authentication/roles/show' => 'config/authentication/roles/show',
- 'config/authentication/roles/add' => 'config/authentication/roles/add',
- 'config/authentication/roles/edit' => 'config/authentication/roles/edit',
- 'config/authentication/roles/remove' => 'config/authentication/roles/remove',
- 'config/modules' => 'config/modules'
-*/
- );
+ protected $providedPermissions;
/**
* Provided restrictions by currently loaded modules
@@ -62,6 +34,40 @@ class RoleForm extends ConfigForm
*/
public function init()
{
+ $this->providedPermissions = array(
+ '*' => $this->translate('Allow everything') . ' (*)',
+ 'application/stacktraces' => $this->translate(
+ 'Allow to adjust in the preferences whether to show stacktraces'
+ ) . ' (application/stacktraces)',
+ 'config/*' => $this->translate('Allow config access') . ' (config/*)',
+/*
+ // [tg] seems excessive for me, hidden for rc1, tbd
+ 'config/application/*' => 'config/application/*',
+ 'config/application/general' => 'config/application/general',
+ 'config/application/resources' => 'config/application/resources',
+ 'config/application/userbackend' => 'config/application/userbackend',
+ 'config/application/usergroupbackend' => 'config/application/usergroupbackend',
+ 'config/authentication/*' => 'config/authentication/*',
+ 'config/authentication/users/*' => 'config/authentication/users/*',
+ 'config/authentication/users/show' => 'config/authentication/users/show',
+ 'config/authentication/users/add' => 'config/authentication/users/add',
+ 'config/authentication/users/edit' => 'config/authentication/users/edit',
+ 'config/authentication/users/remove' => 'config/authentication/users/remove',
+ 'config/authentication/groups/*' => 'config/authentication/groups/*',
+ 'config/authentication/groups/show' => 'config/authentication/groups/show',
+ 'config/authentication/groups/add' => 'config/authentication/groups/add',
+ 'config/authentication/groups/edit' => 'config/authentication/groups/edit',
+ 'config/authentication/groups/remove' => 'config/authentication/groups/remove',
+ 'config/authentication/roles/*' => 'config/authentication/roles/*',
+ 'config/authentication/roles/show' => 'config/authentication/roles/show',
+ 'config/authentication/roles/add' => 'config/authentication/roles/add',
+ 'config/authentication/roles/edit' => 'config/authentication/roles/edit',
+ 'config/authentication/roles/remove' => 'config/authentication/roles/remove',
+ 'config/modules' => 'config/modules'
+*/
+ );
+
+
$helper = new Zend_Form_Element('bogus');
$mm = Icinga::app()->getModuleManager();
foreach ($mm->listInstalledModules() as $moduleName) {
diff --git a/application/views/scripts/form/reorder-authbackend.phtml b/application/views/scripts/form/reorder-authbackend.phtml
index ec1cf7810..4edc7e06f 100644
--- a/application/views/scripts/form/reorder-authbackend.phtml
+++ b/application/views/scripts/form/reorder-authbackend.phtml
@@ -39,7 +39,7 @@
0): ?>
- |
-
+ |
populate(
diff --git a/modules/monitoring/application/views/scripts/list/downtimes.phtml b/modules/monitoring/application/views/scripts/list/downtimes.phtml
index 1125aa9ba..a45bd0499 100644
--- a/modules/monitoring/application/views/scripts/list/downtimes.phtml
+++ b/modules/monitoring/application/views/scripts/list/downtimes.phtml
@@ -126,7 +126,7 @@ if (! $this->compact): ?>
|
-
+ |
populate(
diff --git a/modules/monitoring/configuration.php b/modules/monitoring/configuration.php
index 8844c3247..fa95c3785 100644
--- a/modules/monitoring/configuration.php
+++ b/modules/monitoring/configuration.php
@@ -89,17 +89,34 @@ $this->provideSearchUrl($this->translate('Servicegroups'), 'monitoring/list/serv
* Problems Section
*/
$section = $this->menuSection($this->translate('Problems'), array(
- 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\ProblemMenuItemRenderer',
+ 'renderer' => array(
+ 'SummaryMenuItemRenderer',
+ 'state' => 'critical'
+ ),
'icon' => 'block',
'priority' => 20
));
$section->add($this->translate('Unhandled Hosts'), array(
- 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\UnhandledHostMenuItemRenderer',
+ 'renderer' => array(
+ 'Icinga\Module\Monitoring\Web\Menu\MonitoringBadgeMenuItemRenderer',
+ 'columns' => array(
+ 'hosts_down_unhandled' => $this->translate('%d unhandled hosts down')
+ ),
+ 'state' => 'critical',
+ 'dataView' => 'statussummary'
+ ),
'url' => 'monitoring/list/hosts?host_problem=1&host_handled=0',
'priority' => 30
));
$section->add($this->translate('Unhandled Services'), array(
- 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\UnhandledServiceMenuItemRenderer',
+ 'renderer' => array(
+ 'Icinga\Module\Monitoring\Web\Menu\MonitoringBadgeMenuItemRenderer',
+ 'columns' => array(
+ 'services_critical_unhandled' => $this->translate('%d unhandled services critical')
+ ),
+ 'state' => 'critical',
+ 'dataView' => 'statussummary'
+ ),
'url' => 'monitoring/list/services?service_problem=1&service_handled=0&sort=service_severity',
'priority' => 40
));
@@ -204,7 +221,7 @@ $section = $this->menuSection($this->translate('System'));
$section->add($this->translate('Monitoring Health'), array(
'url' => 'monitoring/process/info',
'priority' => 720,
- 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\BackendAvailabilityMenuItemRenderer'
+ 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\BackendAvailabilityMenuItemRenderer'
));
/*
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php
index 85d9169a9..c8d2e3140 100644
--- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php
@@ -479,8 +479,12 @@ abstract class IdoQuery extends DbQuery
}
}
+ /**
+ * {@inheritdoc}
+ */
public function addFilter(Filter $filter)
{
+ $filter = clone $filter;
$this->requireFilterColumns($filter);
return parent::addFilter($filter);
}
diff --git a/modules/monitoring/library/Monitoring/MonitoringWizard.php b/modules/monitoring/library/Monitoring/MonitoringWizard.php
index 0a224610c..4b495c36e 100644
--- a/modules/monitoring/library/Monitoring/MonitoringWizard.php
+++ b/modules/monitoring/library/Monitoring/MonitoringWizard.php
@@ -120,9 +120,10 @@ class MonitoringWizard extends Wizard implements SetupWizard
'submit',
'backend_validation',
array(
- 'ignore' => true,
- 'label' => t('Validate Configuration'),
- 'decorators' => array('ViewHelper')
+ 'ignore' => true,
+ 'label' => t('Validate Configuration'),
+ 'data-progress-label' => t('Validation In Progress'),
+ 'decorators' => array('ViewHelper')
)
);
$page->getDisplayGroup('buttons')->addElement($page->getElement('backend_validation'));
diff --git a/modules/monitoring/library/Monitoring/Web/Menu/BackendAvailabilityMenuItemRenderer.php b/modules/monitoring/library/Monitoring/Web/Menu/BackendAvailabilityMenuItemRenderer.php
index f65f25993..ca589d3cb 100644
--- a/modules/monitoring/library/Monitoring/Web/Menu/BackendAvailabilityMenuItemRenderer.php
+++ b/modules/monitoring/library/Monitoring/Web/Menu/BackendAvailabilityMenuItemRenderer.php
@@ -4,10 +4,10 @@
namespace Icinga\Module\Monitoring\Web\Menu;
use Icinga\Web\Menu;
-use Icinga\Web\Menu\MenuItemRenderer;
+use Icinga\Web\Menu\BadgeMenuItemRenderer;
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
-class BackendAvailabilityMenuItemRenderer extends MenuItemRenderer
+class BackendAvailabilityMenuItemRenderer extends BadgeMenuItemRenderer
{
/**
* Get whether or not the monitoring backend is currently running
@@ -27,47 +27,39 @@ class BackendAvailabilityMenuItemRenderer extends MenuItemRenderer
}
/**
- * {@inheritdoc}
- */
- public function render(Menu $menu)
- {
- return $this->getBadge() . $this->createLink($menu);
- }
-
- /**
- * Get the problem badge HTML
+ * The css class of the badge
*
* @return string
*/
- protected function getBadge()
+ public function getState()
{
- if (! $this->isCurrentlyRunning()) {
- return sprintf(
- ' %d ',
- sprintf(
- mt('monitoring', 'Monitoring backend %s is not running'), MonitoringBackend::instance()->getName()
- ),
- 1
- );
- }
- return '';
+ return self::STATE_CRITICAL;
}
/**
- * Get the problem data for the summary
+ * The amount of items to display in the badge
*
- * @return array|null
+ * @return int
*/
- public function getSummary()
+ public function getCount()
{
if (! $this->isCurrentlyRunning()) {
- return array(
- 'problems' => 1,
- 'title' => sprintf(
- mt('monitoring', 'Monitoring backend %s is not running'), MonitoringBackend::instance()->getName()
- )
- );
+ return 1;
}
- return null;
+ return 0;
+ }
+
+ /**
+ * The tooltip title
+ *
+ * @return string
+ * @throws \Icinga\Exception\ConfigurationError
+ */
+ public function getTitle()
+ {
+ return sprintf(
+ mt('monitoring', 'Monitoring backend %s is not running'),
+ MonitoringBackend::instance()->getName()
+ );
}
}
diff --git a/modules/monitoring/library/Monitoring/Web/Menu/MonitoringBadgeMenuItemRenderer.php b/modules/monitoring/library/Monitoring/Web/Menu/MonitoringBadgeMenuItemRenderer.php
new file mode 100644
index 000000000..90d02fe52
--- /dev/null
+++ b/modules/monitoring/library/Monitoring/Web/Menu/MonitoringBadgeMenuItemRenderer.php
@@ -0,0 +1,183 @@
+columns = $configuration->get('columns');
+ $this->state = $configuration->get('state');
+ $this->dataView = $configuration->get('dataView');
+
+ // clear the outdated summary cache, since new columns are being added. Optimally all menu item are constructed
+ // before any rendering is going on to avoid trashing too man old requests
+ if (isset(self::$summaries[$this->dataView])) {
+ unset(self::$summaries[$this->dataView]);
+ }
+
+ // add the new columns to this view
+ if (! isset(self::$dataViews[$this->dataView])) {
+ self::$dataViews[$this->dataView] = array();
+ }
+ foreach ($this->columns as $column => $title) {
+ if (! array_search($column, self::$dataViews[$this->dataView])) {
+ self::$dataViews[$this->dataView][] = $column;
+ }
+ $this->titles[$column] = $title;
+ }
+ }
+
+ /**
+ * Apply a restriction on the given data view
+ *
+ * @param string $restriction The name of restriction
+ * @param Filterable $filterable The filterable to restrict
+ *
+ * @return Filterable The filterable
+ */
+ protected static function applyRestriction($restriction, Filterable $filterable)
+ {
+ $restrictions = Filter::matchAny();
+ foreach (Auth::getInstance()->getRestrictions($restriction) as $filter) {
+ $restrictions->addFilter(Filter::fromQueryString($filter));
+ }
+ $filterable->applyFilter($restrictions);
+ return $filterable;
+ }
+
+ /**
+ * Fetch the response from the database or access cache
+ *
+ * @param $view
+ *
+ * @return null
+ * @throws \Icinga\Exception\ConfigurationError
+ */
+ protected static function summary($view)
+ {
+ if (! isset(self::$summaries[$view])) {
+ $summary = MonitoringBackend::instance()->select()->from(
+ $view,
+ self::$dataViews[$view]
+ );
+ static::applyRestriction('monitoring/filter/objects', $summary);
+ self::$summaries[$view] = $summary->fetchRow();
+ }
+ return isset(self::$summaries[$view]) ? self::$summaries[$view] : null;
+ }
+
+ /**
+ * Defines the color of the badge
+ *
+ * @return string
+ */
+ public function getState()
+ {
+ return $this->state;
+ }
+
+ /**
+ * The amount of items to display in the badge
+ *
+ * @return int
+ */
+ public function getCount()
+ {
+ $sum = self::summary($this->dataView);
+ $count = 0;
+
+ foreach ($this->columns as $col => $title) {
+ if (isset($sum->$col)) {
+ $count += $sum->$col;
+ }
+ }
+ return $count;
+ }
+
+ /**
+ * The tooltip title
+ *
+ * @return string
+ */
+ public function getTitle()
+ {
+ $titles = array();
+ $sum = $this->summary($this->dataView);
+ foreach ($this->columns as $column => $value) {
+ if (isset($sum->$column) && $sum->$column > 0) {
+ $titles[] = sprintf($this->titles[$column], $sum->$column);
+ }
+ }
+ return implode(', ', $titles);
+ }
+}
diff --git a/modules/monitoring/library/Monitoring/Web/Menu/MonitoringMenuItemRenderer.php b/modules/monitoring/library/Monitoring/Web/Menu/MonitoringMenuItemRenderer.php
deleted file mode 100644
index df901b165..000000000
--- a/modules/monitoring/library/Monitoring/Web/Menu/MonitoringMenuItemRenderer.php
+++ /dev/null
@@ -1,109 +0,0 @@
-getRestrictions($restriction) as $filter) {
- $restrictions->addFilter(Filter::fromQueryString($filter));
- }
- $filterable->applyFilter($restrictions);
- return $filterable;
- }
-
- protected static function summary($column = null)
- {
- if (self::$summary === null) {
- $summary = MonitoringBackend::instance()->select()->from(
- 'statussummary',
- array(
- 'hosts_down_unhandled',
- 'services_critical_unhandled'
- )
- );
- static::applyRestriction('monitoring/filter/objects', $summary);
- self::$summary = $summary->fetchRow();
- }
-
- if ($column === null) {
- return self::$summary;
- } elseif (isset(self::$summary->$column)) {
- return self::$summary->$column;
- } else {
- return null;
- }
- }
-
- protected function getBadgeTitle()
- {
- $translations = array(
- 'hosts_down_unhandled' => mt('monitoring', '%d unhandled hosts down'),
- 'services_critical_unhandled' => mt('monitoring', '%d unhandled services critical')
- );
-
- $titles = array();
- $sum = $this->summary();
-
- foreach ($this->columns as $col) {
- if (isset($sum->$col) && $sum->$col > 0) {
- $titles[] = sprintf($translations[$col], $sum->$col);
- }
- }
-
- return implode(', ', $titles);
- }
-
- protected function countItems()
- {
- $sum = self::summary();
- $count = 0;
-
- foreach ($this->columns as $col) {
- if (isset($sum->$col)) {
- $count += $sum->$col;
- }
- }
-
- return $count;
- }
-
- public function render(Menu $menu)
- {
- return $this->getBadge() . $this->createLink($menu);
- }
-
- protected function getBadge()
- {
- if ($count = $this->countItems()) {
- return sprintf(
- '%s ',
- $this->getBadgeTitle(),
- $count
- );
- }
- return '';
- }
-}
diff --git a/modules/monitoring/library/Monitoring/Web/Menu/ProblemMenuItemRenderer.php b/modules/monitoring/library/Monitoring/Web/Menu/ProblemMenuItemRenderer.php
deleted file mode 100644
index d17431398..000000000
--- a/modules/monitoring/library/Monitoring/Web/Menu/ProblemMenuItemRenderer.php
+++ /dev/null
@@ -1,12 +0,0 @@
-
- |