Skip to content

Commit

Permalink
Fix broken command transport fallback handling (#983)
Browse files Browse the repository at this point in the history
fixes #950
  • Loading branch information
nilmerg authored Apr 8, 2024
2 parents 83af168 + e924ab8 commit e2abb5c
Show file tree
Hide file tree
Showing 22 changed files with 230 additions and 327 deletions.
40 changes: 15 additions & 25 deletions application/forms/Command/CommandForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
namespace Icinga\Module\Icingadb\Forms\Command;

use ArrayIterator;
use Countable;
use Exception;
use Generator;
use Icinga\Application\Logger;
use Icinga\Module\Icingadb\Command\IcingaCommand;
use Icinga\Module\Icingadb\Command\Transport\CommandTransport;
Expand All @@ -16,6 +16,8 @@
use ipl\Html\Form;
use ipl\Orm\Model;
use ipl\Web\Common\CsrfCounterMeasure;
use Iterator;
use IteratorIterator;
use Traversable;

abstract class CommandForm extends Form
Expand All @@ -25,7 +27,7 @@ abstract class CommandForm extends Form

protected $defaultAttributes = ['class' => 'icinga-form icinga-controls'];

/** @var mixed */
/** @var (Traversable<Model>&Countable)|array<Model> */
protected $objects;

/** @var bool */
Expand All @@ -43,7 +45,7 @@ abstract class CommandForm extends Form
/**
* Set the objects to issue the command for
*
* @param mixed $objects A traversable that is also countable
* @param (Traversable<Model>&Countable)|array<Model> $objects A traversable that is also countable
*
* @return $this
*/
Expand All @@ -57,7 +59,7 @@ public function setObjects($objects): self
/**
* Get the objects to issue the command for
*
* @return mixed
* @return (Traversable<Model>&Countable)|array<Model>
*/
public function getObjects()
{
Expand Down Expand Up @@ -105,11 +107,11 @@ abstract protected function assembleSubmitButton();
/**
* Get the commands to issue for the given objects
*
* @param Traversable<Model> $objects
* @param Iterator<Model> $objects
*
* @return Traversable<IcingaCommand>
*/
abstract protected function getCommands(Traversable $objects): Traversable;
abstract protected function getCommands(Iterator $objects): Traversable;

protected function assemble()
{
Expand All @@ -123,10 +125,15 @@ protected function assemble()

protected function onSuccess()
{
$errors = [];
$objects = $this->getObjects();
if (is_array($objects)) {
$objects = new ArrayIterator($objects);
} else {
$objects = new IteratorIterator($objects);
}

foreach ($this->getCommands(is_array($objects) ? new ArrayIterator($objects) : $objects) as $command) {
$errors = [];
foreach ($this->getCommands($objects) as $command) {
try {
$this->sendCommand($command);
} catch (Exception $e) {
Expand Down Expand Up @@ -159,21 +166,4 @@ protected function sendCommand(IcingaCommand $command)
{
(new CommandTransport())->send($command);
}

/**
* Yield the $objects the currently logged in user has the permission $permission for
*
* @param string $permission
* @param Traversable $objects
*
* @return Generator
*/
protected function filterGrantedOn(string $permission, Traversable $objects): Generator
{
foreach ($objects as $object) {
if ($this->isGrantedOn($permission, $object)) {
yield $object;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
use Icinga\Web\Notification;
use ipl\Web\FormDecorator\IcingaFormDecorator;
use Iterator;
use Traversable;

class ToggleInstanceFeaturesForm extends CommandForm
Expand Down Expand Up @@ -133,7 +134,7 @@ protected function assembleSubmitButton()
{
}

protected function getCommands(Traversable $objects): Traversable
protected function getCommands(Iterator $objects): Traversable
{
foreach ($this->features as $feature => $spec) {
$featureState = $this->getElement($feature)->isChecked();
Expand Down
10 changes: 8 additions & 2 deletions application/forms/Command/Object/AcknowledgeProblemForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Icinga\Module\Icingadb\Forms\Command\Object;

use CallbackFilterIterator;
use DateInterval;
use DateTime;
use Icinga\Application\Config;
Expand All @@ -14,9 +15,11 @@
use ipl\Html\Attributes;
use ipl\Html\HtmlElement;
use ipl\Html\Text;
use ipl\Orm\Model;
use ipl\Validator\CallbackValidator;
use ipl\Web\FormDecorator\IcingaFormDecorator;
use ipl\Web\Widget\Icon;
use Iterator;
use Traversable;

use function ipl\Stdlib\iterable_value_first;
Expand Down Expand Up @@ -186,10 +189,13 @@ protected function assembleSubmitButton()
(new IcingaFormDecorator())->decorate($this->getElement('btn_submit'));
}

protected function getCommands(Traversable $objects): Traversable
protected function getCommands(Iterator $objects): Traversable
{
$granted = $this->filterGrantedOn('icingadb/command/acknowledge-problem', $objects);
$granted = new CallbackFilterIterator($objects, function (Model $object): bool {
return $this->isGrantedOn('icingadb/command/acknowledge-problem', $object);
});

$granted->rewind(); // Forwards the pointer to the first element
if ($granted->valid()) {
$command = new AcknowledgeProblemCommand();
$command->setObjects($granted);
Expand Down
10 changes: 8 additions & 2 deletions application/forms/Command/Object/AddCommentForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Icinga\Module\Icingadb\Forms\Command\Object;

use CallbackFilterIterator;
use DateInterval;
use DateTime;
use Icinga\Application\Config;
Expand All @@ -14,9 +15,11 @@
use ipl\Html\Attributes;
use ipl\Html\HtmlElement;
use ipl\Html\Text;
use ipl\Orm\Model;
use ipl\Validator\CallbackValidator;
use ipl\Web\FormDecorator\IcingaFormDecorator;
use ipl\Web\Widget\Icon;
use Iterator;
use Traversable;

use function ipl\Stdlib\iterable_value_first;
Expand Down Expand Up @@ -141,10 +144,13 @@ protected function assembleSubmitButton()
(new IcingaFormDecorator())->decorate($this->getElement('btn_submit'));
}

protected function getCommands(Traversable $objects): Traversable
protected function getCommands(Iterator $objects): Traversable
{
$granted = $this->filterGrantedOn('icingadb/command/comment/add', $objects);
$granted = new CallbackFilterIterator($objects, function (Model $object): bool {
return $this->isGrantedOn('icingadb/command/comment/add', $object);
});

$granted->rewind(); // Forwards the pointer to the first element
if ($granted->valid()) {
$command = new AddCommentCommand();
$command->setObjects($granted);
Expand Down
27 changes: 12 additions & 15 deletions application/forms/Command/Object/CheckNowForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

namespace Icinga\Module\Icingadb\Forms\Command\Object;

use Generator;
use CallbackFilterIterator;
use Icinga\Module\Icingadb\Command\Object\ScheduleCheckCommand;
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
use Icinga\Web\Notification;
use ipl\Orm\Model;
use ipl\Web\Widget\Icon;
use Iterator;
use Traversable;

class CheckNowForm extends CommandForm
Expand Down Expand Up @@ -44,22 +46,17 @@ protected function assembleSubmitButton()
);
}

protected function getCommands(Traversable $objects): Traversable
protected function getCommands(Iterator $objects): Traversable
{
$granted = (function () use ($objects): Generator {
foreach ($objects as $object) {
if (
$this->isGrantedOn('icingadb/command/schedule-check', $object)
|| (
$object->active_checks_enabled
&& $this->isGrantedOn('icingadb/command/schedule-check/active-only', $object)
)
) {
yield $object;
}
}
})();
$granted = new CallbackFilterIterator($objects, function (Model $object): bool {
return $this->isGrantedOn('icingadb/command/schedule-check', $object)
|| (
$object->active_checks_enabled
&& $this->isGrantedOn('icingadb/command/schedule-check/active-only', $object)
);
});

$granted->rewind(); // Forwards the pointer to the first element
if ($granted->valid()) {
$command = new ScheduleCheckCommand();
$command->setObjects($granted);
Expand Down
17 changes: 8 additions & 9 deletions application/forms/Command/Object/DeleteCommentForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

namespace Icinga\Module\Icingadb\Forms\Command\Object;

use Generator;
use CallbackFilterIterator;
use Icinga\Module\Icingadb\Command\Object\DeleteCommentCommand;
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
use Icinga\Web\Notification;
use ipl\Orm\Model;
use ipl\Web\Common\RedirectOption;
use ipl\Web\Widget\Icon;
use Iterator;
use Traversable;

class DeleteCommentForm extends CommandForm
Expand Down Expand Up @@ -54,16 +56,13 @@ protected function assembleSubmitButton()
);
}

protected function getCommands(Traversable $objects): Traversable
protected function getCommands(Iterator $objects): Traversable
{
$granted = (function () use ($objects): Generator {
foreach ($objects as $object) {
if ($this->isGrantedOn('icingadb/command/comment/delete', $object->{$object->object_type})) {
yield $object;
}
}
})();
$granted = new CallbackFilterIterator($objects, function (Model $object): bool {
return $this->isGrantedOn('icingadb/command/comment/delete', $object->{$object->object_type});
});

$granted->rewind(); // Forwards the pointer to the first element
if ($granted->valid()) {
$command = new DeleteCommentCommand();
$command->setObjects($granted);
Expand Down
21 changes: 9 additions & 12 deletions application/forms/Command/Object/DeleteDowntimeForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

namespace Icinga\Module\Icingadb\Forms\Command\Object;

use Generator;
use CallbackFilterIterator;
use Icinga\Module\Icingadb\Command\Object\DeleteDowntimeCommand;
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
use Icinga\Web\Notification;
use ipl\Orm\Model;
use ipl\Web\Common\RedirectOption;
use ipl\Web\Widget\Icon;
use Iterator;
use Traversable;

class DeleteDowntimeForm extends CommandForm
Expand Down Expand Up @@ -66,19 +68,14 @@ protected function assembleSubmitButton()
);
}

protected function getCommands(Traversable $objects): Traversable
protected function getCommands(Iterator $objects): Traversable
{
$granted = (function () use ($objects): Generator {
foreach ($objects as $object) {
if (
$this->isGrantedOn('icingadb/command/downtime/delete', $object->{$object->object_type})
&& $object->scheduled_by === null
) {
yield $object;
}
}
})();
$granted = new CallbackFilterIterator($objects, function (Model $object): bool {
return $object->scheduled_by === null
&& $this->isGrantedOn('icingadb/command/downtime/delete', $object->{$object->object_type});
});

$granted->rewind(); // Forwards the pointer to the first element
if ($granted->valid()) {
$command = new DeleteDowntimeCommand();
$command->setObjects($granted);
Expand Down
17 changes: 8 additions & 9 deletions application/forms/Command/Object/ProcessCheckResultForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Icinga\Module\Icingadb\Forms\Command\Object;

use Generator;
use CallbackFilterIterator;
use Icinga\Module\Icingadb\Command\Object\ProcessCheckResultCommand;
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
use Icinga\Module\Icingadb\Model\Host;
Expand All @@ -15,6 +15,7 @@
use ipl\Orm\Model;
use ipl\Web\FormDecorator\IcingaFormDecorator;
use ipl\Web\Widget\Icon;
use Iterator;
use Traversable;

use function ipl\Stdlib\iterable_value_first;
Expand Down Expand Up @@ -133,16 +134,14 @@ protected function assembleSubmitButton()
(new IcingaFormDecorator())->decorate($this->getElement('btn_submit'));
}

protected function getCommands(Traversable $objects): Traversable
protected function getCommands(Iterator $objects): Traversable
{
$granted = (function () use ($objects): Generator {
foreach ($this->filterGrantedOn('icingadb/command/process-check-result', $objects) as $object) {
if ($object->passive_checks_enabled) {
yield $object;
}
}
})();
$granted = new CallbackFilterIterator($objects, function (Model $object): bool {
return $object->passive_checks_enabled
&& $this->isGrantedOn('icingadb/command/process-check-result', $object);
});

$granted->rewind(); // Forwards the pointer to the first element
if ($granted->valid()) {
$command = new ProcessCheckResultCommand();
$command->setObjects($granted);
Expand Down
10 changes: 8 additions & 2 deletions application/forms/Command/Object/RemoveAcknowledgementForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

namespace Icinga\Module\Icingadb\Forms\Command\Object;

use CallbackFilterIterator;
use Icinga\Module\Icingadb\Command\Object\RemoveAcknowledgementCommand;
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
use Icinga\Module\Icingadb\Model\Host;
use Icinga\Web\Notification;
use ipl\Orm\Model;
use ipl\Web\Widget\Icon;
use Iterator;
use Traversable;

use function ipl\Stdlib\iterable_value_first;
Expand Down Expand Up @@ -62,10 +65,13 @@ protected function assembleSubmitButton()
);
}

protected function getCommands(Traversable $objects): Traversable
protected function getCommands(Iterator $objects): Traversable
{
$granted = $this->filterGrantedOn('icingadb/command/remove-acknowledgement', $objects);
$granted = new CallbackFilterIterator($objects, function (Model $object): bool {
return $this->isGrantedOn('icingadb/command/remove-acknowledgement', $object);
});

$granted->rewind(); // Forwards the pointer to the first element
if ($granted->valid()) {
$command = new RemoveAcknowledgementCommand();
$command->setObjects($granted);
Expand Down
Loading

0 comments on commit e2abb5c

Please sign in to comment.