From 6add437dcefd8d603ffd0029404ff1ade2a5ea34 Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Fri, 4 May 2018 13:11:42 +0200 Subject: [PATCH] IcingaCommand: do not allow to delete while in use fixes #1443 --- doc/82-Changelog.md | 1 + library/Director/Objects/IcingaCommand.php | 36 +++++++++++++++++++ .../Director/Web/Form/DirectorObjectForm.php | 10 ++++++ 3 files changed, 47 insertions(+) diff --git a/doc/82-Changelog.md b/doc/82-Changelog.md index c09e902c..7d436c82 100644 --- a/doc/82-Changelog.md +++ b/doc/82-Changelog.md @@ -24,6 +24,7 @@ before switching to a new version. * FEATURE: A Service Set can now be assigned to multiple hosts at once #1281 * FEATURE: Commands can now be filtered by usage (#1480) * FIX: Don't suggest Command templates where Commands are required (#1414) +* FIX: Do not allow to delete Commands being used by other objects (#1443) ### CLI * FEATURE: Director Health Check Plugin (#1278) diff --git a/library/Director/Objects/IcingaCommand.php b/library/Director/Objects/IcingaCommand.php index f8fe2d3e..215c9741 100644 --- a/library/Director/Objects/IcingaCommand.php +++ b/library/Director/Objects/IcingaCommand.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Objects; use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c; use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1; use Icinga\Module\Director\Objects\Extension\Arguments; +use Zend_Db_Select as DbSelect; class IcingaCommand extends IcingaObject implements ObjectWithArguments { @@ -149,6 +150,41 @@ class IcingaCommand extends IcingaObject implements ObjectWithArguments return true; } + public function countDirectUses() + { + $db = $this->getDb(); + $id = (int) $this->get('id'); + + $qh = $db->select()->from( + array('h' => 'icinga_host'), + array('cnt' => 'COUNT(*)') + )->where('h.check_command_id = ?', $id) + ->orWhere('h.event_command_id = ?', $id); + $qs = $db->select()->from( + array('s' => 'icinga_service'), + array('cnt' => 'COUNT(*)') + )->where('s.check_command_id = ?', $id) + ->orWhere('s.event_command_id = ?', $id); + $qn = $db->select()->from( + array('n' => 'icinga_notification'), + array('cnt' => 'COUNT(*)') + )->where('n.command_id = ?', $id); + $query = $db->select()->union( + [$qh, $qs, $qn], + DbSelect::SQL_UNION_ALL + ); + + return $db->fetchOne($db->select()->from( + ['all_cnts' => $query], + ['cnt' => 'SUM(cnt)'] + )); + } + + public function isInUse() + { + return $this->countDirectUses() > 0; + } + protected function renderCommand() { $command = $this->command; diff --git a/library/Director/Web/Form/DirectorObjectForm.php b/library/Director/Web/Form/DirectorObjectForm.php index 913da859..272eb5a9 100644 --- a/library/Director/Web/Form/DirectorObjectForm.php +++ b/library/Director/Web/Form/DirectorObjectForm.php @@ -11,6 +11,7 @@ use Icinga\Module\Director\Exception\NestingError; use Icinga\Module\Director\IcingaConfig\StateFilterSet; use Icinga\Module\Director\IcingaConfig\TypeFilterSet; use Icinga\Module\Director\Objects\IcingaTemplateChoice; +use Icinga\Module\Director\Objects\IcingaCommand; use Icinga\Module\Director\Objects\IcingaObject; use Icinga\Module\Director\Util; use Icinga\Module\Director\Web\Form\Validate\NamePattern; @@ -885,6 +886,15 @@ abstract class DirectorObjectForm extends DirectorForm ) ); } + } elseif ($object instanceof IcingaCommand && $object->isInUse()) { + $el->setAttrib('disabled', 'disabled'); + $el->setAttrib( + 'title', + sprintf( + $this->translate('This Command is still in use by %d other objects'), + $object->countDirectUses() + ) + ); } $this->addElement($el);