From 464a440f0f6667dcad6c0df7bb4a948dfd7ba2a7 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Tue, 12 Nov 2024 14:12:42 +0100 Subject: [PATCH] Introduce new class `ScheduleDowntimeCommand` Covers the full functionality of the schedule-downtime endpoint of Icinga 2's api now. fixes #1090 --- .../Object/ScheduleHostDowntimeForm.php | 57 +--- .../Object/ScheduleServiceDowntimeForm.php | 26 +- .../Object/ScheduleDowntimeCommand.php | 264 ++++++++++++++++++ .../Renderer/IcingaApiCommandRenderer.php | 15 +- 4 files changed, 302 insertions(+), 60 deletions(-) create mode 100644 library/Icingadb/Command/Object/ScheduleDowntimeCommand.php diff --git a/application/forms/Command/Object/ScheduleHostDowntimeForm.php b/application/forms/Command/Object/ScheduleHostDowntimeForm.php index a09b00d8..84979da5 100644 --- a/application/forms/Command/Object/ScheduleHostDowntimeForm.php +++ b/application/forms/Command/Object/ScheduleHostDowntimeForm.php @@ -4,14 +4,10 @@ namespace Icinga\Module\Icingadb\Forms\Command\Object; -use CallbackFilterIterator; use DateInterval; use DateTime; use Icinga\Application\Config; -use Icinga\Module\Icingadb\Command\Object\PropagateHostDowntimeCommand; -use Icinga\Module\Icingadb\Command\Object\ScheduleHostDowntimeCommand; use Icinga\Web\Notification; -use ipl\Orm\Model; use ipl\Web\FormDecorator\IcingaFormDecorator; use Iterator; use Traversable; @@ -60,7 +56,7 @@ class ScheduleHostDowntimeForm extends ScheduleServiceDowntimeForm $decorator = new IcingaFormDecorator(); - $this->addElement( + $allServices = $this->createElement( 'checkbox', 'all_services', [ @@ -72,54 +68,19 @@ class ScheduleHostDowntimeForm extends ScheduleServiceDowntimeForm 'value' => $this->hostDowntimeAllServices ] ); - $decorator->decorate($this->getElement('all_services')); - - $this->addElement( - 'select', - 'child_options', - array( - 'description' => t('Schedule child downtimes.'), - 'label' => t('Child Options'), - 'options' => [ - 0 => t('Do nothing with child hosts'), - 1 => t('Schedule triggered downtime for all child hosts'), - 2 => t('Schedule non-triggered downtime for all child hosts') - ] - ) - ); - $decorator->decorate($this->getElement('child_options')); + $this->insertBefore($allServices, $this->getElement('child_options')); + $this->registerElement($allServices); + $decorator->decorate($allServices); } protected function getCommands(Iterator $objects): Traversable { - $granted = new CallbackFilterIterator($objects, function (Model $object): bool { - return $this->isGrantedOn('icingadb/command/downtime/schedule', $object); - }); + if (! $this->getElement('all_services')->isChecked()) { + yield from parent::getCommands($objects); + } - $granted->rewind(); // Forwards the pointer to the first element - if ($granted->valid()) { - if (($childOptions = (int) $this->getValue('child_options'))) { - $command = new PropagateHostDowntimeCommand(); - $command->setTriggered($childOptions === 1); - } else { - $command = new ScheduleHostDowntimeCommand(); - } - - $command->setObjects($granted); - $command->setComment($this->getValue('comment')); - $command->setAuthor($this->getAuth()->getUser()->getUsername()); - $command->setStart($this->getValue('start')->getTimestamp()); - $command->setEnd($this->getValue('end')->getTimestamp()); - $command->setForAllServices($this->getElement('all_services')->isChecked()); - - if ($this->getElement('flexible')->isChecked()) { - $command->setFixed(false); - $command->setDuration( - $this->getValue('hours') * 3600 + $this->getValue('minutes') * 60 - ); - } - - yield $command; + foreach (parent::getCommands($objects) as $command) { + yield $command->setForAllServices(); } } } diff --git a/application/forms/Command/Object/ScheduleServiceDowntimeForm.php b/application/forms/Command/Object/ScheduleServiceDowntimeForm.php index b237408a..7b8935be 100644 --- a/application/forms/Command/Object/ScheduleServiceDowntimeForm.php +++ b/application/forms/Command/Object/ScheduleServiceDowntimeForm.php @@ -8,7 +8,7 @@ use CallbackFilterIterator; use DateInterval; use DateTime; use Icinga\Application\Config; -use Icinga\Module\Icingadb\Command\Object\ScheduleServiceDowntimeCommand; +use Icinga\Module\Icingadb\Command\Object\ScheduleDowntimeCommand; use Icinga\Module\Icingadb\Forms\Command\CommandForm; use Icinga\Web\Notification; use ipl\Html\Attributes; @@ -229,6 +229,27 @@ class ScheduleServiceDowntimeForm extends CommandForm $this->add($hoursInput); } + + $this->addElement( + 'select', + 'child_options', + array( + 'description' => t('Schedule child downtimes.'), + 'label' => t('Child Options'), + 'options' => [ + ScheduleDowntimeCommand::IGNORE_CHILDREN => t( + 'Do nothing with children' + ), + ScheduleDowntimeCommand::TRIGGER_CHILDREN => t( + 'Schedule a downtime for all children and trigger them by this downtime' + ), + ScheduleDowntimeCommand::SCHEDULE_CHILDREN => t( + 'Schedule non-triggered downtime for all children' + ) + ] + ) + ); + $decorator->decorate($this->getElement('child_options')); } protected function assembleSubmitButton() @@ -253,12 +274,13 @@ class ScheduleServiceDowntimeForm extends CommandForm $granted->rewind(); // Forwards the pointer to the first element if ($granted->valid()) { - $command = new ScheduleServiceDowntimeCommand(); + $command = new ScheduleDowntimeCommand(); $command->setObjects($granted); $command->setComment($this->getValue('comment')); $command->setAuthor($this->getAuth()->getUser()->getUsername()); $command->setStart($this->getValue('start')->getTimestamp()); $command->setEnd($this->getValue('end')->getTimestamp()); + $command->setChildOption((int) $this->getValue('child_options')); if ($this->getElement('flexible')->isChecked()) { $command->setFixed(false); diff --git a/library/Icingadb/Command/Object/ScheduleDowntimeCommand.php b/library/Icingadb/Command/Object/ScheduleDowntimeCommand.php new file mode 100644 index 00000000..bb2cda77 --- /dev/null +++ b/library/Icingadb/Command/Object/ScheduleDowntimeCommand.php @@ -0,0 +1,264 @@ +start = $start; + + return $this; + } + + /** + * Get the time when the downtime should start + * + * @return int Unix timestamp + */ + public function getStart(): int + { + if ($this->start === null) { + throw new \LogicException( + 'You are accessing an unset property. Please make sure to set it beforehand.' + ); + } + + return $this->start; + } + + /** + * Set the time when the downtime should end + * + * @param int $end Unix timestamp + * + * @return $this + */ + public function setEnd(int $end): self + { + $this->end = $end; + + return $this; + } + + /** + * Get the time when the downtime should end + * + * @return int Unix timestamp + */ + public function getEnd(): int + { + if ($this->start === null) { + throw new \LogicException( + 'You are accessing an unset property. Please make sure to set it beforehand.' + ); + } + + return $this->end; + } + + /** + * Set whether it's a fixed or flexible downtime + * + * @param boolean $fixed + * + * @return $this + */ + public function setFixed(bool $fixed = true): self + { + $this->fixed = $fixed; + + return $this; + } + + /** + * Is the downtime fixed? + * + * @return boolean + */ + public function getFixed(): bool + { + return $this->fixed; + } + + /** + * Set the ID of the downtime which triggers this downtime + * + * @param int $triggerId + * + * @return $this + */ + public function setTriggerId(int $triggerId): self + { + $this->triggerId = $triggerId; + + return $this; + } + + /** + * Get the ID of the downtime which triggers this downtime + * + * @return int|null + */ + public function getTriggerId() + { + return $this->triggerId; + } + + /** + * Set the duration in seconds the downtime must last if it's a flexible downtime + * + * @param int $duration + * + * @return $this + */ + public function setDuration(int $duration): self + { + $this->duration = $duration; + + return $this; + } + + /** + * Get the duration in seconds the downtime must last if it's a flexible downtime + * + * @return int|null + */ + public function getDuration() + { + return $this->duration; + } + + /** + * Set whether to schedule a downtime for all services associated with a particular host + * + * @param bool $forAllServices + * + * @return $this + */ + public function setForAllServices(bool $forAllServices = true): self + { + $this->forAllServices = $forAllServices; + + return $this; + } + + /** + * Get whether to schedule a downtime for all services associated with a particular host + * + * @return bool + */ + public function getForAllServices(): bool + { + return $this->forAllServices; + } + + /** + * Set what to do with children + * + * @param CHILD_OPTION $option + * + * @return $this + */ + public function setChildOption(int $option): self + { + $this->childOption = $option; + + return $this; + } + + /** + * Get what to do with children + * + * @return CHILD_OPTION + */ + public function getChildOption(): int + { + return $this->childOption; + } +} diff --git a/library/Icingadb/Command/Renderer/IcingaApiCommandRenderer.php b/library/Icingadb/Command/Renderer/IcingaApiCommandRenderer.php index 37075c99..c7d221ba 100644 --- a/library/Icingadb/Command/Renderer/IcingaApiCommandRenderer.php +++ b/library/Icingadb/Command/Renderer/IcingaApiCommandRenderer.php @@ -6,6 +6,7 @@ namespace Icinga\Module\Icingadb\Command\Renderer; use Icinga\Module\Icingadb\Command\IcingaApiCommand; use Icinga\Module\Icingadb\Command\Object\GetObjectCommand; +use Icinga\Module\Icingadb\Command\Object\ScheduleDowntimeCommand; use Icinga\Module\Icingadb\Model\Host; use Icinga\Module\Icingadb\Model\Service; use Icinga\Module\Icingadb\Command\Instance\ToggleInstanceFeatureCommand; @@ -14,11 +15,8 @@ use Icinga\Module\Icingadb\Command\Object\AddCommentCommand; use Icinga\Module\Icingadb\Command\Object\DeleteCommentCommand; use Icinga\Module\Icingadb\Command\Object\DeleteDowntimeCommand; use Icinga\Module\Icingadb\Command\Object\ProcessCheckResultCommand; -use Icinga\Module\Icingadb\Command\Object\PropagateHostDowntimeCommand; use Icinga\Module\Icingadb\Command\Object\RemoveAcknowledgementCommand; -use Icinga\Module\Icingadb\Command\Object\ScheduleHostDowntimeCommand; use Icinga\Module\Icingadb\Command\Object\ScheduleCheckCommand; -use Icinga\Module\Icingadb\Command\Object\ScheduleServiceDowntimeCommand; use Icinga\Module\Icingadb\Command\Object\SendCustomNotificationCommand; use Icinga\Module\Icingadb\Command\Object\ToggleObjectFeatureCommand; use Icinga\Module\Icingadb\Command\IcingaCommand; @@ -191,7 +189,7 @@ class IcingaApiCommandRenderer implements IcingaCommandRendererInterface return IcingaApiCommand::create($endpoint, $data); } - public function renderScheduleDowntime(ScheduleServiceDowntimeCommand $command): IcingaApiCommand + public function renderScheduleDowntime(ScheduleDowntimeCommand $command): IcingaApiCommand { $endpoint = 'actions/schedule-downtime'; $data = [ @@ -201,14 +199,11 @@ class IcingaApiCommandRenderer implements IcingaCommandRendererInterface 'end_time' => $command->getEnd(), 'duration' => $command->getDuration(), 'fixed' => $command->getFixed(), - 'trigger_name' => $command->getTriggerId() + 'trigger_name' => $command->getTriggerId(), + 'child_options' => $command->getChildOption() ]; - if ($command instanceof PropagateHostDowntimeCommand) { - $data['child_options'] = $command->getTriggered() ? 1 : 2; - } - - if ($command instanceof ScheduleHostDowntimeCommand && $command->getForAllServices()) { + if ($command->getForAllServices()) { $data['all_services'] = true; }