Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package icingaweb2-module-director for openSUSE:Factory checked in at 2025-03-26 21:24:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/icingaweb2-module-director (Old) and /work/SRC/openSUSE:Factory/.icingaweb2-module-director.new.2696 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "icingaweb2-module-director" Wed Mar 26 21:24:15 2025 rev:25 rq:1256250 version:1.11.4 Changes: -------- --- /work/SRC/openSUSE:Factory/icingaweb2-module-director/icingaweb2-module-director.changes 2024-12-13 22:41:35.382199489 +0100 +++ /work/SRC/openSUSE:Factory/.icingaweb2-module-director.new.2696/icingaweb2-module-director.changes 2025-03-26 21:25:48.748449850 +0100 @@ -1,0 +2,19 @@ +Wed Mar 26 14:06:46 UTC 2025 - ecsos <ec...@opensuse.org> + +- Update to 1.11.4 + * Security + - Rest API endpoints accessible to restricted users (GHSA-3233-ggc5-m3qg) + * UI + - Fix editing of custom variables for multi-selected objects #2950 + - Fix: Check for the existence of service templates to add services #1249 + * Import and Sync + - Fix erratic job behavior during summer and winter time change (no issue) + * Integration + - Fix custom variable renderer for service apply for rules (no issue) + - Fix custom variable renderer for array type data lists #2960 + * Database Schema + - Fix MySQL 8.4 nonstandard foreign keys deprecation #2885 + * Fixed Issues + - You can find issues related to this release on our roadmap + +------------------------------------------------------------------- Old: ---- icingaweb2-module-director-1.11.3.tar.gz New: ---- icingaweb2-module-director-1.11.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ icingaweb2-module-director.spec ++++++ --- /var/tmp/diff_new_pack.2hco84/_old 2025-03-26 21:25:49.288472051 +0100 +++ /var/tmp/diff_new_pack.2hco84/_new 2025-03-26 21:25:49.288472051 +0100 @@ -1,7 +1,7 @@ # # spec file for package icingaweb2-module-director # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -22,7 +22,7 @@ %define icingadirector_user icingadirector Name: icingaweb2-module-director -Version: 1.11.3 +Version: 1.11.4 Release: 0 Summary: Config module for Icinga Web 2 License: GPL-2.0-or-later ++++++ icingaweb2-module-director-1.11.3.tar.gz -> icingaweb2-module-director-1.11.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/application/controllers/NotificationController.php new/icingaweb2-module-director-1.11.4/application/controllers/NotificationController.php --- old/icingaweb2-module-director-1.11.3/application/controllers/NotificationController.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/application/controllers/NotificationController.php 2025-03-26 11:24:49.000000000 +0100 @@ -2,6 +2,7 @@ namespace Icinga\Module\Director\Controllers; +use Icinga\Exception\NotFoundError; use Icinga\Module\Director\Web\Controller\ObjectController; use Icinga\Module\Director\Objects\IcingaHost; use Icinga\Module\Director\Objects\IcingaNotification; @@ -80,6 +81,10 @@ } } + if (! $this->allowsObject($this->object)) { + throw new NotFoundError('No such object available'); + } + return $this->object; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/application/controllers/ServiceController.php new/icingaweb2-module-director-1.11.4/application/controllers/ServiceController.php --- old/icingaweb2-module-director-1.11.3/application/controllers/ServiceController.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/application/controllers/ServiceController.php 2025-03-26 11:24:49.000000000 +0100 @@ -49,14 +49,6 @@ $this->host = $this->getOptionalRelatedObjectFromParams('host', 'host'); $this->set = $this->getOptionalRelatedObjectFromParams('service_set', 'set'); parent::init(); - if ($this->object) { - if ($this->host === null) { - $this->host = $this->loadOptionalRelatedObject($this->object, 'host'); - } - if ($this->set === null) { - $this->set = $this->loadOptionalRelatedObject($this->object, 'service_set'); - } - } $this->addOptionalHostTabs(); $this->addOptionalSetTabs(); } @@ -77,6 +69,20 @@ return null; } + protected function loadOptionalObject(): void + { + parent::loadOptionalObject(); + + if ($this->object) { + if ($this->host === null) { + $this->host = $this->loadOptionalRelatedObject($this->object, 'host'); + } + if ($this->set === null) { + $this->set = $this->loadOptionalRelatedObject($this->object, 'service_set'); + } + } + } + protected function loadOptionalRelatedObject(IcingaObject $object, $relation) { $key = $object->getUnresolvedRelated($relation); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/application/controllers/ServicesetController.php new/icingaweb2-module-director-1.11.4/application/controllers/ServicesetController.php --- old/icingaweb2-module-director-1.11.3/application/controllers/ServicesetController.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/application/controllers/ServicesetController.php 2025-03-26 11:24:49.000000000 +0100 @@ -3,6 +3,7 @@ namespace Icinga\Module\Director\Controllers; use Icinga\Data\Filter\Filter; +use Icinga\Exception\NotFoundError; use Icinga\Module\Director\Forms\IcingaServiceSetForm; use Icinga\Module\Director\Objects\IcingaHost; use Icinga\Module\Director\Objects\IcingaServiceSet; @@ -136,6 +137,10 @@ } } + if (! $this->allowsObject($this->object)) { + throw new NotFoundError('No such object available'); + } + return $this->object; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/application/forms/IcingaAddServiceForm.php new/icingaweb2-module-director-1.11.4/application/forms/IcingaAddServiceForm.php --- old/icingaweb2-module-director-1.11.3/application/forms/IcingaAddServiceForm.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/application/forms/IcingaAddServiceForm.php 2025-03-26 11:24:49.000000000 +0100 @@ -30,7 +30,13 @@ ); } - $this->addSingleImportElement(); + $this->addSingleImportElement(true); + + if (empty($this->enumServiceTemplates())) { + $this->setSubmitLabel(false); + + return; + } if (! ($imports = $this->getSentOrObjectValue('imports'))) { $this->setSubmitLabel($this->translate('Next')); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/application/forms/IcingaMultiEditForm.php new/icingaweb2-module-director-1.11.4/application/forms/IcingaMultiEditForm.php --- old/icingaweb2-module-director-1.11.3/application/forms/IcingaMultiEditForm.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/application/forms/IcingaMultiEditForm.php 2025-03-26 11:24:49.000000000 +0100 @@ -51,6 +51,7 @@ $loader = new IcingaObjectFieldLoader($object); $loader->prepareElements($this); $loader->addFieldsToForm($this); + $this->varNameMap = $loader->getNameMap(); if ($form = $this->relatedForm) { if ($form instanceof DirectorObjectForm) { @@ -237,10 +238,6 @@ $this->removeElement($key); $label = $element->getLabel(); - if ($this->isCustomVar($key)) { - $this->varNameMap[$key] = $label; - } - $group = $this->getDisplayGroupForElement($element); $description = $element->getDescription(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/doc/02-Installation.md.d/From-Source.md new/icingaweb2-module-director-1.11.4/doc/02-Installation.md.d/From-Source.md --- old/icingaweb2-module-director-1.11.3/doc/02-Installation.md.d/From-Source.md 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/doc/02-Installation.md.d/From-Source.md 2025-03-26 11:24:49.000000000 +0100 @@ -41,7 +41,7 @@ You might want to use a script as follows for this task: ```shell -MODULE_VERSION="1.11.3" +MODULE_VERSION="1.11.4" ICINGAWEB_MODULEPATH="/usr/share/icingaweb2/modules" REPO_URL="https://github.com/icinga/icingaweb2-module-director" TARGET_DIR="${ICINGAWEB_MODULEPATH}/director" @@ -60,7 +60,7 @@ You might want to use a script as follows for this task: ```shell -MODULE_VERSION="1.11.3" +MODULE_VERSION="1.11.4" ICINGAWEB_MODULEPATH="/usr/share/icingaweb2/modules" REPO_URL="https://github.com/icinga/icingaweb2-module-director" TARGET_DIR="${ICINGAWEB_MODULEPATH}/director" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/doc/82-Changelog.md new/icingaweb2-module-director-1.11.4/doc/82-Changelog.md --- old/icingaweb2-module-director-1.11.3/doc/82-Changelog.md 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/doc/82-Changelog.md 2025-03-26 11:24:49.000000000 +0100 @@ -4,6 +4,35 @@ Please make sure to always read our [Upgrading](05-Upgrading.md) documentation before switching to a new version. +v1.11.4 +------- + +### Security + +- Rest API endpoints accessible to restricted users ([GHSA-3233-ggc5-m3qg](https://github.com/Icinga/icingaweb2-module-director/security/advisories/GHSA-3233-ggc5-m3qg)) + +### UI + +- Fix editing of custom variables for multi-selected objects [#2950](https://github.com/Icinga/icingaweb2-module-director/issues/2950) +- Fix: Check for the existence of service templates to add services [#1249](https://github.com/Icinga/icingaweb2-module-director/issues/1249) + +### Import and Sync + +- Fix erratic job behavior during summer and winter time change (no issue) + +### Integration + +- Fix custom variable renderer for service apply for rules (no issue) +- Fix custom variable renderer for array type data lists [#2960](https://github.com/Icinga/icingaweb2-module-director/issues/2960) + +### Database Schema + +- Fix MySQL 8.4 nonstandard foreign keys deprecation [#2885](https://github.com/Icinga/icingaweb2-module-director/issues/2885) + +### Fixed Issues + +You can find issues related to this release on our [roadmap](https://github.com/Icinga/icingaweb2-module-director/milestone/39?closed=1) + v1.11.3 ------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/Objects/DirectorJob.php new/icingaweb2-module-director-1.11.4/library/Director/Objects/DirectorJob.php --- old/icingaweb2-module-director-1.11.3/library/Director/Objects/DirectorJob.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/Objects/DirectorJob.php 2025-03-26 11:24:49.000000000 +0100 @@ -3,6 +3,7 @@ namespace Icinga\Module\Director\Objects; use Icinga\Exception\NotFoundError; +use Icinga\Module\Director\Daemon\DaemonUtil; use Icinga\Module\Director\Daemon\Logger; use Icinga\Module\Director\Data\Db\DbObjectWithSettings; use Icinga\Module\Director\Db; @@ -84,7 +85,8 @@ public function run() { $job = $this->getInstance(); - $this->set('ts_last_attempt', date('Y-m-d H:i:s')); + $currentTimestamp = DaemonUtil::timestampWithMilliseconds(); + $this->set('ts_last_attempt', $currentTimestamp); try { $job->run(); @@ -92,7 +94,7 @@ $success = true; } catch (Exception $e) { Logger::error($e->getMessage()); - $this->set('ts_last_error', date('Y-m-d H:i:s')); + $this->set('ts_last_error', $currentTimestamp); $this->set('last_error_message', $e->getMessage()); $this->set('last_attempt_succeeded', 'n'); $success = false; @@ -127,8 +129,8 @@ } return ( - strtotime($this->get('ts_last_attempt')) + $this->get('run_interval') * 2 - ) < time(); + $this->get('ts_last_attempt') + $this->get('run_interval') * 2 * 1000 + ) < DaemonUtil::timestampWithMilliseconds(); } public function hasBeenDisabled() @@ -145,7 +147,9 @@ return $this->isWithinTimeperiod(); } - if (strtotime($this->get('ts_last_attempt')) + $this->get('run_interval') < time()) { + if ( + $this->get('ts_last_attempt') + $this->get('run_interval') * 1000 < DaemonUtil::timestampWithMilliseconds() + ) { return $this->isWithinTimeperiod(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/ProvidedHook/Icingadb/CustomVarRenderer.php new/icingaweb2-module-director-1.11.4/library/Director/ProvidedHook/Icingadb/CustomVarRenderer.php --- old/icingaweb2-module-director-1.11.3/library/Director/ProvidedHook/Icingadb/CustomVarRenderer.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/ProvidedHook/Icingadb/CustomVarRenderer.php 2025-03-26 11:24:49.000000000 +0100 @@ -5,6 +5,7 @@ use Icinga\Application\Config; use Icinga\Exception\ConfigurationError; use Icinga\Exception\NotFoundError; +use Icinga\Module\Director\CustomVariable\CustomVariableArray; use Icinga\Module\Director\Daemon\Logger; use Icinga\Module\Director\Db; use Icinga\Module\Director\Db\AppliedServiceSetLoader; @@ -113,22 +114,42 @@ $appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery(); foreach ($appliedFilterQuery->fetchAll() as $appliedService) { - if ($appliedService->name === $serviceName) { - $query = $db->getDbAdapter()->select()->from('icinga_service') - ->where('object_name = ?', $serviceName) - ->where("object_type = 'apply'") - ->where('assign_filter = ?', $appliedService->assign_filter); - - $directorAppliedServices = IcingaService::loadAll( - $db, - $query, - 'object_name' - ); - - $directorServiceObj = current($directorAppliedServices); + if ($appliedService->apply_for === null) { + $isAppliedService = $appliedService->name === $serviceName; + } else { + /** @var ?CustomVariableArray $hostVar */ + $hostVar = $directorHostObj->vars()->get((substr($appliedService->apply_for, 10))); + if ($hostVar) { + $appliedServiceName = $appliedService->name; + $appliedForServiceLookup = []; + foreach ($hostVar->getValue() as $val) { + $appliedForServiceLookup[$appliedServiceName . $val] = true; + } + + $isAppliedService = isset($appliedForServiceLookup[$serviceName]); + } else { + $isAppliedService = false; + } + } - break; + if (! $isAppliedService) { + continue; } + + $query = $db->getDbAdapter()->select()->from('icinga_service') + ->where('object_name = ?', $appliedService->name) + ->where("object_type = 'apply'") + ->where('assign_filter = ?', $appliedService->assign_filter); + + $directorAppliedServices = IcingaService::loadAll( + $db, + $query, + 'object_name' + ); + + $directorServiceObj = current($directorAppliedServices); + + break; } } elseif ($serviceOrigin[$i] === 'service-set') { $templateResolver = new IcingaTemplateResolver($directorHostObj); @@ -253,7 +274,24 @@ return '***'; } - if (isset($this->datalistMaps[$key][$value])) { + if (is_array($value)) { + $renderedValue = []; + foreach ($value as $v) { + if (is_string($v) && isset($this->datalistMaps[$key][$v])) { + $renderedValue[] = new HtmlElement( + 'span', + Attributes::create(['title' => $this->datalistMaps[$key][$v] . " [$v]"]), + Text::create($this->datalistMaps[$key][$v]) + ); + } else { + $renderedValue[] = $v; + } + } + + return $renderedValue; + } + + if (is_string($value) && isset($this->datalistMaps[$key][$value])) { return new HtmlElement( 'span', Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/ProvidedHook/Monitoring/CustomVarRenderer.php new/icingaweb2-module-director-1.11.4/library/Director/ProvidedHook/Monitoring/CustomVarRenderer.php --- old/icingaweb2-module-director-1.11.3/library/Director/ProvidedHook/Monitoring/CustomVarRenderer.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/ProvidedHook/Monitoring/CustomVarRenderer.php 2025-03-26 11:24:49.000000000 +0100 @@ -5,6 +5,7 @@ use Icinga\Application\Config; use Icinga\Exception\ConfigurationError; use Icinga\Exception\NotFoundError; +use Icinga\Module\Director\CustomVariable\CustomVariableArray; use Icinga\Module\Director\Daemon\Logger; use Icinga\Module\Director\Db; use Icinga\Module\Director\Db\AppliedServiceSetLoader; @@ -114,22 +115,42 @@ $appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery(); foreach ($appliedFilterQuery->fetchAll() as $appliedService) { - if ($appliedService->name === $serviceName) { - $query = $db->getDbAdapter()->select()->from('icinga_service') - ->where('object_name = ?', $serviceName) - ->where("object_type = 'apply'") - ->where('assign_filter = ?', $appliedService->assign_filter); - - $directorAppliedServices = IcingaService::loadAll( - $db, - $query, - 'object_name' - ); - - $directorServiceObj = current($directorAppliedServices); + if ($appliedService->apply_for === null) { + $isAppliedService = $appliedService->name === $serviceName; + } else { + /** @var ?CustomVariableArray $hostVar */ + $hostVar = $directorHostObj->vars()->get((substr($appliedService->apply_for, 10))); + if ($hostVar) { + $appliedServiceName = $appliedService->name; + $appliedForServiceLookup = []; + foreach ($hostVar->getValue() as $val) { + $appliedForServiceLookup[$appliedServiceName . $val] = true; + } + + $isAppliedService = isset($appliedForServiceLookup[$serviceName]); + } else { + $isAppliedService = false; + } + } - break; + if (! $isAppliedService) { + continue; } + + $query = $db->getDbAdapter()->select()->from('icinga_service') + ->where('object_name = ?', $appliedService->name) + ->where("object_type = 'apply'") + ->where('assign_filter = ?', $appliedService->assign_filter); + + $directorAppliedServices = IcingaService::loadAll( + $db, + $query, + 'object_name' + ); + + $directorServiceObj = current($directorAppliedServices); + + break; } } elseif ($serviceOrigin[$i] === 'service-set') { $templateResolver = new IcingaTemplateResolver($directorHostObj); @@ -254,7 +275,24 @@ return '***'; } - if (isset($this->datalistMaps[$key][$value])) { + if (is_array($value)) { + $renderedValue = []; + foreach ($value as $v) { + if (is_string($v) && isset($this->datalistMaps[$key][$v])) { + $renderedValue[] = new HtmlElement( + 'span', + Attributes::create(['title' => $this->datalistMaps[$key][$v] . " [$v]"]), + Text::create($this->datalistMaps[$key][$v]) + ); + } else { + $renderedValue[] = $v; + } + } + + return $renderedValue; + } + + if (is_string($value) && isset($this->datalistMaps[$key][$value])) { return new HtmlElement( 'span', Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/Restriction/FilterByNameRestriction.php new/icingaweb2-module-director-1.11.4/library/Director/Restriction/FilterByNameRestriction.php --- old/icingaweb2-module-director-1.11.3/library/Director/Restriction/FilterByNameRestriction.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/Restriction/FilterByNameRestriction.php 2025-03-26 11:24:49.000000000 +0100 @@ -5,6 +5,7 @@ use gipfl\IcingaWeb2\Zf1\Db\FilterRenderer; use Icinga\Authentication\Auth; use Icinga\Data\Filter\Filter; +use Icinga\Data\Filter\FilterEqual; use Icinga\Module\Director\Db; use Icinga\Module\Director\Objects\IcingaObject; use Zend_Db_Select as ZfSelect; @@ -30,7 +31,11 @@ protected function setNameForType($type) { - $this->name = "director/{$type}/filter-by-name"; + if ($type === 'service_set') { + $this->name = "director/{$type}/filter-by-name"; + } else { + $this->name = "director/{$type}/apply/filter-by-name"; + } } public function allows(IcingaObject $object) @@ -39,9 +44,9 @@ return true; } - return $this->getFilter()->matches([ + return $this->getFilter()->matches( (object) ['object_name' => $object->getObjectName()] - ]); + ); } public function getFilter() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/Web/Controller/Extension/ObjectRestrictions.php new/icingaweb2-module-director-1.11.4/library/Director/Web/Controller/Extension/ObjectRestrictions.php --- old/icingaweb2-module-director-1.11.3/library/Director/Web/Controller/Extension/ObjectRestrictions.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/Web/Controller/Extension/ObjectRestrictions.php 2025-03-26 11:24:49.000000000 +0100 @@ -5,6 +5,7 @@ use Icinga\Authentication\Auth; use Icinga\Module\Director\Db; use Icinga\Module\Director\Objects\IcingaObject; +use Icinga\Module\Director\Restriction\FilterByNameRestriction; use Icinga\Module\Director\Restriction\HostgroupRestriction; use Icinga\Module\Director\Restriction\ObjectRestriction; @@ -13,6 +14,9 @@ /** @var ObjectRestriction[] */ private $objectRestrictions; + /** @var IcingaObject */ + private $dummyRestrictedObject; + /** * @return ObjectRestriction[] */ @@ -30,13 +34,27 @@ */ protected function loadObjectRestrictions(Db $db, Auth $auth) { - return [ - new HostgroupRestriction($db, $auth) - ]; + $objectType = $this->dummyRestrictedObject->getShortTableName(); + if ( + ($objectType === 'service' && $this->dummyRestrictedObject->isApplyRule()) + || $objectType === 'notification' + || $objectType === 'service_set' + || $objectType === 'scheduled_downtime' + ) { + if ($objectType === 'scheduled_downtime') { + $objectType = 'scheduled-downtime'; + } + + return [new FilterByNameRestriction($db, $auth, $objectType)]; + } + + // If the object is host or host group load HostgroupRestriction + return [new HostgroupRestriction($db, $auth)]; } public function allowsObject(IcingaObject $object) { + $this->dummyRestrictedObject = $object; foreach ($this->getObjectRestrictions() as $restriction) { if (! $restriction->allows($object)) { return false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/Web/Controller/ObjectsController.php new/icingaweb2-module-director-1.11.4/library/Director/Web/Controller/ObjectsController.php --- old/icingaweb2-module-director-1.11.3/library/Director/Web/Controller/ObjectsController.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/Web/Controller/ObjectsController.php 2025-03-26 11:24:49.000000000 +0100 @@ -17,6 +17,7 @@ use Icinga\Module\Director\RestApi\IcingaObjectsHandler; use Icinga\Module\Director\Web\ActionBar\ObjectsActionBar; use Icinga\Module\Director\Web\ActionBar\TemplateActionBar; +use Icinga\Module\Director\Web\Controller\Extension\ObjectRestrictions; use Icinga\Module\Director\Web\Form\FormLoader; use Icinga\Module\Director\Web\Table\ApplyRulesTable; use Icinga\Module\Director\Web\Table\ObjectSetTable; @@ -33,6 +34,7 @@ abstract class ObjectsController extends ActionController { use BranchHelper; + use ObjectRestrictions; protected $isApified = true; @@ -75,9 +77,13 @@ $table = $this->getTable(); if ( $request->getControllerName() === 'services' - && $host = $this->params->get('host') + && $hostName = $this->params->get('host') ) { - $host = IcingaHost::load($host, $this->db()); + $host = IcingaHost::load($hostName, $this->db()); + if (! $this->allowsObject($host)) { + throw new NotFoundError(sprintf('Failed to load %s "%s"', $host->getTableName(), $hostName)); + } + $table->getQuery()->where('o.host_id = ?', $host->get('id')); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/Web/Form/IcingaObjectFieldLoader.php new/icingaweb2-module-director-1.11.4/library/Director/Web/Form/IcingaObjectFieldLoader.php --- old/icingaweb2-module-director-1.11.3/library/Director/Web/Form/IcingaObjectFieldLoader.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/Web/Form/IcingaObjectFieldLoader.php 2025-03-26 11:24:49.000000000 +0100 @@ -60,6 +60,16 @@ return $this; } + /** + * Get element names to variable names map (Example: ['elName' => 'varName']) + * + * @return array + */ + public function getNameMap(): array + { + return $this->nameMap; + } + public function loadFieldsForMultipleObjects($objects) { $fields = array(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/Web/Table/JobTable.php new/icingaweb2-module-director-1.11.4/library/Director/Web/Table/JobTable.php --- old/icingaweb2-module-director-1.11.3/library/Director/Web/Table/JobTable.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/Web/Table/JobTable.php 2025-03-26 11:24:49.000000000 +0100 @@ -4,6 +4,7 @@ use gipfl\IcingaWeb2\Link; use gipfl\IcingaWeb2\Table\ZfQueryBasedTable; +use Icinga\Module\Director\Daemon\DaemonUtil; class JobTable extends ZfQueryBasedTable { @@ -37,11 +38,11 @@ protected function getJobClasses($row) { - if ($row->unixts_last_attempt === null) { + if ($row->ts_last_attempt === null) { return 'pending'; } - if ($row->unixts_last_attempt + $row->run_interval < time()) { + if ($row->ts_last_attempt + $row->run_interval * 1000 < DaemonUtil::timestampWithMilliseconds()) { return 'pending'; } @@ -73,7 +74,6 @@ 'run_interval' => 'j.run_interval', 'last_attempt_succeeded' => 'j.last_attempt_succeeded', 'ts_last_attempt' => 'j.ts_last_attempt', - 'unixts_last_attempt' => 'UNIX_TIMESTAMP(j.ts_last_attempt)', 'ts_last_error' => 'j.ts_last_error', 'last_error_message' => 'j.last_error_message', ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/Web/Table/ObjectsTable.php new/icingaweb2-module-director-1.11.4/library/Director/Web/Table/ObjectsTable.php --- old/icingaweb2-module-director-1.11.3/library/Director/Web/Table/ObjectsTable.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/Web/Table/ObjectsTable.php 2025-03-26 11:24:49.000000000 +0100 @@ -226,11 +226,14 @@ { /** @var Db $db */ $db = $this->connection(); + $dummyObject = $this->getDummyObject(); + $type = $dummyObject->getShortTableName(); - return [ - new HostgroupRestriction($db, $this->auth), - new FilterByNameRestriction($db, $this->auth, $this->getDummyObject()->getShortTableName()) - ]; + if ($dummyObject->isApplyRule()) { + return [new FilterByNameRestriction($db, $this->auth, $type)]; + } else { + return [new HostgroupRestriction($db, $this->auth)]; + } } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/library/Director/Web/Widget/JobDetails.php new/icingaweb2-module-director-1.11.4/library/Director/Web/Widget/JobDetails.php --- old/icingaweb2-module-director-1.11.3/library/Director/Web/Widget/JobDetails.php 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/library/Director/Web/Widget/JobDetails.php 2025-03-26 11:24:49.000000000 +0100 @@ -45,7 +45,7 @@ $tsLastAttempt = $job->get('ts_last_attempt'); if ($tsLastAttempt) { - $ts = \strtotime($tsLastAttempt); + $ts = $tsLastAttempt / 1000; $timeAgo = Html::tag('span', [ 'class' => 'time-ago', 'title' => DateFormatter::formatDateTime($ts) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/module.info new/icingaweb2-module-director-1.11.4/module.info --- old/icingaweb2-module-director-1.11.3/module.info 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/module.info 2025-03-26 11:24:49.000000000 +0100 @@ -1,5 +1,5 @@ Name: Icinga Director -Version: 1.11.3 +Version: 1.11.4 Depends: reactbundle (>=0.9.0), ipl (>=0.5.0), incubator (>=0.22.0) Description: Director - Config tool for Icinga 2 Icinga Director is a configuration tool that has been designed to make diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/schema/mysql-migrations/upgrade_188.sql new/icingaweb2-module-director-1.11.4/schema/mysql-migrations/upgrade_188.sql --- old/icingaweb2-module-director-1.11.3/schema/mysql-migrations/upgrade_188.sql 1970-01-01 01:00:00.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/schema/mysql-migrations/upgrade_188.sql 2025-03-26 11:24:49.000000000 +0100 @@ -0,0 +1,17 @@ +ALTER TABLE director_activity_log +DROP INDEX checksum, +ADD UNIQUE INDEX checksum (checksum); + +ALTER TABLE director_generated_config +DROP FOREIGN KEY director_generated_config_activity; + +ALTER TABLE director_generated_config +ADD CONSTRAINT director_generated_config_activity + FOREIGN KEY (last_activity_checksum) + REFERENCES director_activity_log (checksum) + ON DELETE RESTRICT + ON UPDATE RESTRICT; + +INSERT INTO director_schema_migration + (schema_version, migration_time) + VALUES (188, NOW()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/schema/mysql-migrations/upgrade_189.sql new/icingaweb2-module-director-1.11.4/schema/mysql-migrations/upgrade_189.sql --- old/icingaweb2-module-director-1.11.3/schema/mysql-migrations/upgrade_189.sql 1970-01-01 01:00:00.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/schema/mysql-migrations/upgrade_189.sql 2025-03-26 11:24:49.000000000 +0100 @@ -0,0 +1,17 @@ +ALTER TABLE director_job ADD COLUMN ts_last_attempt_tmp BIGINT(20) DEFAULT NULL; +ALTER TABLE director_job ADD COLUMN ts_last_error_tmp BIGINT(20) DEFAULT NULL; + + +UPDATE director_job +SET ts_last_attempt_tmp = UNIX_TIMESTAMP(ts_last_attempt) * 1000, + ts_last_error_tmp = UNIX_TIMESTAMP(ts_last_error) * 1000; + +ALTER TABLE director_job + DROP COLUMN ts_last_attempt, + DROP COLUMN ts_last_error, + CHANGE ts_last_attempt_tmp ts_last_attempt BIGINT(20) DEFAULT NULL, + CHANGE ts_last_error_tmp ts_last_error BIGINT(20) DEFAULT NULL; + +INSERT INTO director_schema_migration +(schema_version, migration_time) +VALUES (189, NOW()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/schema/mysql.sql new/icingaweb2-module-director-1.11.4/schema/mysql.sql --- old/icingaweb2-module-director-1.11.3/schema/mysql.sql 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/schema/mysql.sql 2025-03-26 11:24:49.000000000 +0100 @@ -46,7 +46,7 @@ INDEX search_idx (object_name), INDEX search_idx2 (object_type(32), object_name(64), change_time), INDEX search_author (author), - INDEX checksum (checksum) + UNIQUE INDEX checksum (checksum) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE director_activity_log_remark ( @@ -114,7 +114,7 @@ last_activity_checksum VARBINARY(20) NOT NULL, PRIMARY KEY (checksum), CONSTRAINT director_generated_config_activity - FOREIGN KEY activity_checksum (last_activity_checksum) + FOREIGN KEY (last_activity_checksum) REFERENCES director_activity_log (checksum) ON DELETE RESTRICT ON UPDATE RESTRICT @@ -347,8 +347,8 @@ run_interval INT(10) UNSIGNED NOT NULL, -- seconds timeperiod_id INT(10) UNSIGNED DEFAULT NULL, last_attempt_succeeded ENUM('y', 'n') DEFAULT NULL, - ts_last_attempt TIMESTAMP NULL DEFAULT NULL, - ts_last_error TIMESTAMP NULL DEFAULT NULL, + ts_last_attempt BIGINT(20) NULL DEFAULT NULL, + ts_last_error BIGINT(20) NULL DEFAULT NULL, last_error_message TEXT DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY (job_name), @@ -2446,4 +2446,4 @@ INSERT INTO director_schema_migration (schema_version, migration_time) - VALUES (187, NOW()); + VALUES (189, NOW()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/schema/pgsql-migrations/upgrade_189.sql new/icingaweb2-module-director-1.11.4/schema/pgsql-migrations/upgrade_189.sql --- old/icingaweb2-module-director-1.11.3/schema/pgsql-migrations/upgrade_189.sql 1970-01-01 01:00:00.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/schema/pgsql-migrations/upgrade_189.sql 2025-03-26 11:24:49.000000000 +0100 @@ -0,0 +1,18 @@ +ALTER TABLE director_job ADD COLUMN ts_last_attempt_tmp bigint DEFAULT NULL; +ALTER TABLE director_job ADD COLUMN ts_last_error_tmp bigint DEFAULT NULL; + + +UPDATE director_job +SET ts_last_attempt_tmp = UNIX_TIMESTAMP(ts_last_attempt) * 1000, + ts_last_error_tmp = UNIX_TIMESTAMP(ts_last_error) * 1000; + +ALTER TABLE director_job + DROP COLUMN ts_last_attempt, + DROP COLUMN ts_last_error; + +ALTER TABLE director_job RENAME COLUMN ts_last_attempt_tmp TO ts_last_attempt; +ALTER TABLE director_job RENAME COLUMN ts_last_error_tmp TO ts_last_error; + +INSERT INTO director_schema_migration + (schema_version, migration_time) + VALUES (189, NOW()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icingaweb2-module-director-1.11.3/schema/pgsql.sql new/icingaweb2-module-director-1.11.4/schema/pgsql.sql --- old/icingaweb2-module-director-1.11.3/schema/pgsql.sql 2024-12-12 13:20:10.000000000 +0100 +++ new/icingaweb2-module-director-1.11.4/schema/pgsql.sql 2025-03-26 11:24:49.000000000 +0100 @@ -448,8 +448,8 @@ run_interval integer NOT NULL, -- seconds timeperiod_id integer DEFAULT NULL, last_attempt_succeeded enum_boolean DEFAULT NULL, - ts_last_attempt timestamp with time zone DEFAULT NULL, - ts_last_error timestamp with time zone DEFAULT NULL, + ts_last_attempt bigint DEFAULT NULL, + ts_last_error bigint DEFAULT NULL, last_error_message text NULL DEFAULT NULL, CONSTRAINT director_job_period FOREIGN KEY (timeperiod_id) @@ -2781,4 +2781,4 @@ INSERT INTO director_schema_migration (schema_version, migration_time) - VALUES (187, NOW()); + VALUES (189, NOW());