Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix broken command transport fallback handling #983

Merged
merged 6 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading