summaryrefslogtreecommitdiffstats
path: root/modules/monitoring/application/forms/Command
diff options
context:
space:
mode:
Diffstat (limited to 'modules/monitoring/application/forms/Command')
-rw-r--r--modules/monitoring/application/forms/Command/CommandForm.php92
-rw-r--r--modules/monitoring/application/forms/Command/Instance/DisableNotificationsExpireCommandForm.php64
-rw-r--r--modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php279
-rw-r--r--modules/monitoring/application/forms/Command/Object/AcknowledgeProblemCommandForm.php172
-rw-r--r--modules/monitoring/application/forms/Command/Object/AddCommentCommandForm.php148
-rw-r--r--modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php87
-rw-r--r--modules/monitoring/application/forms/Command/Object/DeleteCommentCommandForm.php109
-rw-r--r--modules/monitoring/application/forms/Command/Object/DeleteCommentsCommandForm.php89
-rw-r--r--modules/monitoring/application/forms/Command/Object/DeleteDowntimeCommandForm.php129
-rw-r--r--modules/monitoring/application/forms/Command/Object/DeleteDowntimesCommandForm.php89
-rw-r--r--modules/monitoring/application/forms/Command/Object/ObjectsCommandForm.php47
-rw-r--r--modules/monitoring/application/forms/Command/Object/ProcessCheckResultCommandForm.php139
-rw-r--r--modules/monitoring/application/forms/Command/Object/RemoveAcknowledgementCommandForm.php122
-rw-r--r--modules/monitoring/application/forms/Command/Object/ScheduleHostCheckCommandForm.php67
-rw-r--r--modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php178
-rw-r--r--modules/monitoring/application/forms/Command/Object/ScheduleServiceCheckCommandForm.php112
-rw-r--r--modules/monitoring/application/forms/Command/Object/ScheduleServiceDowntimeCommandForm.php263
-rw-r--r--modules/monitoring/application/forms/Command/Object/SendCustomNotificationCommandForm.php110
-rw-r--r--modules/monitoring/application/forms/Command/Object/ToggleObjectFeaturesCommandForm.php187
19 files changed, 2483 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..ab46071
--- /dev/null
+++ b/modules/monitoring/application/forms/Command/Object/ProcessCheckResultCommandForm.php
@@ -0,0 +1,139 @@
+<?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)
+ {
+ 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;
+ }
+}