diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:46:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:46:43 +0000 |
commit | 3e02d5aff85babc3ffbfcf52313f2108e313aa23 (patch) | |
tree | b01f3923360c20a6a504aff42d45670c58af3ec5 /modules/monitoring/application/forms | |
parent | Initial commit. (diff) | |
download | icingaweb2-upstream.tar.xz icingaweb2-upstream.zip |
Adding upstream version 2.12.1.upstream/2.12.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules/monitoring/application/forms')
36 files changed, 4479 insertions, 0 deletions
diff --git a/modules/monitoring/application/forms/Command/CommandForm.php b/modules/monitoring/application/forms/Command/CommandForm.php new file mode 100644 index 0000000..34391cf --- /dev/null +++ b/modules/monitoring/application/forms/Command/CommandForm.php @@ -0,0 +1,92 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command; + +use Icinga\Exception\ConfigurationError; +use Icinga\Web\Form; +use Icinga\Web\Request; +use Icinga\Module\Monitoring\Backend\MonitoringBackend; +use Icinga\Module\Monitoring\Command\Transport\CommandTransport; +use Icinga\Module\Monitoring\Command\Transport\CommandTransportInterface; + +/** + * Base class for command forms + */ +abstract class CommandForm extends Form +{ + /** + * Monitoring backend + * + * @var MonitoringBackend + */ + protected $backend; + + /** + * Set the monitoring backend + * + * @param MonitoringBackend $backend + * + * @return $this + */ + public function setBackend(MonitoringBackend $backend) + { + $this->backend = $backend; + return $this; + } + + /** + * Get the monitoring backend + * + * @return MonitoringBackend + */ + public function getBackend() + { + return $this->backend; + } + + /** + * Get the transport used to send commands + * + * @param Request $request + * + * @return CommandTransportInterface + * + * @throws ConfigurationError + */ + public function getTransport(Request $request) + { + if (($transportName = $request->getParam('transport')) !== null) { + $config = CommandTransport::getConfig(); + if ($config->hasSection($transportName)) { + $transport = CommandTransport::createTransport($config->getSection($transportName)); + } else { + throw new ConfigurationError(sprintf( + mt('monitoring', 'Command transport "%s" not found.'), + $transportName + )); + } + } else { + $transport = new CommandTransport(); + } + + return $transport; + } + + /** + * {@inheritdoc} + */ + public function getRedirectUrl() + { + $redirectUrl = parent::getRedirectUrl(); + // TODO(el): Forms should provide event handling. This is quite hackish + $formData = $this->getRequestData(); + if ($this->wasSent($formData) + && (! $this->getSubmitLabel() || $this->isSubmitted()) + && $this->isValid($formData) + ) { + $this->getResponse()->setAutoRefreshInterval(1); + } + return $redirectUrl; + } +} diff --git a/modules/monitoring/application/forms/Command/Instance/DisableNotificationsExpireCommandForm.php b/modules/monitoring/application/forms/Command/Instance/DisableNotificationsExpireCommandForm.php new file mode 100644 index 0000000..ee49962 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Instance/DisableNotificationsExpireCommandForm.php @@ -0,0 +1,64 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Instance; + +use DateTime; +use DateInterval; +use Icinga\Module\Monitoring\Command\Instance\DisableNotificationsExpireCommand; +use Icinga\Module\Monitoring\Forms\Command\CommandForm; +use Icinga\Web\Notification; + +/** + * Form for disabling host and service notifications w/ an optional expire date and time on an Icinga instance + */ +class DisableNotificationsExpireCommandForm extends CommandForm +{ + /** + * (non-PHPDoc) + * @see \Zend_Form::init() For the method documentation. + */ + public function init() + { + $this->setRequiredCue(null); + $this->setSubmitLabel($this->translate('Disable Notifications')); + $this->addDescription($this->translate( + 'This command is used to disable host and service notifications for a specific time.' + )); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + $expireTime = new DateTime(); + $expireTime->add(new DateInterval('PT1H')); + $this->addElement( + 'dateTimePicker', + 'expire_time', + array( + 'required' => true, + 'label' => $this->translate('Expire Time'), + 'description' => $this->translate('Set the expire time.'), + 'value' => $expireTime + ) + ); + return $this; + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + $disableNotifications = new DisableNotificationsExpireCommand(); + $disableNotifications + ->setExpireTime($this->getElement('expire_time')->getValue()->getTimestamp()); + $this->getTransport($this->request)->send($disableNotifications); + Notification::success($this->translate('Disabling host and service notifications..')); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php b/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php new file mode 100644 index 0000000..8b01399 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php @@ -0,0 +1,279 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Instance; + +use Icinga\Module\Monitoring\Command\Instance\ToggleInstanceFeatureCommand; +use Icinga\Module\Monitoring\Forms\Command\CommandForm; +use Icinga\Web\Notification; + +/** + * Form for enabling or disabling features of Icinga instances + */ +class ToggleInstanceFeaturesCommandForm extends CommandForm +{ + /** + * Instance status + * + * @var object + */ + protected $status; + + /** + * (non-PHPDoc) + * @see \Zend_Form::init() For the method documentation. + */ + public function init() + { + $this->setUseFormAutosubmit(); + $this->setAttrib('class', self::DEFAULT_CLASSES . ' instance-features'); + } + + /** + * Set the instance status + * + * @param object $status + * + * @return $this + */ + public function setStatus($status) + { + $this->status = (object) $status; + return $this; + } + + /** + * Get the instance status + * + * @return object + */ + public function getStatus() + { + return $this->status; + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + $notificationDescription = null; + $isIcinga2 = $this->getBackend()->isIcinga2($this->status->program_version); + + if (! $isIcinga2) { + if ((bool) $this->status->notifications_enabled) { + if ($this->hasPermission('monitoring/command/feature/instance')) { + $notificationDescription = sprintf( + '<a aria-label="%1$s" class="action-link" title="%1$s"' + . ' href="%2$s" data-base-target="_next">%3$s</a>', + $this->translate('Disable notifications for a specific time on a program-wide basis'), + $this->getView()->href('monitoring/health/disable-notifications'), + $this->translate('Disable temporarily') + ); + } else { + $notificationDescription = null; + } + } elseif ($this->status->disable_notif_expire_time) { + $notificationDescription = sprintf( + $this->translate('Notifications will be re-enabled in <strong>%s</strong>'), + $this->getView()->timeUntil($this->status->disable_notif_expire_time) + ); + } + } + + $toggleDisabled = $this->hasPermission('monitoring/command/feature/instance') ? null : ''; + + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_ACTIVE_HOST_CHECKS, + array( + 'label' => $this->translate('Active Host Checks'), + 'autosubmit' => true, + 'disabled' => $toggleDisabled + ) + ); + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_ACTIVE_SERVICE_CHECKS, + array( + 'label' => $this->translate('Active Service Checks'), + 'autosubmit' => true, + 'disabled' => $toggleDisabled + ) + ); + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_EVENT_HANDLERS, + array( + 'label' => $this->translate('Event Handlers'), + 'autosubmit' => true, + 'disabled' => $toggleDisabled + ) + ); + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_FLAP_DETECTION, + array( + 'label' => $this->translate('Flap Detection'), + 'autosubmit' => true, + 'disabled' => $toggleDisabled + ) + ); + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_NOTIFICATIONS, + array( + 'label' => $this->translate('Notifications'), + 'autosubmit' => true, + 'description' => $notificationDescription, + 'decorators' => array( + array('Label', array('tag'=>'span', 'separator' => '', 'class' => 'control-label')), + array( + 'Description', + array('tag' => 'span', 'class' => 'description', 'escape' => false) + ), + array(array('labelWrap' => 'HtmlTag'), array('tag' => 'div', 'class' => 'control-label-group')), + array('ViewHelper', array('separator' => '')), + array('Errors', array('separator' => '')), + array('HtmlTag', array('tag' => 'div', 'class' => 'control-group')) + ), + 'disabled' => $toggleDisabled + ) + ); + + if (! $isIcinga2) { + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_HOST_OBSESSING, + array( + 'label' => $this->translate('Obsessing Over Hosts'), + 'autosubmit' => true, + 'disabled' => $toggleDisabled + ) + ); + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_SERVICE_OBSESSING, + array( + 'label' => $this->translate('Obsessing Over Services'), + 'autosubmit' => true, + 'disabled' => $toggleDisabled + ) + ); + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_PASSIVE_HOST_CHECKS, + array( + 'label' => $this->translate('Passive Host Checks'), + 'autosubmit' => true, + 'disabled' => $toggleDisabled + ) + ); + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_PASSIVE_SERVICE_CHECKS, + array( + 'label' => $this->translate('Passive Service Checks'), + 'autosubmit' => true, + 'disabled' => $toggleDisabled + ) + ); + } + + $this->addElement( + 'checkbox', + ToggleInstanceFeatureCommand::FEATURE_PERFORMANCE_DATA, + array( + 'label' => $this->translate('Performance Data'), + 'autosubmit' => true, + 'disabled' => $toggleDisabled + ) + ); + } + + /** + * Load feature status + * + * @param object $instanceStatus + * + * @return $this + */ + public function load($instanceStatus) + { + $this->create(); + foreach ($this->getValues() as $feature => $enabled) { + $this->getElement($feature)->setChecked($instanceStatus->{$feature}); + } + + return $this; + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + $this->assertPermission('monitoring/command/feature/instance'); + + $notifications = array( + ToggleInstanceFeatureCommand::FEATURE_ACTIVE_HOST_CHECKS => array( + $this->translate('Enabling active host checks..'), + $this->translate('Disabling active host checks..') + ), + ToggleInstanceFeatureCommand::FEATURE_ACTIVE_SERVICE_CHECKS => array( + $this->translate('Enabling active service checks..'), + $this->translate('Disabling active service checks..') + ), + ToggleInstanceFeatureCommand::FEATURE_EVENT_HANDLERS => array( + $this->translate('Enabling event handlers..'), + $this->translate('Disabling event handlers..') + ), + ToggleInstanceFeatureCommand::FEATURE_FLAP_DETECTION => array( + $this->translate('Enabling flap detection..'), + $this->translate('Disabling flap detection..') + ), + ToggleInstanceFeatureCommand::FEATURE_NOTIFICATIONS => array( + $this->translate('Enabling notifications..'), + $this->translate('Disabling notifications..') + ), + ToggleInstanceFeatureCommand::FEATURE_HOST_OBSESSING => array( + $this->translate('Enabling obsessing over hosts..'), + $this->translate('Disabling obsessing over hosts..') + ), + ToggleInstanceFeatureCommand::FEATURE_SERVICE_OBSESSING => array( + $this->translate('Enabling obsessing over services..'), + $this->translate('Disabling obsessing over services..') + ), + ToggleInstanceFeatureCommand::FEATURE_PASSIVE_HOST_CHECKS => array( + $this->translate('Enabling passive host checks..'), + $this->translate('Disabling passive host checks..') + ), + ToggleInstanceFeatureCommand::FEATURE_PASSIVE_SERVICE_CHECKS => array( + $this->translate('Enabling passive service checks..'), + $this->translate('Disabling passive service checks..') + ), + ToggleInstanceFeatureCommand::FEATURE_PERFORMANCE_DATA => array( + $this->translate('Enabling performance data..'), + $this->translate('Disabling performance data..') + ) + ); + + foreach ($this->getValues() as $feature => $enabled) { + if ((bool) $this->status->{$feature} !== (bool) $enabled) { + $toggleFeature = new ToggleInstanceFeatureCommand(); + $toggleFeature + ->setFeature($feature) + ->setEnabled($enabled); + $this->getTransport($this->request)->send($toggleFeature); + + Notification::success( + $notifications[$feature][$enabled ? 0 : 1] + ); + } + } + + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/AcknowledgeProblemCommandForm.php b/modules/monitoring/application/forms/Command/Object/AcknowledgeProblemCommandForm.php new file mode 100644 index 0000000..c7caf5d --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/AcknowledgeProblemCommandForm.php @@ -0,0 +1,172 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use DateTime; +use DateInterval; +use Icinga\Application\Config; +use Icinga\Module\Monitoring\Command\Object\AcknowledgeProblemCommand; +use Icinga\Web\Notification; + +/** + * Form for acknowledging host or service problems + */ +class AcknowledgeProblemCommandForm extends ObjectsCommandForm +{ + /** + * Initialize this form + */ + public function init() + { + $this->addDescription($this->translate( + '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 or service' + . ' recovers.' + )); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + */ + public function getSubmitLabel() + { + return $this->translatePlural('Acknowledge problem', 'Acknowledge problems', count($this->objects)); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + $config = Config::module('monitoring'); + + $acknowledgeExpire = (bool) $config->get('settings', 'acknowledge_expire', false); + + $this->addElements(array( + array( + 'textarea', + 'comment', + array( + 'required' => true, + 'label' => $this->translate('Comment'), + 'description' => $this->translate( + 'If you work with other administrators, you may find it useful to share information about' + . ' the host or service that is having problems. Make sure you enter a brief description of' + . ' what you are doing.' + ), + 'attribs' => array('class' => 'autofocus') + ) + ), + array( + 'checkbox', + 'persistent', + array( + 'label' => $this->translate('Persistent Comment'), + 'value' => (bool) $config->get('settings', 'acknowledge_persistent', false), + 'description' => $this->translate( + 'If you would like the comment to remain even when the acknowledgement is removed, check this' + . ' option.' + ) + ) + ), + array( + 'checkbox', + 'expire', + array( + 'label' => $this->translate('Use Expire Time'), + 'value' => $acknowledgeExpire, + 'description' => $this->translate( + 'If the acknowledgement should expire, check this option.' + ), + 'autosubmit' => true + ) + ) + )); + $expire = isset($formData['expire']) ? $formData['expire'] : $acknowledgeExpire; + if ($expire) { + $expireTime = new DateTime(); + $expireTime->add(new DateInterval($config->get('settings', 'acknowledge_expire_time', 'PT1H'))); + $this->addElement( + 'dateTimePicker', + 'expire_time', + array( + 'label' => $this->translate('Expire Time'), + 'value' => $expireTime, + 'description' => $this->translate( + 'Enter the expire date and time for this acknowledgement here. Icinga will delete the' + . ' acknowledgement after this time expired.' + ) + ) + ); + $this->addDisplayGroup( + array('expire', 'expire_time'), + 'expire-expire_time', + array( + 'decorators' => array( + 'FormElements', + array('HtmlTag', array('tag' => 'div')) + ) + ) + ); + } + $this->addElements(array( + array( + 'checkbox', + 'sticky', + array( + 'label' => $this->translate('Sticky Acknowledgement'), + 'value' => (bool) $config->get('settings', 'acknowledge_sticky', false), + 'description' => $this->translate( + 'If you want the acknowledgement to remain until the host or service recovers even if the host' + . ' or service changes state, check this option.' + ) + ) + ), + array( + 'checkbox', + 'notify', + array( + 'label' => $this->translate('Send Notification'), + 'value' => (bool) $config->get('settings', 'acknowledge_notify', true), + 'description' => $this->translate( + 'If you do not want an acknowledgement notification to be sent out to the appropriate contacts,' + . ' uncheck this option.' + ) + ) + ) + )); + return $this; + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\MonitoredObject $object */ + $ack = new AcknowledgeProblemCommand(); + $ack + ->setObject($object) + ->setComment($this->getElement('comment')->getValue()) + ->setAuthor($this->request->getUser()->getUsername()) + ->setPersistent($this->getElement('persistent')->isChecked()) + ->setSticky($this->getElement('sticky')->isChecked()) + ->setNotify($this->getElement('notify')->isChecked()); + if ($this->getElement('expire')->isChecked()) { + $ack->setExpireTime($this->getElement('expire_time')->getValue()->getTimestamp()); + } + $this->getTransport($this->request)->send($ack); + } + Notification::success($this->translatePlural( + 'Acknowledging problem..', + 'Acknowledging problems..', + count($this->objects) + )); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/AddCommentCommandForm.php b/modules/monitoring/application/forms/Command/Object/AddCommentCommandForm.php new file mode 100644 index 0000000..72133a0 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/AddCommentCommandForm.php @@ -0,0 +1,148 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use DateInterval; +use DateTime; +use Icinga\Application\Config; +use Icinga\Module\Monitoring\Command\Object\AddCommentCommand; +use Icinga\Web\Notification; + +/** + * Form for adding host or service comments + */ +class AddCommentCommandForm extends ObjectsCommandForm +{ + /** + * Initialize this form + */ + public function init() + { + $this->addDescription($this->translate('This command is used to add host or service comments.')); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + */ + public function getSubmitLabel() + { + return $this->translatePlural('Add comment', 'Add comments', count($this->objects)); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + $this->addElement( + 'textarea', + 'comment', + array( + 'required' => true, + 'label' => $this->translate('Comment'), + 'description' => $this->translate( + 'If you work with other administrators, you may find it useful to share information about' + . ' the host or service that is having problems. Make sure you enter a brief description of' + . ' what you are doing.' + ), + 'attribs' => array('class' => 'autofocus') + ) + ); + if (! $this->getBackend()->isIcinga2()) { + $this->addElement( + 'checkbox', + 'persistent', + array( + 'label' => $this->translate('Persistent'), + 'value' => (bool) Config::module('monitoring')->get('settings', 'comment_persistent', true), + 'description' => $this->translate( + 'If you uncheck this option, the comment will automatically be deleted the next time Icinga is' + . ' restarted.' + ) + ) + ); + } + + if (version_compare($this->getBackend()->getProgramVersion(), '2.13.0', '>=')) { + $config = Config::module('monitoring'); + $commentExpire = (bool) $config->get('settings', 'comment_expire', false); + + $this->addElement( + 'checkbox', + 'expire', + [ + 'label' => $this->translate('Use Expire Time'), + 'value' => $commentExpire, + 'description' => $this->translate('If the comment should expire, check this option.'), + 'autosubmit' => true + ] + ); + + if (isset($formData['expire']) ? $formData['expire'] : $commentExpire) { + $expireTime = new DateTime(); + $expireTime->add(new DateInterval($config->get('settings', 'comment_expire_time', 'PT1H'))); + + $this->addElement( + 'dateTimePicker', + 'expire_time', + [ + 'label' => $this->translate('Expire Time'), + 'value' => $expireTime, + 'description' => $this->translate( + 'Enter the expire date and time for this comment here. Icinga will delete the' + . ' comment after this time expired.' + ) + ] + ); + + $this->addDisplayGroup( + ['expire', 'expire_time'], + 'expire-expire_time', + [ + 'decorators' => [ + 'FormElements', + ['HtmlTag', ['tag' => 'div']] + ] + ] + ); + } + } + + return $this; + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\MonitoredObject $object */ + $comment = new AddCommentCommand(); + $comment->setObject($object); + $comment->setComment($this->getElement('comment')->getValue()); + $comment->setAuthor($this->request->getUser()->getUsername()); + if (($persistent = $this->getElement('persistent')) !== null) { + $comment->setPersistent($persistent->isChecked()); + } + + $expire = $this->getElement('expire'); + + if ($expire !== null && $expire->isChecked()) { + $comment->setExpireTime($this->getElement('expire_time')->getValue()->getTimestamp()); + } + + $this->getTransport($this->request)->send($comment); + } + Notification::success($this->translatePlural( + 'Adding comment..', + 'Adding comments..', + count($this->objects) + )); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php b/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php new file mode 100644 index 0000000..a586d2f --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php @@ -0,0 +1,87 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Module\Monitoring\Command\Object\ScheduleHostCheckCommand; +use Icinga\Module\Monitoring\Command\Object\ScheduleServiceCheckCommand; +use Icinga\Web\Notification; + +/** + * Form for immediately checking hosts or services + */ +class CheckNowCommandForm extends ObjectsCommandForm +{ + /** + * (non-PHPDoc) + * @see \Zend_Form::init() For the method documentation. + */ + public function init() + { + $this->setAttrib('class', 'inline'); + $this->setSubmitLabel($this->translate('Check now')); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::addSubmitButton() For the method documentation. + */ + public function addSubmitButton() + { + $this->addElements(array( + array( + 'button', + 'btn_submit', + array( + 'class' => 'link-button spinner', + 'decorators' => array( + 'ViewHelper', + array('HtmlTag', array('tag' => 'div', 'class' => 'control-group form-controls')) + ), + 'escape' => false, + 'ignore' => true, + 'label' => $this->getView()->icon('arrows-cw') . $this->translate('Check now'), + 'type' => 'submit', + 'title' => $this->translate('Schedule the next active check to run immediately'), + 'value' => $this->translate('Check now') + ) + ) + )); + + return $this; + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\MonitoredObject $object */ + if (! $object->active_checks_enabled + && ! $this->Auth()->hasPermission('monitoring/command/schedule-check') + ) { + continue; + } + + if ($object->getType() === $object::TYPE_HOST) { + $check = new ScheduleHostCheckCommand(); + } else { + $check = new ScheduleServiceCheckCommand(); + } + $check + ->setObject($object) + ->setForced() + ->setCheckTime(time()); + $this->getTransport($this->request)->send($check); + } + Notification::success(mtp( + 'monitoring', + 'Scheduling check..', + 'Scheduling checks..', + count($this->objects) + )); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/DeleteCommentCommandForm.php b/modules/monitoring/application/forms/Command/Object/DeleteCommentCommandForm.php new file mode 100644 index 0000000..cd15b19 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/DeleteCommentCommandForm.php @@ -0,0 +1,109 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Module\Monitoring\Command\Object\DeleteCommentCommand; +use Icinga\Module\Monitoring\Forms\Command\CommandForm; +use Icinga\Web\Notification; + +/** + * Form for deleting host or service comments + */ +class DeleteCommentCommandForm extends CommandForm +{ + /** + * {@inheritdoc} + */ + public function init() + { + $this->setAttrib('class', 'inline'); + } + + /** + * {@inheritdoc} + */ + public function addSubmitButton() + { + $this->addElement( + 'button', + 'btn_submit', + array( + 'class' => 'link-button spinner', + 'decorators' => array( + 'ViewHelper', + array('HtmlTag', array('tag' => 'div', 'class' => 'control-group form-controls')) + ), + 'escape' => false, + 'ignore' => true, + 'label' => $this->getView()->icon('cancel'), + 'title' => $this->translate('Delete this comment'), + 'type' => 'submit' + ) + ); + return $this; + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData = array()) + { + $this->addElements( + array( + array( + 'hidden', + 'comment_id', + array( + 'required' => true, + 'validators' => array('NotEmpty'), + 'decorators' => array('ViewHelper') + ) + ), + array( + 'hidden', + 'comment_is_service', + array( + 'filters' => array('Boolean'), + 'decorators' => array('ViewHelper') + ) + ), + array( + 'hidden', + 'comment_name', + array( + 'decorators' => array('ViewHelper') + ) + ), + array( + 'hidden', + 'redirect', + array( + 'decorators' => array('ViewHelper') + ) + ) + ) + ); + return $this; + } + + /** + * {@inheritdoc} + */ + public function onSuccess() + { + $cmd = new DeleteCommentCommand(); + $cmd + ->setAuthor($this->Auth()->getUser()->getUsername()) + ->setCommentId($this->getElement('comment_id')->getValue()) + ->setCommentName($this->getElement('comment_name')->getValue()) + ->setIsService($this->getElement('comment_is_service')->getValue()); + $this->getTransport($this->request)->send($cmd); + $redirect = $this->getElement('redirect')->getValue(); + if (! empty($redirect)) { + $this->setRedirectUrl($redirect); + } + Notification::success($this->translate('Deleting comment..')); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/DeleteCommentsCommandForm.php b/modules/monitoring/application/forms/Command/Object/DeleteCommentsCommandForm.php new file mode 100644 index 0000000..70ea7b8 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/DeleteCommentsCommandForm.php @@ -0,0 +1,89 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Module\Monitoring\Command\Object\DeleteCommentCommand; +use Icinga\Module\Monitoring\Forms\Command\CommandForm; +use Icinga\Web\Notification; + +/** + * Form for deleting host or service comments + */ +class DeleteCommentsCommandForm extends CommandForm +{ + /** + * The comments to delete + * + * @var array + */ + protected $comments; + + /** + * {@inheritdoc} + */ + public function init() + { + $this->setAttrib('class', 'inline'); + } + + /** + * Set the comments to delete + * + * @param iterable $comments + * + * @return $this + */ + public function setComments($comments) + { + $this->comments = $comments; + return $this; + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData = array()) + { + $this->addElements(array( + array( + 'hidden', + 'redirect', + array('decorators' => array('ViewHelper')) + ) + )); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getSubmitLabel() + { + return $this->translatePlural('Remove', 'Remove All', count($this->comments)); + } + + /** + * {@inheritdoc} + */ + public function onSuccess() + { + foreach ($this->comments as $comment) { + $cmd = new DeleteCommentCommand(); + $cmd + ->setCommentId($comment->id) + ->setCommentName($comment->name) + ->setAuthor($this->Auth()->getUser()->getUsername()) + ->setIsService(isset($comment->service_description)); + $this->getTransport($this->request)->send($cmd); + } + $redirect = $this->getElement('redirect')->getValue(); + if (! empty($redirect)) { + $this->setRedirectUrl($redirect); + } + Notification::success( + $this->translatePlural('Deleting comment..', 'Deleting comments..', count($this->comments)) + ); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/DeleteDowntimeCommandForm.php b/modules/monitoring/application/forms/Command/Object/DeleteDowntimeCommandForm.php new file mode 100644 index 0000000..79700cb --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/DeleteDowntimeCommandForm.php @@ -0,0 +1,129 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Module\Monitoring\Command\Object\DeleteDowntimeCommand; +use Icinga\Module\Monitoring\Exception\CommandTransportException; +use Icinga\Module\Monitoring\Forms\Command\CommandForm; +use Icinga\Web\Notification; + +/** + * Form for deleting host or service downtimes + */ +class DeleteDowntimeCommandForm extends CommandForm +{ + /** + * {@inheritdoc} + */ + public function init() + { + $this->setAttrib('class', 'inline'); + } + + /** + * {@inheritdoc} + */ + public function addSubmitButton() + { + $this->addElement( + 'button', + 'btn_submit', + array( + 'class' => 'link-button spinner', + 'decorators' => array( + 'ViewHelper', + array('HtmlTag', array('tag' => 'div', 'class' => 'control-group form-controls')) + ), + 'escape' => false, + 'ignore' => true, + 'label' => $this->getView()->icon('cancel'), + 'title' => $this->translate('Delete this downtime'), + 'type' => 'submit' + ) + ); + return $this; + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData = array()) + { + $this->addElements( + array( + array( + 'hidden', + 'downtime_id', + array( + 'decorators' => array('ViewHelper'), + 'required' => true, + 'validators' => array('NotEmpty') + ) + ), + array( + 'hidden', + 'downtime_is_service', + array( + 'decorators' => array('ViewHelper'), + 'filters' => array('Boolean') + ) + ), + array( + 'hidden', + 'downtime_name', + array( + 'decorators' => array('ViewHelper') + ) + ), + array( + 'hidden', + 'redirect', + array( + 'decorators' => array('ViewHelper') + ) + ) + ) + ); + return $this; + } + + /** + * {@inheritdoc} + */ + public function onSuccess() + { + $cmd = new DeleteDowntimeCommand(); + $cmd + ->setAuthor($this->Auth()->getUser()->getUsername()) + ->setDowntimeId($this->getElement('downtime_id')->getValue()) + ->setDowntimeName($this->getElement('downtime_name')->getValue()) + ->setIsService($this->getElement('downtime_is_service')->getValue()); + + $errorMsg = null; + + try { + $this->getTransport($this->request)->send($cmd); + } catch (CommandTransportException $e) { + $errorMsg = $e->getMessage(); + } + + if (! $errorMsg) { + $redirect = $this->getElement('redirect')->getValue(); + Notification::success($this->translate('Deleting downtime.')); + } else { + if (! $this->getIsApiTarget()) { + $redirect = $this->getRequest()->getUrl(); + } + + Notification::error($errorMsg); + } + + if (! empty($redirect)) { + $this->setRedirectUrl($redirect); + return true; + } + + return false; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/DeleteDowntimesCommandForm.php b/modules/monitoring/application/forms/Command/Object/DeleteDowntimesCommandForm.php new file mode 100644 index 0000000..d4ee803 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/DeleteDowntimesCommandForm.php @@ -0,0 +1,89 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Module\Monitoring\Command\Object\DeleteDowntimeCommand; +use Icinga\Module\Monitoring\Forms\Command\CommandForm; +use Icinga\Web\Notification; + +/** + * Form for deleting host or service downtimes + */ +class DeleteDowntimesCommandForm extends CommandForm +{ + /** + * The downtimes to delete + * + * @var array + */ + protected $downtimes; + + /** + * {@inheritdoc} + */ + public function init() + { + $this->setAttrib('class', 'inline'); + } + + /** + * Set the downtimes to delete + * + * @param iterable $downtimes + * + * @return $this + */ + public function setDowntimes($downtimes) + { + $this->downtimes = $downtimes; + return $this; + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData = array()) + { + $this->addElements(array( + array( + 'hidden', + 'redirect', + array('decorators' => array('ViewHelper')) + ) + )); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getSubmitLabel() + { + return $this->translatePlural('Remove', 'Remove All', count($this->downtimes)); + } + + /** + * {@inheritdoc} + */ + public function onSuccess() + { + foreach ($this->downtimes as $downtime) { + $delDowntime = new DeleteDowntimeCommand(); + $delDowntime + ->setDowntimeId($downtime->id) + ->setDowntimeName($downtime->name) + ->setAuthor($this->Auth()->getUser()->getUsername()) + ->setIsService(isset($downtime->service_description)); + $this->getTransport($this->request)->send($delDowntime); + } + $redirect = $this->getElement('redirect')->getValue(); + if (! empty($redirect)) { + $this->setRedirectUrl($redirect); + } + Notification::success( + $this->translatePlural('Deleting downtime..', 'Deleting downtimes..', count($this->downtimes)) + ); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/ObjectsCommandForm.php b/modules/monitoring/application/forms/Command/Object/ObjectsCommandForm.php new file mode 100644 index 0000000..928c365 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/ObjectsCommandForm.php @@ -0,0 +1,47 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Module\Monitoring\Forms\Command\CommandForm; +use Icinga\Module\Monitoring\Object\MonitoredObject; + +/** + * Base class for Icinga object command forms + */ +abstract class ObjectsCommandForm extends CommandForm +{ + /** + * Involved Icinga objects + * + * @var array|\Traversable|\ArrayAccess + */ + protected $objects; + + /** + * Set the involved Icinga objects + * + * @param $objects MonitoredObject|array|\Traversable|\ArrayAccess + * + * @return $this + */ + public function setObjects($objects) + { + if ($objects instanceof MonitoredObject) { + $this->objects = array($objects); + } else { + $this->objects = $objects; + } + return $this; + } + + /** + * Get the involved Icinga objects + * + * @return array|\ArrayAccess|\Traversable + */ + public function getObjects() + { + return $this->objects; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/ProcessCheckResultCommandForm.php b/modules/monitoring/application/forms/Command/Object/ProcessCheckResultCommandForm.php new file mode 100644 index 0000000..7a196ec --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/ProcessCheckResultCommandForm.php @@ -0,0 +1,140 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Web\Notification; +use Icinga\Module\Monitoring\Command\Object\ProcessCheckResultCommand; + +/** + * Form for submitting a passive host or service check result + */ +class ProcessCheckResultCommandForm extends ObjectsCommandForm +{ + /** + * Initialize this form + */ + public function init() + { + $this->addDescription($this->translate( + 'This command is used to submit passive host or service check results.' + )); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + */ + public function getSubmitLabel() + { + return $this->translatePlural( + 'Submit Passive Check Result', + 'Submit Passive Check Results', + count($this->objects) + ); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::createElements() For the method documentation. + */ + public function createElements(array $formData) + { + $object = null; + foreach ($this->getObjects() as $object) { + /** @var \Icinga\Module\Monitoring\Object\MonitoredObject $object */ + // Nasty, but as getObjects() returns everything but an object with a real + // iterator interface this is the only way to fetch just the first element + break; + } + + $this->addElement( + 'select', + 'status', + array( + 'required' => true, + 'label' => $this->translate('Status'), + 'description' => $this->translate('The state this check result should report'), + 'multiOptions' => $object->getType() === $object::TYPE_HOST ? $this->getHostMultiOptions() : array( + ProcessCheckResultCommand::SERVICE_OK => $this->translate('OK', 'icinga.state'), + ProcessCheckResultCommand::SERVICE_WARNING => $this->translate('WARNING', 'icinga.state'), + ProcessCheckResultCommand::SERVICE_CRITICAL => $this->translate('CRITICAL', 'icinga.state'), + ProcessCheckResultCommand::SERVICE_UNKNOWN => $this->translate('UNKNOWN', 'icinga.state') + ) + ) + ); + $this->addElement( + 'text', + 'output', + array( + 'required' => true, + 'label' => $this->translate('Output'), + 'description' => $this->translate('The plugin output of this check result') + ) + ); + $this->addElement( + 'text', + 'perfdata', + array( + 'allowEmpty' => true, + 'label' => $this->translate('Performance Data'), + 'description' => $this->translate( + 'The performance data of this check result. Leave empty' + . ' if this check result has no performance data' + ) + ) + ); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\MonitoredObject $object */ + if (! $object->passive_checks_enabled) { + continue; + } + + $command = new ProcessCheckResultCommand(); + $command->setObject($object); + $command->setStatus($this->getValue('status')); + $command->setOutput($this->getValue('output')); + + if ($perfdata = $this->getValue('perfdata')) { + $command->setPerformanceData($perfdata); + } + + $this->getTransport($this->request)->send($command); + } + + Notification::success($this->translatePlural( + 'Processing check result..', + 'Processing check results..', + count($this->objects) + )); + + return true; + } + + /** + * Returns the available host options based on the program version + * + * @return array + */ + protected function getHostMultiOptions() + { + $options = array( + ProcessCheckResultCommand::HOST_UP => $this->translate('UP', 'icinga.state'), + ProcessCheckResultCommand::HOST_DOWN => $this->translate('DOWN', 'icinga.state') + ); + + if (! $this->getBackend()->isIcinga2()) { + $options[ProcessCheckResultCommand::HOST_UNREACHABLE] = $this->translate('UNREACHABLE', 'icinga.state'); + } + + return $options; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/RemoveAcknowledgementCommandForm.php b/modules/monitoring/application/forms/Command/Object/RemoveAcknowledgementCommandForm.php new file mode 100644 index 0000000..e45a055 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/RemoveAcknowledgementCommandForm.php @@ -0,0 +1,122 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Module\Monitoring\Command\Object\RemoveAcknowledgementCommand; +use Icinga\Web\Notification; + +/** + * Form for removing host or service problem acknowledgements + */ +class RemoveAcknowledgementCommandForm extends ObjectsCommandForm +{ + /** + * Whether to show the submit label next to the remove icon + * + * The submit label is disabled in detail views but should be enabled in multi-select views. + * + * @var bool + */ + protected $labelEnabled = false; + + /** + * Whether to show the submit label next to the remove icon + * + * @return bool + */ + public function isLabelEnabled() + { + return $this->labelEnabled; + } + + /** + * Set whether to show the submit label next to the remove icon + * + * @param bool $labelEnabled + * + * @return $this + */ + public function setLabelEnabled($labelEnabled) + { + $this->labelEnabled = (bool) $labelEnabled; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function init() + { + $this->setAttrib('class', 'inline'); + } + + /** + * {@inheritdoc} + */ + public function addSubmitButton() + { + $this->addElement( + 'button', + 'btn_submit', + array( + 'class' => 'link-button spinner', + 'decorators' => array( + 'ViewHelper', + array('HtmlTag', array('tag' => 'div', 'class' => 'control-group form-controls')) + ), + 'escape' => false, + 'ignore' => true, + 'label' => $this->getSubmitLabel(), + 'title' => $this->translatePlural( + 'Remove acknowledgement', + 'Remove acknowledgements', + count($this->objects) + ), + 'type' => 'submit' + ) + ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getSubmitLabel() + { + $label = $this->getView()->icon('cancel'); + if ($this->isLabelEnabled()) { + $label .= $this->translatePlural( + 'Remove acknowledgement', + 'Remove acknowledgements', + count($this->objects) + ); + } + + return $label; + } + + /** + * {@inheritdoc} + */ + public function onSuccess() + { + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\MonitoredObject $object */ + $removeAck = new RemoveAcknowledgementCommand(); + $removeAck->setObject($object); + $removeAck->setAuthor($this->Auth()->getUser()->getUsername()); + $this->getTransport($this->request)->send($removeAck); + } + Notification::success(mtp( + 'monitoring', + 'Removing acknowledgement..', + 'Removing acknowledgements..', + count($this->objects) + )); + + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/ScheduleHostCheckCommandForm.php b/modules/monitoring/application/forms/Command/Object/ScheduleHostCheckCommandForm.php new file mode 100644 index 0000000..55b044f --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/ScheduleHostCheckCommandForm.php @@ -0,0 +1,67 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Application\Config; +use Icinga\Module\Monitoring\Command\Object\ScheduleHostCheckCommand; +use Icinga\Web\Notification; + +/** + * Form for scheduling host checks + */ +class ScheduleHostCheckCommandForm extends ScheduleServiceCheckCommandForm +{ + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + $config = Config::module('monitoring'); + + parent::createElements($formData); + $this->addElements(array( + array( + 'checkbox', + 'all_services', + array( + 'label' => $this->translate('All Services'), + 'value' => (bool) $config->get('settings', 'hostcheck_all_services', false), + 'description' => $this->translate( + 'Schedule check for all services on the hosts and the hosts themselves.' + ) + ) + ) + )); + return $this; + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\Host $object */ + if (! $object->active_checks_enabled + && ! $this->Auth()->hasPermission('monitoring/command/schedule-check') + ) { + continue; + } + + $check = new ScheduleHostCheckCommand(); + $check + ->setObject($object) + ->setOfAllServices($this->getElement('all_services')->isChecked()); + $this->scheduleCheck($check, $this->request); + } + Notification::success($this->translatePlural( + 'Scheduling host check..', + 'Scheduling host checks..', + count($this->objects) + )); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php b/modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php new file mode 100644 index 0000000..89db1ce --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php @@ -0,0 +1,178 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use DateInterval; +use DateTime; +use Icinga\Application\Config; +use Icinga\Module\Monitoring\Command\Object\ApiScheduleHostDowntimeCommand; +use Icinga\Module\Monitoring\Command\Object\PropagateHostDowntimeCommand; +use Icinga\Module\Monitoring\Command\Object\ScheduleHostDowntimeCommand; +use Icinga\Module\Monitoring\Command\Object\ScheduleServiceDowntimeCommand; +use Icinga\Module\Monitoring\Command\Transport\ApiCommandTransport; +use Icinga\Module\Monitoring\Command\Transport\CommandTransport; +use Icinga\Web\Notification; + +/** + * Form for scheduling host downtimes + */ +class ScheduleHostDowntimeCommandForm extends ScheduleServiceDowntimeCommandForm +{ + /** @var bool */ + protected $hostDowntimeAllServices; + + public function init() + { + $this->start = new DateTime(); + $config = Config::module('monitoring'); + $this->commentText = $config->get('settings', 'hostdowntime_comment_text'); + + $this->hostDowntimeAllServices = (bool) $config->get('settings', 'hostdowntime_all_services', false); + + $fixedEnd = clone $this->start; + $fixed = $config->get('settings', 'hostdowntime_end_fixed', 'PT1H'); + $this->fixedEnd = $fixedEnd->add(new DateInterval($fixed)); + + $flexibleEnd = clone $this->start; + $flexible = $config->get('settings', 'hostdowntime_end_flexible', 'PT1H'); + $this->flexibleEnd = $flexibleEnd->add(new DateInterval($flexible)); + + $flexibleDuration = $config->get('settings', 'hostdowntime_flexible_duration', 'PT2H'); + $this->flexibleDuration = new DateInterval($flexibleDuration); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + parent::createElements($formData); + + $this->addElement( + 'checkbox', + 'all_services', + array( + 'description' => $this->translate( + 'Schedule downtime for all services on the hosts and the hosts themselves.' + ), + 'label' => $this->translate('All Services'), + 'value' => $this->hostDowntimeAllServices + ) + ); + + if (! $this->getBackend()->isIcinga2() + || version_compare($this->getBackend()->getProgramVersion(), '2.6.0', '>=') + ) { + $this->addElement( + 'select', + 'child_hosts', + array( + 'description' => $this->translate( + 'Define what should be done with the child hosts of the hosts.' + ), + 'label' => $this->translate('Child Hosts'), + 'multiOptions' => array( + 0 => $this->translate('Do nothing with child hosts'), + 1 => $this->translate('Schedule triggered downtime for all child hosts'), + 2 => $this->translate('Schedule non-triggered downtime for all child hosts') + ), + 'value' => 0 + ) + ); + } + + return $this; + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + $end = $this->getValue('end')->getTimestamp(); + if ($end <= $this->getValue('start')->getTimestamp()) { + $endElement = $this->_elements['end']; + $endElement->setValue($endElement->getValue()->format($endElement->getFormat())); + $endElement->addError($this->translate('The end time must be greater than the start time')); + return false; + } + + $now = new DateTime; + if ($end <= $now->getTimestamp()) { + $endElement = $this->_elements['end']; + $endElement->setValue($endElement->getValue()->format($endElement->getFormat())); + $endElement->addError($this->translate('A downtime must not be in the past')); + return false; + } + + // Send all_services API parameter if Icinga is equal to or greater than 2.11.0 + $allServicesNative = version_compare($this->getBackend()->getProgramVersion(), '2.11.0', '>='); + // Use ApiScheduleHostDowntimeCommand only when Icinga is equal to or greater than 2.11.0 and + // when an API command transport is requested or only API command transports are configured: + $useApiDowntime = $allServicesNative; + if ($useApiDowntime) { + $transport = $this->getTransport($this->getRequest()); + if ($transport instanceof CommandTransport) { + foreach ($transport::getConfig() as $config) { + if (strtolower($config->transport) !== 'api') { + $useApiDowntime = false; + break; + } + } + } elseif (! $transport instanceof ApiCommandTransport) { + $useApiDowntime = false; + } + } + + foreach ($this->objects as $object) { + if ($useApiDowntime) { + $hostDowntime = (new ApiScheduleHostDowntimeCommand()) + ->setForAllServices($this->getElement('all_services')->isChecked()) + ->setChildOptions((int) $this->getElement('child_hosts')->getValue()); + // Code duplicated for readability and scope + $hostDowntime->setObject($object); + $this->scheduleDowntime($hostDowntime, $this->request); + + continue; + } + + /** @var \Icinga\Module\Monitoring\Object\Host $object */ + if (($childHostsEl = $this->getElement('child_hosts')) !== null) { + $childHosts = (int) $childHostsEl->getValue(); + } else { + $childHosts = 0; + } + $allServices = $this->getElement('all_services')->isChecked(); + if ($childHosts === 0) { + $hostDowntime = (new ScheduleHostDowntimeCommand()) + ->setForAllServicesNative($allServicesNative); + if ($allServices === true) { + $hostDowntime->setForAllServices(); + }; + } else { + $hostDowntime = new PropagateHostDowntimeCommand(); + if ($childHosts === 1) { + $hostDowntime->setTriggered(); + } + if ($allServices === true) { + foreach ($object->services as $service) { + $serviceDowntime = new ScheduleServiceDowntimeCommand(); + $serviceDowntime->setObject($service); + $this->scheduleDowntime($serviceDowntime, $this->request); + } + } + } + $hostDowntime->setObject($object); + $this->scheduleDowntime($hostDowntime, $this->request); + } + Notification::success($this->translatePlural( + 'Scheduling host downtime..', + 'Scheduling host downtimes..', + count($this->objects) + )); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/ScheduleServiceCheckCommandForm.php b/modules/monitoring/application/forms/Command/Object/ScheduleServiceCheckCommandForm.php new file mode 100644 index 0000000..f65aea8 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/ScheduleServiceCheckCommandForm.php @@ -0,0 +1,112 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use DateTime; +use DateInterval; +use Icinga\Module\Monitoring\Command\Object\ScheduleServiceCheckCommand; +use Icinga\Web\Notification; +use Icinga\Web\Request; + +/** + * Form for scheduling service checks + */ +class ScheduleServiceCheckCommandForm extends ObjectsCommandForm +{ + /** + * Initialize this form + */ + public function init() + { + $this->addDescription($this->translate( + 'This command is used to schedule the next check of hosts or services. Icinga will re-queue the' + . ' hosts or services to be checked at the time you specify.' + )); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + */ + public function getSubmitLabel() + { + return $this->translatePlural('Schedule check', 'Schedule checks', count($this->objects)); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + $checkTime = new DateTime(); + $checkTime->add(new DateInterval('PT1H')); + $this->addElements(array( + array( + 'dateTimePicker', + 'check_time', + array( + 'required' => true, + 'label' => $this->translate('Check Time'), + 'description' => $this->translate( + 'Set the date and time when the check should be scheduled.' + ), + 'value' => $checkTime + ) + ), + array( + 'checkbox', + 'force_check', + array( + 'label' => $this->translate('Force Check'), + 'description' => $this->translate( + 'If you select this option, Icinga will force a check regardless of both what time the' + . ' scheduled check occurs and whether or not checks are enabled.' + ) + ) + ) + )); + return $this; + } + + /** + * Schedule a check + * + * @param ScheduleServiceCheckCommand $check + * @param Request $request + */ + public function scheduleCheck(ScheduleServiceCheckCommand $check, Request $request) + { + $check + ->setForced($this->getElement('force_check')->isChecked()) + ->setCheckTime($this->getElement('check_time')->getValue()->getTimestamp()); + $this->getTransport($request)->send($check); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\Service $object */ + if (! $object->active_checks_enabled + && ! $this->Auth()->hasPermission('monitoring/command/schedule-check') + ) { + continue; + } + + $check = new ScheduleServiceCheckCommand(); + $check->setObject($object); + $this->scheduleCheck($check, $this->request); + } + Notification::success($this->translatePlural( + 'Scheduling service check..', + 'Scheduling service checks..', + count($this->objects) + )); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/ScheduleServiceDowntimeCommandForm.php b/modules/monitoring/application/forms/Command/Object/ScheduleServiceDowntimeCommandForm.php new file mode 100644 index 0000000..90d50d4 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/ScheduleServiceDowntimeCommandForm.php @@ -0,0 +1,263 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use DateTime; +use DateInterval; +use Icinga\Application\Config; +use Icinga\Module\Monitoring\Command\Object\ScheduleServiceDowntimeCommand; +use Icinga\Web\Notification; +use Icinga\Web\Request; + +/** + * Form for scheduling service downtimes + */ +class ScheduleServiceDowntimeCommandForm extends ObjectsCommandForm +{ + /** + * Fixed downtime + */ + const FIXED = 'fixed'; + + /** + * Flexible downtime + */ + const FLEXIBLE = 'flexible'; + + /** @var DateTime downtime start */ + protected $start; + + /** @var DateTime fixed downtime end */ + protected $fixedEnd; + + /** @var DateTime flexible downtime end */ + protected $flexibleEnd; + + /** @var DateInterval flexible downtime duration */ + protected $flexibleDuration; + + /** @var mixed Comment text */ + protected $commentText; + + /** + * Initialize this form + */ + public function init() + { + $this->start = new DateTime(); + + $config = Config::module('monitoring'); + + $this->commentText = $config->get('settings', 'servicedowntime_comment_text'); + $fixedEnd = clone $this->start; + $fixed = $config->get('settings', 'servicedowntime_end_fixed', 'PT1H'); + $this->fixedEnd = $fixedEnd->add(new DateInterval($fixed)); + + $flexibleEnd = clone $this->start; + $flexible = $config->get('settings', 'servicedowntime_end_flexible', 'PT1H'); + $this->flexibleEnd = $flexibleEnd->add(new DateInterval($flexible)); + + $flexibleDuration = $config->get('settings', 'servicedowntime_flexible_duration', 'PT2H'); + $this->flexibleDuration = new DateInterval($flexibleDuration); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + */ + public function getSubmitLabel() + { + return $this->translatePlural('Schedule downtime', 'Schedule downtimes', count($this->objects)); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + $this->addDescription($this->translate( + 'This command is used to schedule host and service downtimes. During the specified downtime,' + . ' Icinga will not send notifications out about the hosts and services. When the scheduled' + . ' downtime expires, Icinga will send out notifications for the hosts and services as it' + . ' normally would. Scheduled downtimes are preserved across program shutdowns and' + . ' restarts.' + )); + + $isFlexible = (bool) isset($formData['type']) && $formData['type'] === self::FLEXIBLE; + + $this->addElements(array( + array( + 'textarea', + 'comment', + array( + 'required' => true, + 'label' => $this->translate('Comment'), + 'description' => $this->translate( + 'If you work with other administrators, you may find it useful to share information about' + . ' the host or service that is having problems. Make sure you enter a brief description of' + . ' what you are doing.' + ), + 'attribs' => array('class' => 'autofocus'), + 'value' => $this->commentText + ) + ), + array( + 'dateTimePicker', + 'start', + array( + 'required' => true, + 'label' => $this->translate('Start Time'), + 'description' => $this->translate('Set the start date and time for the downtime.'), + 'value' => $this->start + ) + ), + array( + 'dateTimePicker', + 'end', + array( + 'required' => true, + 'label' => $this->translate('End Time'), + 'description' => $this->translate('Set the end date and time for the downtime.'), + 'preserveDefault' => true, + 'value' => $isFlexible ? $this->flexibleEnd : $this->fixedEnd + ) + ), + array( + 'select', + 'type', + array( + 'required' => true, + 'autosubmit' => true, + 'label' => $this->translate('Type'), + 'description' => $this->translate( + 'If you select the fixed option, the downtime will be in effect between the start and end' + . ' times you specify whereas a flexible downtime starts when the host or service enters a' + . ' problem state sometime between the start and end times you specified and lasts as long' + . ' as the duration time you enter. The duration fields do not apply for fixed downtimes.' + ), + 'multiOptions' => array( + self::FIXED => $this->translate('Fixed'), + self::FLEXIBLE => $this->translate('Flexible') + ), + 'validators' => array( + array( + 'InArray', + true, + array(array(self::FIXED, self::FLEXIBLE)) + ) + ) + ) + ) + )); + $this->addDisplayGroup( + array('start', 'end'), + 'start-end', + array( + 'decorators' => array( + 'FormElements', + array('HtmlTag', array('tag' => 'div')) + ) + ) + ); + if ($isFlexible) { + $this->addElements(array( + array( + 'number', + 'hours', + array( + 'required' => true, + 'label' => $this->translate('Hours'), + 'value' => $this->flexibleDuration->h, + 'min' => -1 + ) + ), + array( + 'number', + 'minutes', + array( + 'required' => true, + 'label' => $this->translate('Minutes'), + 'value' => $this->flexibleDuration->m, + 'min' => -1 + ) + ) + )); + $this->addDisplayGroup( + array('hours', 'minutes'), + 'duration', + array( + 'legend' => $this->translate('Flexible Duration'), + 'description' => $this->translate( + 'Enter here the duration of the downtime. The downtime will be automatically deleted after this' + . ' time expired.' + ), + 'decorators' => array( + 'FormElements', + array('HtmlTag', array('tag' => 'div')), + array( + 'Description', + array('tag' => 'span', 'class' => 'description', 'placement' => 'prepend') + ), + 'Fieldset' + ) + ) + ); + } + return $this; + } + + public function scheduleDowntime(ScheduleServiceDowntimeCommand $downtime, Request $request) + { + $downtime + ->setComment($this->getElement('comment')->getValue()) + ->setAuthor($request->getUser()->getUsername()) + ->setStart($this->getElement('start')->getValue()->getTimestamp()) + ->setEnd($this->getElement('end')->getValue()->getTimestamp()); + if ($this->getElement('type')->getValue() === self::FLEXIBLE) { + $downtime->setFixed(false); + $downtime->setDuration( + (float) $this->getElement('hours')->getValue() * 3600 + + (float) $this->getElement('minutes')->getValue() * 60 + ); + } + $this->getTransport($request)->send($downtime); + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + $end = $this->getValue('end')->getTimestamp(); + if ($end <= $this->getValue('start')->getTimestamp()) { + $endElement = $this->_elements['end']; + $endElement->setValue($endElement->getValue()->format($endElement->getFormat())); + $endElement->addError($this->translate('The end time must be greater than the start time')); + return false; + } + + $now = new DateTime; + if ($end <= $now->getTimestamp()) { + $endElement = $this->_elements['end']; + $endElement->setValue($endElement->getValue()->format($endElement->getFormat())); + $endElement->addError($this->translate('A downtime must not be in the past')); + return false; + } + + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\Service $object */ + $downtime = new ScheduleServiceDowntimeCommand(); + $downtime->setObject($object); + $this->scheduleDowntime($downtime, $this->request); + } + Notification::success($this->translatePlural( + 'Scheduling service downtime..', + 'Scheduling service downtimes..', + count($this->objects) + )); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/SendCustomNotificationCommandForm.php b/modules/monitoring/application/forms/Command/Object/SendCustomNotificationCommandForm.php new file mode 100644 index 0000000..0d1c393 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/SendCustomNotificationCommandForm.php @@ -0,0 +1,110 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Application\Config; +use Icinga\Module\Monitoring\Command\Object\SendCustomNotificationCommand; +use Icinga\Web\Notification; + +/** + * Form to send custom notifications + */ +class SendCustomNotificationCommandForm extends ObjectsCommandForm +{ + /** + * Initialize this form + */ + public function init() + { + $this->addDescription( + $this->translate('This command is used to send custom notifications about hosts or services.') + ); + } + + /** + * {@inheritdoc} + */ + public function getSubmitLabel() + { + return $this->translatePlural('Send custom notification', 'Send custom notifications', count($this->objects)); + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData = array()) + { + $config = Config::module('monitoring'); + + $this->addElements(array( + array( + 'textarea', + 'comment', + array( + 'required' => true, + 'label' => $this->translate('Comment'), + 'description' => $this->translate( + 'If you work with other administrators, you may find it useful to share information about' + . ' the host or service that is having problems. Make sure you enter a brief description of' + . ' what you are doing.' + ) + ) + ), + array( + 'checkbox', + 'forced', + array( + 'label' => $this->translate('Forced'), + 'value' => (bool) $config->get('settings', 'custom_notification_forced', false), + 'description' => $this->translate( + 'If you check this option, the notification is sent out regardless of time restrictions and' + . ' whether or not notifications are enabled.' + ) + ) + ) + )); + + if (! $this->getBackend()->isIcinga2()) { + $this->addElement( + 'checkbox', + 'broadcast', + array( + 'label' => $this->translate('Broadcast'), + 'value' => (bool) $config->get('settings', 'custom_notification_broadcast', false), + 'description' => $this->translate( + 'If you check this option, the notification is sent out to all normal and escalated contacts.' + ) + ) + ); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function onSuccess() + { + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\MonitoredObject $object */ + $notification = new SendCustomNotificationCommand(); + $notification + ->setObject($object) + ->setComment($this->getElement('comment')->getValue()) + ->setAuthor($this->request->getUser()->getUsername()) + ->setForced($this->getElement('forced')->isChecked()); + if (($broadcast = $this->getElement('broadcast')) !== null) { + $notification->setBroadcast($broadcast->isChecked()); + } + $this->getTransport($this->request)->send($notification); + } + Notification::success($this->translatePlural( + 'Sending custom notification..', + 'Sending custom notifications..', + count($this->objects) + )); + return true; + } +} diff --git a/modules/monitoring/application/forms/Command/Object/ToggleObjectFeaturesCommandForm.php b/modules/monitoring/application/forms/Command/Object/ToggleObjectFeaturesCommandForm.php new file mode 100644 index 0000000..e4aabb2 --- /dev/null +++ b/modules/monitoring/application/forms/Command/Object/ToggleObjectFeaturesCommandForm.php @@ -0,0 +1,187 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Command\Object; + +use Icinga\Module\Monitoring\Command\Object\ToggleObjectFeatureCommand; +use Icinga\Module\Monitoring\Object\MonitoredObject; +use Icinga\Web\Notification; + +/** + * Form for enabling or disabling features of Icinga objects, i.e. hosts or services + */ +class ToggleObjectFeaturesCommandForm extends ObjectsCommandForm +{ + /** + * Feature to feature spec map + * + * @var string[] + */ + protected $features; + + /** + * Feature to feature status map + * + * @var int[] + */ + protected $featureStatus; + + /** + * {@inheritdoc} + */ + public function init() + { + $this->setUseFormAutosubmit(); + $this->setAttrib('class', self::DEFAULT_CLASSES . ' object-features'); + $features = array( + ToggleObjectFeatureCommand::FEATURE_ACTIVE_CHECKS => array( + 'label' => $this->translate('Active Checks'), + 'permission' => 'monitoring/command/feature/object/active-checks' + ), + ToggleObjectFeatureCommand::FEATURE_PASSIVE_CHECKS => array( + 'label' => $this->translate('Passive Checks'), + 'permission' => 'monitoring/command/feature/object/passive-checks' + ), + ToggleObjectFeatureCommand::FEATURE_OBSESSING => array( + 'label' => $this->translate('Obsessing'), + 'permission' => 'monitoring/command/feature/object/obsessing' + ), + ToggleObjectFeatureCommand::FEATURE_NOTIFICATIONS => array( + 'label' => $this->translate('Notifications'), + 'permission' => 'monitoring/command/feature/object/notifications' + ), + ToggleObjectFeatureCommand::FEATURE_EVENT_HANDLER => array( + 'label' => $this->translate('Event Handler'), + 'permission' => 'monitoring/command/feature/object/event-handler' + ), + ToggleObjectFeatureCommand::FEATURE_FLAP_DETECTION => array( + 'label' => $this->translate('Flap Detection'), + 'permission' => 'monitoring/command/feature/object/flap-detection' + ) + ); + if ($this->getBackend()->isIcinga2()) { + unset($features[ToggleObjectFeatureCommand::FEATURE_OBSESSING]); + } + $this->features = $features; + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData = array()) + { + foreach ($this->features as $feature => $spec) { + $options = array( + 'autosubmit' => true, + 'disabled' => $this->hasPermission($spec['permission']) ? null : 'disabled', + 'label' => $spec['label'] + ); + if ($formData[$feature . '_changed']) { + $options['description'] = $this->translate('changed'); + } + if ($formData[$feature] === 2) { + $this->addElement('select', $feature, $options + [ + 'description' => $this->translate('Multiple Values'), + 'filters' => [['Null', ['type' => \Zend_Filter_Null::STRING]]], + 'multiOptions' => [ + '' => $this->translate('Leave Unchanged'), + $this->translate('Disable All'), + $this->translate('Enable All') + ], + 'decorators' => array_merge( + array_slice(static::$defaultElementDecorators, 0, 3), + [['Description', ['tag' => 'span']]], + array_slice(static::$defaultElementDecorators, 4, 1), + [['HtmlTag', ['tag' => 'div', 'class' => 'control-group indeterminate']]] + ) + ]); + } else { + $options['value'] = $formData[$feature]; + $this->addElement('checkbox', $feature, $options); + } + } + } + + /** + * Load feature status + * + * @param MonitoredObject|object $object + * + * @return $this + */ + public function load($object) + { + $featureStatus = array(); + foreach (array_keys($this->features) as $feature) { + $featureStatus[$feature] = $object->{$feature}; + if (isset($object->{$feature . '_changed'})) { + $featureStatus[$feature . '_changed'] = (bool) $object->{$feature . '_changed'}; + } else { + $featureStatus[$feature . '_changed'] = false; + } + } + $this->create($featureStatus); + $this->featureStatus = $featureStatus; + + return $this; + } + + /** + * (non-PHPDoc) + * @see \Icinga\Web\Form::onSuccess() For the method documentation. + */ + public function onSuccess() + { + $notifications = array( + ToggleObjectFeatureCommand::FEATURE_ACTIVE_CHECKS => array( + $this->translate('Enabling active checks..'), + $this->translate('Disabling active checks..') + ), + ToggleObjectFeatureCommand::FEATURE_PASSIVE_CHECKS => array( + $this->translate('Enabling passive checks..'), + $this->translate('Disabling passive checks..') + ), + ToggleObjectFeatureCommand::FEATURE_OBSESSING => array( + $this->translate('Enabling obsessing..'), + $this->translate('Disabling obsessing..') + ), + ToggleObjectFeatureCommand::FEATURE_NOTIFICATIONS => array( + $this->translate('Enabling notifications..'), + $this->translate('Disabling notifications..') + ), + ToggleObjectFeatureCommand::FEATURE_EVENT_HANDLER => array( + $this->translate('Enabling event handler..'), + $this->translate('Disabling event handler..') + ), + ToggleObjectFeatureCommand::FEATURE_FLAP_DETECTION => array( + $this->translate('Enabling flap detection..'), + $this->translate('Disabling flap detection..') + ) + ); + + foreach ($this->getValues() as $feature => $enabled) { + if ($this->getElement($feature)->getAttrib('disabled') !== null + || $enabled === null + || (int) $enabled === (int) $this->featureStatus[$feature] + ) { + continue; + } + foreach ($this->objects as $object) { + /** @var \Icinga\Module\Monitoring\Object\MonitoredObject $object */ + if ((bool) $object->{$feature} !== (bool) $enabled) { + $toggleFeature = new ToggleObjectFeatureCommand(); + $toggleFeature + ->setFeature($feature) + ->setObject($object) + ->setEnabled($enabled); + $this->getTransport($this->request)->send($toggleFeature); + } + } + Notification::success( + $notifications[$feature][$enabled ? 0 : 1] + ); + } + + return true; + } +} diff --git a/modules/monitoring/application/forms/Config/BackendConfigForm.php b/modules/monitoring/application/forms/Config/BackendConfigForm.php new file mode 100644 index 0000000..5ed42e1 --- /dev/null +++ b/modules/monitoring/application/forms/Config/BackendConfigForm.php @@ -0,0 +1,367 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Config; + +use Exception; +use InvalidArgumentException; +use Icinga\Application\Config; +use Icinga\Data\ConfigObject; +use Icinga\Data\ResourceFactory; +use Icinga\Exception\ConfigurationError; +use Icinga\Exception\IcingaException; +use Icinga\Exception\NotFoundError; +use Icinga\Forms\ConfigForm; +use Icinga\Web\Form; + +/** + * Form for managing monitoring backends + */ +class BackendConfigForm extends ConfigForm +{ + /** + * The available monitoring backend resources split by type + * + * @var array + */ + protected $resources; + + /** + * The backend to load when displaying the form for the first time + * + * @var string + */ + protected $backendToLoad; + + /** + * Initialize this form + */ + public function init() + { + $this->setName('form_config_monitoring_backends'); + $this->setSubmitLabel($this->translate('Save Changes')); + } + + /** + * Set the resource configuration to use + * + * @param Config $resourceConfig The resource configuration + * + * @return $this + * + * @throws ConfigurationError In case there are no valid monitoring backend resources + */ + public function setResourceConfig(Config $resourceConfig) + { + $resources = array(); + foreach ($resourceConfig as $name => $resource) { + if ($resource->type === 'db') { + $resources['ido'][$name] = $name; + } + } + + if (empty($resources)) { + throw new ConfigurationError($this->translate( + 'Could not find any valid monitoring backend resources. Please configure a database resource first.' + )); + } + + $this->resources = $resources; + return $this; + } + + /** + * Populate the form with the given backend's config + * + * @param string $name + * + * @return $this + * + * @throws NotFoundError In case no backend with the given name is found + */ + public function load($name) + { + if (! $this->config->hasSection($name)) { + throw new NotFoundError('No monitoring backend called "%s" found', $name); + } + + $this->backendToLoad = $name; + return $this; + } + + /** + * Add a new monitoring backend + * + * The backend to add is identified by the array-key `name'. + * + * @param array $data + * + * @return $this + * + * @throws InvalidArgumentException In case $data does not contain a backend name + * @throws IcingaException In case a backend with the same name already exists + */ + public function add(array $data) + { + if (! isset($data['name'])) { + throw new InvalidArgumentException('Key \'name\' missing'); + } + + $backendName = $data['name']; + if ($this->config->hasSection($backendName)) { + throw new IcingaException( + $this->translate('A monitoring backend with the name "%s" does already exist'), + $backendName + ); + } + + unset($data['name']); + $this->config->setSection($backendName, $data); + return $this; + } + + /** + * Edit a monitoring backend + * + * @param string $name + * @param array $data + * + * @return $this + * + * @throws NotFoundError In case no backend with the given name is found + */ + public function edit($name, array $data) + { + if (! $this->config->hasSection($name)) { + throw new NotFoundError('No monitoring backend called "%s" found', $name); + } + + $backendConfig = $this->config->getSection($name); + if (isset($data['name'])) { + if ($data['name'] !== $name) { + $this->config->removeSection($name); + $name = $data['name']; + } + + unset($data['name']); + } + + $backendConfig->merge($data); + $this->config->setSection($name, $backendConfig); + return $this; + } + + /** + * Remove a monitoring backend + * + * @param string $name + * + * @return $this + */ + public function delete($name) + { + $this->config->removeSection($name); + return $this; + } + + /** + * Create and add elements to this form + * + * @param array $formData + */ + public function createElements(array $formData) + { + $this->addElement( + 'checkbox', + 'disabled', + array( + 'label' => $this->translate('Disable This Backend') + ) + ); + $this->addElement( + 'text', + 'name', + array( + 'required' => true, + 'label' => $this->translate('Backend Name'), + 'description' => $this->translate( + 'The name of this monitoring backend that is used to differentiate it from others' + ) + ) + ); + + $resourceType = isset($formData['type']) ? $formData['type'] : null; + + $resourceTypes = array(); + if ($resourceType === 'ido' || array_key_exists('ido', $this->resources)) { + $resourceTypes['ido'] = 'IDO Backend'; + } + + if ($resourceType === null) { + $resourceType = key($resourceTypes); + } + + $this->addElement( + 'select', + 'type', + array( + 'required' => true, + 'autosubmit' => true, + 'label' => $this->translate('Backend Type'), + 'description' => $this->translate( + 'The type of data source used for retrieving monitoring information' + ), + 'multiOptions' => $resourceTypes + ) + ); + + $this->addElement( + 'select', + 'resource', + array( + 'required' => true, + 'label' => $this->translate('Resource'), + 'description' => $this->translate('The resource to use'), + 'multiOptions' => $this->resources[$resourceType], + 'value' => current($this->resources[$resourceType]), + 'autosubmit' => true + ) + ); + $resourceName = isset($formData['resource']) ? $formData['resource'] : $this->getValue('resource'); + $this->addElement( + 'note', + 'resource_note', + array( + 'escape' => false, + 'value' => sprintf( + '<a href="%1$s" data-base-target="_next" title="%2$s" aria-label="%2$s">%3$s</a>', + $this->getView()->url('config/editresource', array('resource' => $resourceName)), + sprintf($this->translate('Show the configuration of the %s resource'), $resourceName), + $this->translate('Show resource configuration') + ) + ) + ); + + if (isset($formData['skip_validation']) && $formData['skip_validation']) { + // In case another error occured and the checkbox was displayed before + $this->addSkipValidationCheckbox(); + } + } + + /** + * Populate the configuration of the backend to load + */ + public function onRequest() + { + if ($this->backendToLoad) { + $data = $this->config->getSection($this->backendToLoad)->toArray(); + $data['name'] = $this->backendToLoad; + $this->populate($data); + } + } + + /** + * Return whether the given values are valid + * + * @param array $formData The data to validate + * + * @return bool + */ + public function isValid($formData) + { + if (! parent::isValid($formData)) { + return false; + } + + if (($el = $this->getElement('skip_validation')) === null || false === $el->isChecked()) { + $resourceConfig = ResourceFactory::getResourceConfig($this->getValue('resource')); + if (! self::isValidIdoSchema($this, $resourceConfig) + || (! $this->getElement('disabled')->isChecked() + && ! self::isValidIdoInstance($this, $resourceConfig)) + ) { + if ($el === null) { + $this->addSkipValidationCheckbox(); + } + + return false; + } + } + + return true; + } + + /** + * Add a checkbox to the form by which the user can skip the schema validation + */ + protected function addSkipValidationCheckbox() + { + $this->addElement( + 'checkbox', + 'skip_validation', + array( + 'order' => 0, + 'ignore' => true, + 'label' => $this->translate('Skip Validation'), + 'description' => $this->translate( + 'Check this to not to validate the IDO schema of the chosen resource.' + ) + ) + ); + } + + /** + * Return whether the given resource contains a valid IDO schema + * + * @param Form $form + * @param ConfigObject $resourceConfig + * + * @return bool + */ + public static function isValidIdoSchema(Form $form, ConfigObject $resourceConfig) + { + try { + $db = ResourceFactory::createResource($resourceConfig); + $db->select()->from('icinga_dbversion', array('version'))->fetchOne(); + } catch (Exception $_) { + $form->error($form->translate( + 'Cannot find the IDO schema. Please verify that the given database ' + . 'contains the schema and that the configured user has access to it.' + )); + return false; + } + + return true; + } + + /** + * Return whether a single icinga instance is writing to the given resource + * + * @param Form $form + * @param ConfigObject $resourceConfig + * + * @return bool True if it's a single instance, false if none + * or multiple instances are writing to it + */ + public static function isValidIdoInstance(Form $form, ConfigObject $resourceConfig) + { + $db = ResourceFactory::createResource($resourceConfig); + $rowCount = $db->select()->from('icinga_instances')->count(); + + if ($rowCount === 0) { + $form->warning($form->translate( + 'There is currently no icinga instance writing to the IDO. Make sure ' + . 'that a icinga instance is configured and able to write to the IDO.' + )); + return false; + } elseif ($rowCount > 1) { + $form->warning($form->translate( + 'There is currently more than one icinga instance writing to the IDO. You\'ll see all objects from all' + . ' instances without any differentation. If this is not desired, consider setting up a separate IDO' + . ' for each instance.' + )); + return false; + } + + return true; + } +} diff --git a/modules/monitoring/application/forms/Config/SecurityConfigForm.php b/modules/monitoring/application/forms/Config/SecurityConfigForm.php new file mode 100644 index 0000000..d57f985 --- /dev/null +++ b/modules/monitoring/application/forms/Config/SecurityConfigForm.php @@ -0,0 +1,75 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Config; + +use Icinga\Web\Notification; +use Icinga\Forms\ConfigForm; + +/** + * Form for modifying security relevant settings + */ +class SecurityConfigForm extends ConfigForm +{ + /** + * Initialize this form + */ + public function init() + { + $this->setName('form_config_monitoring_security'); + $this->setSubmitLabel($this->translate('Save Changes')); + } + + /** + * @see Form::onSuccess() + */ + public function onSuccess() + { + $this->config->setSection('security', $this->getValues()); + + if ($this->save()) { + Notification::success($this->translate('New security configuration has successfully been stored')); + } else { + return false; + } + } + + /** + * @see Form::onRequest() + */ + public function onRequest() + { + $this->populate($this->config->getSection('security')->toArray()); + } + + /** + * @see Form::createElements() + */ + public function createElements(array $formData) + { + $this->addElement( + 'text', + 'protected_customvars', + array( + 'allowEmpty' => true, + 'attribs' => array('placeholder' => $this->getDefaultProtectedCustomvars()), + 'label' => $this->translate('Protected Custom Variables'), + 'description' => $this->translate( + 'Comma separated case insensitive list of protected custom variables.' + . ' Use * as a placeholder for zero or more wildcard characters.' + . ' Existence of those custom variables will be shown, but their values will be masked.' + ) + ) + ); + } + + /** + * Return the customvars to suggest to protect when none are protected + * + * @return string + */ + public function getDefaultProtectedCustomvars() + { + return '*pw*,*pass*,community'; + } +} diff --git a/modules/monitoring/application/forms/Config/Transport/ApiTransportForm.php b/modules/monitoring/application/forms/Config/Transport/ApiTransportForm.php new file mode 100644 index 0000000..3d501e0 --- /dev/null +++ b/modules/monitoring/application/forms/Config/Transport/ApiTransportForm.php @@ -0,0 +1,75 @@ +<?php +/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Config\Transport; + +use Icinga\Web\Form; + +class ApiTransportForm extends Form +{ + /** + * {@inheritdoc} + */ + public function init() + { + $this->setName('form_config_command_transport_api'); + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData = array()) + { + $this->addElements(array( + array( + 'text', + 'host', + array( + 'required' => true, + 'label' => $this->translate('Host'), + 'description' => $this->translate( + 'Hostname or address of the remote Icinga instance' + ) + ) + ), + array( + 'number', + 'port', + array( + 'required' => true, + 'preserveDefault' => true, + 'label' => $this->translate('Port'), + 'description' => $this->translate('SSH port to connect to on the remote Icinga instance'), + 'value' => 5665 + ) + ), + array( + 'text', + 'username', + array( + 'required' => true, + 'label' => $this->translate('API Username'), + 'description' => $this->translate( + 'User to log in as on the remote Icinga instance. Please note that key-based SSH login must be' + . ' possible for this user' + ) + ) + ), + array( + 'password', + 'password', + array( + 'required' => true, + 'label' => $this->translate('API Password'), + 'description' => $this->translate( + 'User to log in as on the remote Icinga instance. Please note that key-based SSH login must be' + . ' possible for this user' + ), + 'renderPassword' => true + ) + ) + )); + + return $this; + } +} diff --git a/modules/monitoring/application/forms/Config/Transport/LocalTransportForm.php b/modules/monitoring/application/forms/Config/Transport/LocalTransportForm.php new file mode 100644 index 0000000..15c7357 --- /dev/null +++ b/modules/monitoring/application/forms/Config/Transport/LocalTransportForm.php @@ -0,0 +1,37 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Config\Transport; + +use Icinga\Web\Form; + +class LocalTransportForm extends Form +{ + /** + * (non-PHPDoc) + * @see Form::init() For the method documentation. + */ + public function init() + { + $this->setName('form_config_command_transport_local'); + } + + /** + * (non-PHPDoc) + * @see Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + $this->addElement( + 'text', + 'path', + array( + 'required' => true, + 'label' => $this->translate('Command File'), + 'value' => '/var/run/icinga2/cmd/icinga2.cmd', + 'description' => $this->translate('Path to the local Icinga command file') + ) + ); + return $this; + } +} diff --git a/modules/monitoring/application/forms/Config/Transport/RemoteTransportForm.php b/modules/monitoring/application/forms/Config/Transport/RemoteTransportForm.php new file mode 100644 index 0000000..7beeacf --- /dev/null +++ b/modules/monitoring/application/forms/Config/Transport/RemoteTransportForm.php @@ -0,0 +1,185 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Config\Transport; + +use Icinga\Data\ResourceFactory; +use Icinga\Exception\ConfigurationError; +use Icinga\Web\Form; + +class RemoteTransportForm extends Form +{ + /** + * The available resources split by type + * + * @var array + */ + protected $resources; + + /** + * (non-PHPDoc) + * @see Form::init() For the method documentation. + */ + public function init() + { + $this->setName('form_config_command_transport_remote'); + } + + /** + * Load all available ssh identity resources + * + * @return $this + * + * @throws \Icinga\Exception\ConfigurationError + */ + public function loadResources() + { + $resourceConfig = ResourceFactory::getResourceConfigs(); + + $resources = array(); + foreach ($resourceConfig as $name => $resource) { + if ($resource->type === 'ssh') { + $resources['ssh'][$name] = $name; + } + } + + if (empty($resources)) { + throw new ConfigurationError($this->translate('Could not find any valid SSH resources')); + } + + $this->resources = $resources; + + return $this; + } + + /** + * Check whether ssh identity resources exists or not + * + * @return boolean + */ + public function hasResources() + { + $resourceConfig = ResourceFactory::getResourceConfigs(); + + foreach ($resourceConfig as $name => $resource) { + if ($resource->type === 'ssh') { + return true; + } + } + return false; + } + + /** + * (non-PHPDoc) + * @see Form::createElements() For the method documentation. + */ + public function createElements(array $formData = array()) + { + $useResource = false; + + if ($this->hasResources()) { + $useResource = isset($formData['use_resource']) + ? $formData['use_resource'] : $this->getValue('use_resource'); + + $this->addElement( + 'checkbox', + 'use_resource', + array( + 'label' => $this->translate('Use SSH Identity'), + 'description' => $this->translate('Make use of the ssh identity resource'), + 'autosubmit' => true, + 'ignore' => true + ) + ); + } + + if ($useResource) { + $this->loadResources(); + + $decorators = static::$defaultElementDecorators; + array_pop($decorators); // Removes the HtmlTag decorator + + $this->addElement( + 'select', + 'resource', + array( + 'required' => true, + 'label' => $this->translate('SSH Identity'), + 'description' => $this->translate('The resource to use'), + 'decorators' => $decorators, + 'multiOptions' => $this->resources['ssh'], + 'value' => current($this->resources['ssh']), + 'autosubmit' => false + ) + ); + $resourceName = isset($formData['resource']) ? $formData['resource'] : $this->getValue('resource'); + $this->addElement( + 'note', + 'resource_note', + array( + 'escape' => false, + 'decorators' => $decorators, + 'value' => sprintf( + '<a href="%1$s" data-base-target="_next" title="%2$s" aria-label="%2$s">%3$s</a>', + $this->getView()->url('config/editresource', array('resource' => $resourceName)), + sprintf($this->translate('Show the configuration of the %s resource'), $resourceName), + $this->translate('Show resource configuration') + ) + ) + ); + } + + $this->addElements(array( + array( + 'text', + 'host', + array( + 'required' => true, + 'label' => $this->translate('Host'), + 'description' => $this->translate( + 'Hostname or address of the remote Icinga instance' + ) + ) + ), + array( + 'number', + 'port', + array( + 'required' => true, + 'preserveDefault' => true, + 'label' => $this->translate('Port'), + 'description' => $this->translate('SSH port to connect to on the remote Icinga instance'), + 'value' => 22 + ) + ) + )); + + if (! $useResource) { + $this->addElement( + 'text', + 'user', + array( + 'required' => true, + 'label' => $this->translate('User'), + 'description' => $this->translate( + 'User to log in as on the remote Icinga instance. Please note that key-based SSH login must be' + . ' possible for this user' + ) + ) + ); + } + + $this->addElement( + 'text', + 'path', + array( + 'required' => true, + 'label' => $this->translate('Command File'), + 'value' => '/var/run/icinga2/cmd/icinga2.cmd', + 'description' => $this->translate('Path to the Icinga command file on the remote Icinga instance') + ) + ); + + return $this; + } +} diff --git a/modules/monitoring/application/forms/Config/TransportConfigForm.php b/modules/monitoring/application/forms/Config/TransportConfigForm.php new file mode 100644 index 0000000..c68e63d --- /dev/null +++ b/modules/monitoring/application/forms/Config/TransportConfigForm.php @@ -0,0 +1,392 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Config; + +use Icinga\Data\ConfigObject; +use Icinga\Module\Monitoring\Command\Transport\CommandTransport; +use Icinga\Module\Monitoring\Exception\CommandTransportException; +use InvalidArgumentException; +use Icinga\Application\Platform; +use Icinga\Exception\IcingaException; +use Icinga\Exception\NotFoundError; +use Icinga\Forms\ConfigForm; +use Icinga\Module\Monitoring\Command\Transport\ApiCommandTransport; +use Icinga\Module\Monitoring\Command\Transport\LocalCommandFile; +use Icinga\Module\Monitoring\Command\Transport\RemoteCommandFile; +use Icinga\Module\Monitoring\Forms\Config\Transport\ApiTransportForm; +use Icinga\Module\Monitoring\Forms\Config\Transport\LocalTransportForm; +use Icinga\Module\Monitoring\Forms\Config\Transport\RemoteTransportForm; + +/** + * Form for managing command transports + */ +class TransportConfigForm extends ConfigForm +{ + /** + * The transport to load when displaying the form for the first time + * + * @var string + */ + protected $transportToLoad; + + /** + * The names of all available Icinga instances + * + * @var array + */ + protected $instanceNames; + + /** + * @var bool + */ + protected $validatePartial = true; + + /** + * Initialize this form + */ + public function init() + { + $this->setName('form_config_command_transports'); + $this->setSubmitLabel($this->translate('Save Changes')); + } + + /** + * Set the names of all available Icinga instances + * + * @param array $names + * + * @return $this + */ + public function setInstanceNames(array $names) + { + $this->instanceNames = $names; + return $this; + } + + /** + * Return the names of all available Icinga instances + * + * @return array + */ + public function getInstanceNames() + { + return $this->instanceNames ?: array(); + } + + /** + * Return a form object for the given transport type + * + * @param string $type The transport type for which to return a form + * + * @return \Icinga\Web\Form + * + * @throws InvalidArgumentException In case the given transport type is invalid + */ + public function getTransportForm($type) + { + switch (strtolower($type)) { + case LocalCommandFile::TRANSPORT: + return new LocalTransportForm(); + case RemoteCommandFile::TRANSPORT: + return new RemoteTransportForm(); + case ApiCommandTransport::TRANSPORT: + return new ApiTransportForm(); + default: + throw new InvalidArgumentException( + sprintf($this->translate('Invalid command transport type "%s" given'), $type) + ); + } + } + + /** + * Populate the form with the given transport's config + * + * @param string $name + * + * @return $this + * + * @throws NotFoundError In case no transport with the given name is found + */ + public function load($name) + { + if (! $this->config->hasSection($name)) { + throw new NotFoundError('No command transport called "%s" found', $name); + } + + $this->transportToLoad = $name; + return $this; + } + + /** + * Add a new command transport + * + * The transport to add is identified by the array-key `name'. + * + * @param array $data + * + * @return $this + * + * @throws InvalidArgumentException In case $data does not contain a transport name + * @throws IcingaException In case a transport with the same name already exists + */ + public function add(array $data) + { + if (! isset($data['name'])) { + throw new InvalidArgumentException('Key \'name\' missing'); + } + + $transportName = $data['name']; + if ($this->config->hasSection($transportName)) { + throw new IcingaException( + $this->translate('A command transport with the name "%s" does already exist'), + $transportName + ); + } + + unset($data['name']); + $this->config->setSection($transportName, $data); + return $this; + } + + /** + * Edit an existing command transport + * + * @param string $name + * @param array $data + * + * @return $this + * + * @throws NotFoundError In case no transport with the given name is found + */ + public function edit($name, array $data) + { + if (! $this->config->hasSection($name)) { + throw new NotFoundError('No command transport called "%s" found', $name); + } + + $transportConfig = $this->config->getSection($name); + if (isset($data['name'])) { + if ($data['name'] !== $name) { + $this->config->removeSection($name); + $name = $data['name']; + } + + unset($data['name']); + } + + $transportConfig->merge($data); + $this->config->setSection($name, $transportConfig); + return $this; + } + + /** + * Remove a command transport + * + * @param string $name + * + * @return $this + */ + public function delete($name) + { + $this->config->removeSection($name); + return $this; + } + + /** + * Create and add elements to this form + * + * @param array $formData + */ + public function createElements(array $formData) + { + $instanceNames = $this->getInstanceNames(); + if (count($instanceNames) > 1) { + $options = array('none' => $this->translate('None', 'command transport instance association')); + $this->addElement( + 'select', + 'instance', + array( + 'label' => $this->translate('Instance Link'), + 'description' => $this->translate( + 'The name of the Icinga instance this transport should exclusively transfer commands to.' + ), + 'multiOptions' => array_merge($options, array_combine($instanceNames, $instanceNames)) + ) + ); + } + + $this->addElement( + 'text', + 'name', + array( + 'required' => true, + 'label' => $this->translate('Transport Name'), + 'description' => $this->translate( + 'The name of this command transport that is used to differentiate it from others' + ) + ) + ); + + $transportTypes = array( + ApiCommandTransport::TRANSPORT => $this->translate('Icinga 2 API'), + LocalCommandFile::TRANSPORT => $this->translate('Local Command File'), + RemoteCommandFile::TRANSPORT => $this->translate('Remote Command File') + ); + if (! Platform::extensionLoaded('curl')) { + unset($transportTypes[ApiCommandTransport::TRANSPORT]); + } + + $transportType = isset($formData['transport']) ? $formData['transport'] : null; + if ($transportType === null) { + $transportType = key($transportTypes); + } + + $this->addElements(array( + array( + 'select', + 'transport', + array( + 'required' => true, + 'autosubmit' => true, + 'label' => $this->translate('Transport Type'), + 'multiOptions' => $transportTypes + ) + ) + )); + + $this->addSubForm($this->getTransportForm($transportType)->create($formData), 'transport_form'); + } + + /** + * Add a submit button to this form and one to manually validate the configuration + * + * Calls parent::addSubmitButton() to add the submit button. + * + * @return $this + */ + public function addSubmitButton() + { + parent::addSubmitButton(); + + if ($this->getSubForm('transport_form') instanceof ApiTransportForm) { + $btnSubmit = $this->getElement('btn_submit'); + + if ($btnSubmit !== null) { + // In the setup wizard $this is being used as a subform which doesn't have a submit button. + $this->addElement( + 'submit', + 'transport_validation', + array( + 'ignore' => true, + 'label' => $this->translate('Validate Configuration'), + 'data-progress-label' => $this->translate('Validation In Progress'), + 'decorators' => array('ViewHelper') + ) + ); + + $this->setAttrib('data-progress-element', 'transport-progress'); + $this->addElement( + 'note', + 'transport-progress', + array( + 'decorators' => array( + 'ViewHelper', + array('Spinner', array('id' => 'transport-progress')) + ) + ) + ); + + $elements = array('transport_validation', 'transport-progress'); + + $btnSubmit->setDecorators(array('ViewHelper')); + array_unshift($elements, 'btn_submit'); + + $this->addDisplayGroup( + $elements, + 'submit_validation', + array( + 'decorators' => array( + 'FormElements', + array('HtmlTag', array('tag' => 'div', 'class' => 'control-group form-controls')) + ) + ) + ); + } + } + + return $this; + } + + /** + * Populate the configuration of the transport to load + */ + public function onRequest() + { + if ($this->transportToLoad) { + $data = $this->config->getSection($this->transportToLoad)->toArray(); + $data['name'] = $this->transportToLoad; + $this->populate($data); + } + } + + /** + * {@inheritdoc} + */ + public function isValidPartial(array $formData) + { + $isValidPartial = parent::isValidPartial($formData); + + $transportValidation = $this->getElement('transport_validation'); + if ($transportValidation !== null && $transportValidation->isChecked() && $this->isValid($formData)) { + $this->info($this->translate('The configuration has been successfully validated.')); + } + + return $isValidPartial; + } + + /** + * {@inheritdoc} + */ + public function isValid($formData) + { + if (! parent::isValid($formData)) { + return false; + } + + if ($this->getSubForm('transport_form') instanceof ApiTransportForm) { + if (! isset($formData['transport_validation']) + && isset($formData['force_creation']) && $formData['force_creation'] + ) { + // ignore any validation result + return true; + } + + try { + CommandTransport::createTransport(new ConfigObject($this->getValues()))->probe(); + } catch (CommandTransportException $e) { + $this->error(sprintf( + $this->translate('Failed to successfully validate the configuration: %s'), + $e->getMessage() + )); + + $this->addElement( + 'checkbox', + 'force_creation', + array( + 'order' => 0, + 'ignore' => true, + 'label' => $this->translate('Force Changes'), + 'description' => $this->translate( + 'Check this box to enforce changes without connectivity validation' + ) + ) + ); + + return false; + } + } + + return true; + } +} diff --git a/modules/monitoring/application/forms/Config/TransportReorderForm.php b/modules/monitoring/application/forms/Config/TransportReorderForm.php new file mode 100644 index 0000000..f3efe4c --- /dev/null +++ b/modules/monitoring/application/forms/Config/TransportReorderForm.php @@ -0,0 +1,87 @@ +<?php +/* Icinga Web 2 | (c) 2017 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Config; + +use Icinga\Application\Config; +use Icinga\Web\Form; +use Icinga\Web\Notification; + +/** + * Form for reordering command transports + */ +class TransportReorderForm extends Form +{ + /** + * Initialize this form + */ + public function init() + { + $this->setName('form_reorder_command_transports'); + $this->setViewScript('form/reorder-command-transports.phtml'); + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData) + { + // This adds just a dummy element to be able to utilize Form::getValue as part of onSuccess() + $this->addElement( + 'hidden', + 'transport_newpos', + array( + 'required' => true, + 'validators' => array( + array( + 'validator' => 'regex', + 'options' => array( + 'pattern' => '/\A\d+\|/' + ) + ) + ) + ) + ); + } + + /** + * Update the command transport order and save the configuration + */ + public function onSuccess() + { + list($position, $transportName) = explode('|', $this->getValue('transport_newpos'), 2); + $config = $this->getConfig(); + if (! $config->hasSection($transportName)) { + Notification::error(sprintf($this->translate('Command transport "%s" not found'), $transportName)); + return false; + } + + if ($config->count() > 1) { + $sections = $config->keys(); + array_splice($sections, array_search($transportName, $sections, true), 1); + array_splice($sections, $position, 0, array($transportName)); + + $sectionsInNewOrder = array(); + foreach ($sections as $section) { + $sectionsInNewOrder[$section] = $config->getSection($section); + $config->removeSection($section); + } + foreach ($sectionsInNewOrder as $name => $options) { + $config->setSection($name, $options); + } + + $config->saveIni(); + Notification::success($this->translate('Command transport order updated')); + } + } + + /** + * Get the command transports config + * + * @return Config + */ + public function getConfig() + { + return Config::module('monitoring', 'commandtransports'); + } +} diff --git a/modules/monitoring/application/forms/EventOverviewForm.php b/modules/monitoring/application/forms/EventOverviewForm.php new file mode 100644 index 0000000..78774f9 --- /dev/null +++ b/modules/monitoring/application/forms/EventOverviewForm.php @@ -0,0 +1,157 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms; + +use Icinga\Web\Url; +use Icinga\Web\Form; +use Icinga\Data\Filter\Filter; + +/** + * Configure the filter for the event overview + */ +class EventOverviewForm extends Form +{ + /** + * {@inheritdoc} + */ + public function init() + { + $this->setName('form_event_overview'); + $this->setDecorators(array( + 'FormElements', + array('HtmlTag', array('tag' => 'div', 'class' => 'hbox')), + 'Form' + )); + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData) + { + $decorators = array( + array('Label', array('class' => 'optional')), + 'ViewHelper', + array('HtmlTag', array('tag' => 'div', 'class' => 'hbox-item optionbox')), + ); + + $url = Url::fromRequest()->getAbsoluteUrl(); + $this->addElement( + 'checkbox', + 'statechange', + array( + 'label' => $this->translate('State Changes'), + 'class' => 'autosubmit', + 'decorators' => $decorators, + 'value' => strpos($url, $this->stateChangeFilter()->toQueryString()) === false ? 0 : 1 + ) + ); + $this->addElement( + 'checkbox', + 'downtime', + array( + 'label' => $this->translate('Downtimes'), + 'class' => 'autosubmit', + 'decorators' => $decorators, + 'value' => strpos($url, $this->downtimeFilter()->toQueryString()) === false ? 0 : 1 + ) + ); + $this->addElement( + 'checkbox', + 'comment', + array( + 'label' => $this->translate('Comments'), + 'class' => 'autosubmit', + 'decorators' => $decorators, + 'value' => strpos($url, $this->commentFilter()->toQueryString()) === false ? 0 : 1 + ) + ); + $this->addElement( + 'checkbox', + 'notification', + array( + 'label' => $this->translate('Notifications'), + 'class' => 'autosubmit', + 'decorators' => $decorators, + 'value' => strpos($url, $this->notificationFilter()->toQueryString()) === false ? 0 : 1 + ) + ); + $this->addElement( + 'checkbox', + 'flapping', + array( + 'label' => $this->translate('Flapping'), + 'class' => 'autosubmit', + 'decorators' => $decorators, + 'value' => strpos($url, $this->flappingFilter()->toQueryString()) === false ? 0 : 1 + ) + ); + } + + /** + * Return the corresponding filter-object + * + * @returns Filter + */ + public function getFilter() + { + $filters = array(); + if ($this->getValue('statechange')) { + $filters[] = $this->stateChangeFilter(); + } + if ($this->getValue('comment')) { + $filters[] = $this->commentFilter(); + } + if ($this->getValue('notification')) { + $filters[] = $this->notificationFilter(); + } + if ($this->getValue('downtime')) { + $filters[] = $this->downtimeFilter(); + } + if ($this->getValue('flapping')) { + $filters[] = $this->flappingFilter(); + } + return Filter::matchAny($filters); + } + + public function stateChangeFilter() + { + return Filter::matchAny( + Filter::expression('type', '=', 'hard_state'), + Filter::expression('type', '=', 'soft_state') + ); + } + + public function commentFilter() + { + return Filter::matchAny( + Filter::expression('type', '=', 'comment'), + Filter::expression('type', '=', 'comment_deleted'), + Filter::expression('type', '=', 'dt_comment'), + Filter::expression('type', '=', 'dt_comment_deleted'), + Filter::expression('type', '=', 'ack') + ); + } + + public function notificationFilter() + { + return Filter::expression('type', '=', 'notify'); + } + + public function downtimeFilter() + { + return Filter::matchAny( + Filter::expression('type', '=', 'downtime_start'), + Filter::expression('type', '=', 'downtime_end') + ); + } + + public function flappingFilter() + { + return Filter::matchAny( + Filter::expression('type', '=', 'flapping'), + Filter::expression('type', '=', 'flapping_deleted') + ); + } +} diff --git a/modules/monitoring/application/forms/Navigation/ActionForm.php b/modules/monitoring/application/forms/Navigation/ActionForm.php new file mode 100644 index 0000000..81d5588 --- /dev/null +++ b/modules/monitoring/application/forms/Navigation/ActionForm.php @@ -0,0 +1,79 @@ +<?php +/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Navigation; + +use Icinga\Data\Filter\Filter; +use Icinga\Exception\QueryException; +use Icinga\Forms\Navigation\NavigationItemForm; + +class ActionForm extends NavigationItemForm +{ + /** + * {@inheritdoc} + */ + public function createElements(array $formData) + { + parent::createElements($formData); + + $this->addElement( + 'text', + 'filter', + array( + 'allowEmpty' => true, + 'label' => $this->translate('Filter'), + 'description' => $this->translate( + 'Display this action only for objects matching this filter. Leave it blank' + . ' if you want this action being displayed regardless of the object' + ) + ) + ); + } + + /** + * {@inheritdoc} + */ + public function isValid($formData) + { + if (! parent::isValid($formData)) { + return false; + } + + if (($filterString = $this->getValue('filter')) !== null) { + $filter = Filter::matchAll(); + $filter->setAllowedFilterColumns(array( + 'host_name', + 'hostgroup_name', + 'instance_name', + 'service_description', + 'servicegroup_name', + 'contact_name', + 'contactgroup_name', + function ($c) { + return preg_match('/^_(?:host|service)_/', $c); + } + )); + + try { + $filter->addFilter(Filter::fromQueryString($filterString)); + } catch (QueryException $_) { + $this->getElement('filter')->addError(sprintf( + $this->translate('Invalid filter provided. You can only use the following columns: %s'), + implode(', ', array( + 'instance_name', + 'host_name', + 'hostgroup_name', + 'service_description', + 'servicegroup_name', + 'contact_name', + 'contactgroup_name', + '_(host|service)_<customvar-name>' + )) + )); + return false; + } + } + + return true; + } +} diff --git a/modules/monitoring/application/forms/Navigation/HostActionForm.php b/modules/monitoring/application/forms/Navigation/HostActionForm.php new file mode 100644 index 0000000..da237d4 --- /dev/null +++ b/modules/monitoring/application/forms/Navigation/HostActionForm.php @@ -0,0 +1,8 @@ +<?php +/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Navigation; + +class HostActionForm extends ActionForm +{ +} diff --git a/modules/monitoring/application/forms/Navigation/ServiceActionForm.php b/modules/monitoring/application/forms/Navigation/ServiceActionForm.php new file mode 100644 index 0000000..68314d1 --- /dev/null +++ b/modules/monitoring/application/forms/Navigation/ServiceActionForm.php @@ -0,0 +1,8 @@ +<?php +/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Navigation; + +class ServiceActionForm extends ActionForm +{ +} diff --git a/modules/monitoring/application/forms/Setup/BackendPage.php b/modules/monitoring/application/forms/Setup/BackendPage.php new file mode 100644 index 0000000..d5c7efb --- /dev/null +++ b/modules/monitoring/application/forms/Setup/BackendPage.php @@ -0,0 +1,51 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Setup; + +use Icinga\Web\Form; +use Icinga\Application\Platform; + +class BackendPage extends Form +{ + public function init() + { + $this->setName('setup_monitoring_backend'); + $this->setTitle($this->translate('Monitoring Backend', 'setup.page.title')); + $this->addDescription($this->translate( + 'Please configure below how Icinga Web 2 should retrieve monitoring information.' + )); + } + + public function createElements(array $formData) + { + $this->addElement( + 'text', + 'name', + array( + 'required' => true, + 'value' => 'icinga', + 'label' => $this->translate('Backend Name'), + 'description' => $this->translate('The identifier of this backend') + ) + ); + + $resourceTypes = array(); + if (Platform::hasMysqlSupport() || Platform::hasPostgresqlSupport()) { + $resourceTypes['ido'] = 'IDO'; + } + + $this->addElement( + 'select', + 'type', + array( + 'required' => true, + 'label' => $this->translate('Backend Type'), + 'description' => $this->translate( + 'The data source used for retrieving monitoring information' + ), + 'multiOptions' => $resourceTypes + ) + ); + } +} diff --git a/modules/monitoring/application/forms/Setup/IdoResourcePage.php b/modules/monitoring/application/forms/Setup/IdoResourcePage.php new file mode 100644 index 0000000..d648579 --- /dev/null +++ b/modules/monitoring/application/forms/Setup/IdoResourcePage.php @@ -0,0 +1,188 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Setup; + +use Icinga\Data\ConfigObject; +use Icinga\Forms\Config\ResourceConfigForm; +use Icinga\Forms\Config\Resource\DbResourceForm; +use Icinga\Web\Form; +use Icinga\Module\Monitoring\Forms\Config\BackendConfigForm; +use Icinga\Module\Setup\Utils\DbTool; + +class IdoResourcePage extends Form +{ + /** + * Initialize this form + */ + public function init() + { + $this->setName('setup_monitoring_ido'); + $this->setTitle($this->translate('Monitoring IDO Resource', 'setup.page.title')); + $this->addDescription($this->translate( + 'Please fill out the connection details below to access the IDO database of your monitoring environment.' + )); + $this->setValidatePartial(true); + } + + /** + * Create and add elements to this form + * + * @param array $formData + */ + public function createElements(array $formData) + { + $this->addElement( + 'hidden', + 'type', + array( + 'required' => true, + 'value' => 'db' + ) + ); + + if (isset($formData['skip_validation']) && $formData['skip_validation']) { + // In case another error occured and the checkbox was displayed before + $this->addSkipValidationCheckbox(); + } else { + $this->addElement( + 'hidden', + 'skip_validation', + array( + 'required' => true, + 'value' => 0 + ) + ); + } + + $dbResourceForm = new DbResourceForm(); + $this->addElements($dbResourceForm->createElements($formData)->getElements()); + $this->getElement('name')->setValue('icinga_ido'); + } + + /** + * Return whether the given values are valid + * + * @param array $formData The data to validate + * + * @return bool + */ + public function isValid($formData) + { + if (! parent::isValid($formData)) { + return false; + } + + if (! isset($formData['skip_validation']) || !$formData['skip_validation']) { + if (! $this->validateConfiguration()) { + $this->addSkipValidationCheckbox(); + return false; + } + } + + return true; + } + + /** + * Run the configured backend's inspection checks and show the result, if necessary + * + * This will only run any validation if the user pushed the 'backend_validation' button. + * + * @param array $formData + * + * @return bool + */ + public function isValidPartial(array $formData) + { + if (isset($formData['backend_validation']) && parent::isValid($formData)) { + if (! $this->validateConfiguration(true)) { + return false; + } + + $this->info($this->translate('The configuration has been successfully validated.')); + } elseif (! isset($formData['backend_validation'])) { + // This is usually done by isValid(Partial), but as we're not calling any of these... + $this->populate($formData); + } + + return true; + } + + /** + * Return whether the configuration is valid + * + * @param bool $showLog Whether to show the validation log + * + * @return bool + */ + protected function validateConfiguration($showLog = false) + { + $inspection = ResourceConfigForm::inspectResource($this); + if ($inspection !== null) { + if ($showLog) { + $join = function ($e) use (&$join) { + return is_string($e) ? $e : join("\n", array_map($join, $e)); + }; + $this->addElement( + 'note', + 'inspection_output', + array( + 'order' => 0, + 'value' => '<strong>' . $this->translate('Validation Log') . "</strong>\n\n" + . join("\n", array_map($join, $inspection->toArray())), + 'decorators' => array( + 'ViewHelper', + array('HtmlTag', array('tag' => 'pre', 'class' => 'log-output')), + ) + ) + ); + } + + if ($inspection->hasError()) { + $this->error(sprintf( + $this->translate('Failed to successfully validate the configuration: %s'), + $inspection->getError() + )); + return false; + } + } + + $configObject = new ConfigObject($this->getValues()); + if (! BackendConfigForm::isValidIdoSchema($this, $configObject) + || !BackendConfigForm::isValidIdoInstance($this, $configObject) + ) { + return false; + } + + if ($this->getValue('db') === 'pgsql') { + $db = new DbTool($this->getValues()); + $version = $db->connectToDb()->getServerVersion(); + if (version_compare($version, '9.1', '<')) { + $this->error(sprintf( + $this->translate('The server\'s version %s is too old. The minimum required version is %s.'), + $version, + '9.1' + )); + return false; + } + } + + return true; + } + + /** + * Add a checkbox to the form by which the user can skip the configuration validation + */ + protected function addSkipValidationCheckbox() + { + $this->addElement( + 'checkbox', + 'skip_validation', + array( + 'required' => true, + 'label' => $this->translate('Skip Validation'), + 'description' => $this->translate('Check this to not to validate the configuration') + ) + ); + } +} diff --git a/modules/monitoring/application/forms/Setup/SecurityPage.php b/modules/monitoring/application/forms/Setup/SecurityPage.php new file mode 100644 index 0000000..999103c --- /dev/null +++ b/modules/monitoring/application/forms/Setup/SecurityPage.php @@ -0,0 +1,27 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Setup; + +use Icinga\Web\Form; +use Icinga\Module\Monitoring\Forms\Config\SecurityConfigForm; + +class SecurityPage extends Form +{ + public function init() + { + $this->setName('setup_monitoring_security'); + $this->setTitle($this->translate('Monitoring Security', 'setup.page.title')); + $this->addDescription($this->translate( + 'To protect your monitoring environment against prying eyes please fill out the settings below.' + )); + } + + public function createElements(array $formData) + { + $securityConfigForm = new SecurityConfigForm(); + $securityConfigForm->createElements($formData); + $this->addElements($securityConfigForm->getElements()); + $this->getElement('protected_customvars')->setValue($securityConfigForm->getDefaultProtectedCustomvars()); + } +} diff --git a/modules/monitoring/application/forms/Setup/TransportPage.php b/modules/monitoring/application/forms/Setup/TransportPage.php new file mode 100644 index 0000000..9d0760a --- /dev/null +++ b/modules/monitoring/application/forms/Setup/TransportPage.php @@ -0,0 +1,55 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Setup; + +use Icinga\Web\Form; +use Icinga\Module\Monitoring\Forms\Config\TransportConfigForm; + +class TransportPage extends Form +{ + public function init() + { + $this->setName('setup_command_transport'); + $this->setTitle($this->translate('Command Transport', 'setup.page.title')); + $this->addDescription($this->translate( + 'Please define below how you want to send commands to your monitoring instance.' + )); + $this->setValidatePartial(true); + } + + public function createElements(array $formData) + { + $transportConfigForm = new TransportConfigForm(); + $this->addSubForm($transportConfigForm, 'transport_form'); + $transportConfigForm->create($formData); + $transportConfigForm->removeElement('instance'); + $transportConfigForm->getElement('name')->setValue('icinga2'); + } + + public function getValues($suppressArrayNotation = false) + { + return $this->getSubForm('transport_form')->getValues($suppressArrayNotation); + } + + /** + * Run the configured backend's inspection checks and show the result, if necessary + * + * This will only run any validation if the user pushed the 'transport_validation' button. + * + * @param array $formData + * + * @return bool + */ + public function isValidPartial(array $formData) + { + if (isset($formData['transport_validation']) && parent::isValid($formData)) { + $this->info($this->translate('The configuration has been successfully validated.')); + } elseif (! isset($formData['transport_validation'])) { + // This is usually done by isValid(Partial), but as we're not calling any of these... + $this->populate($formData); + } + + return true; + } +} diff --git a/modules/monitoring/application/forms/Setup/WelcomePage.php b/modules/monitoring/application/forms/Setup/WelcomePage.php new file mode 100644 index 0000000..aa78db5 --- /dev/null +++ b/modules/monitoring/application/forms/Setup/WelcomePage.php @@ -0,0 +1,63 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms\Setup; + +use Icinga\Web\Form; + +class WelcomePage extends Form +{ + public function init() + { + $this->setName('setup_monitoring_welcome'); + } + + public function createElements(array $formData) + { + $this->addElement( + 'note', + 'welcome', + array( + 'value' => $this->translate( + 'Welcome to the configuration of the monitoring module for Icinga Web 2!' + ), + 'decorators' => array( + 'ViewHelper', + array('HtmlTag', array('tag' => 'h2')) + ) + ) + ); + + $this->addElement( + 'note', + 'core_hint', + array( + 'value' => $this->translate('This is the core module for Icinga Web 2.'), + 'decorators' => array('ViewHelper') + ) + ); + + $this->addElement( + 'note', + 'description', + array( + 'value' => $this->translate( + 'It offers various status and reporting views with powerful filter capabilities that allow' + . ' you to keep track of the most important events in your monitoring environment.' + ), + 'decorators' => array('ViewHelper') + ) + ); + + $this->addDisplayGroup( + array('core_hint', 'description'), + 'info', + array( + 'decorators' => array( + 'FormElements', + array('HtmlTag', array('tag' => 'div', 'class' => 'info')) + ) + ) + ); + } +} diff --git a/modules/monitoring/application/forms/StatehistoryForm.php b/modules/monitoring/application/forms/StatehistoryForm.php new file mode 100644 index 0000000..c28e39c --- /dev/null +++ b/modules/monitoring/application/forms/StatehistoryForm.php @@ -0,0 +1,141 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Monitoring\Forms; + +use Icinga\Web\Form; +use Icinga\Data\Filter\Filter; + +/** + * Configure the filter for the event grid + */ +class StatehistoryForm extends Form +{ + /** + * {@inheritdoc} + */ + public function init() + { + $this->setName('form_event_overview'); + $this->setSubmitLabel($this->translate('Apply')); + } + + /** + * Return the corresponding filter-object + * + * @returns Filter + */ + public function getFilter() + { + $baseFilter = Filter::matchAny( + Filter::expression('type', '=', 'hard_state') + ); + + if ($this->getValue('objecttype') === 'hosts') { + $objectTypeFilter = Filter::expression('object_type', '=', 'host'); + } else { + $objectTypeFilter = Filter::expression('object_type', '=', 'service'); + } + + $states = array( + 'cnt_down_hard' => Filter::expression('state', '=', '1'), + 'cnt_unreachable_hard' => Filter::expression('state', '=', '2'), + 'cnt_up' => Filter::expression('state', '=', '0'), + 'cnt_critical_hard' => Filter::expression('state', '=', '2'), + 'cnt_warning_hard' => Filter::expression('state', '=', '1'), + 'cnt_unknown_hard' => Filter::expression('state', '=', '3'), + 'cnt_ok' => Filter::expression('state', '=', '0') + ); + $state = $this->getValue('state'); + $stateFilter = $states[$state]; + if (in_array($state, array('cnt_ok', 'cnt_up'))) { + return Filter::matchAll($objectTypeFilter, $stateFilter); + } + return Filter::matchAll($baseFilter, $objectTypeFilter, $stateFilter); + } + + /** + * {@inheritdoc} + */ + public function createElements(array $formData) + { + $this->addElement( + 'select', + 'from', + array( + 'label' => $this->translate('From'), + 'value' => $this->getRequest()->getParam('from', strtotime('3 months ago')), + 'multiOptions' => array( + strtotime('midnight 3 months ago') => $this->translate('3 Months'), + strtotime('midnight 4 months ago') => $this->translate('4 Months'), + strtotime('midnight 8 months ago') => $this->translate('8 Months'), + strtotime('midnight 12 months ago') => $this->translate('1 Year'), + strtotime('midnight 24 months ago') => $this->translate('2 Years') + ) + ) + ); + $this->addElement( + 'select', + 'to', + array( + 'label' => $this->translate('To'), + 'value' => $this->getRequest()->getParam('to', time()), + 'multiOptions' => array( + time() => $this->translate('Today') + ) + ) + ); + + $objectType = $this->getRequest()->getParam('objecttype', 'services'); + $this->addElement( + 'select', + 'objecttype', + array( + 'label' => $this->translate('Object type'), + 'value' => $objectType, + 'multiOptions' => array( + 'services' => $this->translate('Services'), + 'hosts' => $this->translate('Hosts') + ) + ) + ); + if ($objectType === 'services') { + $serviceState = $this->getRequest()->getParam('state', 'cnt_critical_hard'); + if (in_array($serviceState, array('cnt_down_hard', 'cnt_unreachable_hard', 'cnt_up'))) { + $serviceState = 'cnt_critical_hard'; + } + $this->addElement( + 'select', + 'state', + array( + 'label' => $this->translate('State'), + 'value' => $serviceState, + 'multiOptions' => array( + 'cnt_critical_hard' => $this->translate('Critical'), + 'cnt_warning_hard' => $this->translate('Warning'), + 'cnt_unknown_hard' => $this->translate('Unknown'), + 'cnt_ok' => $this->translate('Ok') + ) + ) + ); + } else { + $hostState = $this->getRequest()->getParam('state', 'cnt_down_hard'); + if (in_array($hostState, array('cnt_ok', 'cnt_critical_hard', 'cnt_warning', 'cnt_unknown'))) { + $hostState = 'cnt_down_hard'; + } + $this->addElement( + 'select', + 'state', + array( + 'label' => $this->translate('State'), + 'value' => $hostState, + 'multiOptions' => array( + 'cnt_up' => $this->translate('Up'), + 'cnt_down_hard' => $this->translate('Down'), + 'cnt_unreachable_hard' => $this->translate('Unreachable') + ) + ) + ); + } + } +} |