mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-31 01:34:12 +02:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6749b4fb08 | ||
|
664dedd413 | ||
|
177f300ac3 | ||
|
d0c03b84e6 | ||
|
11a10be9f8 | ||
|
2423fad54c | ||
|
2a4b78bfd2 | ||
|
38f3fe33c9 | ||
|
a99a998540 | ||
|
cadac72f4c | ||
|
4c283a24c8 | ||
|
63dac34b0f | ||
|
5f4ad0f827 | ||
|
b18cf4f80d | ||
|
42a47d6139 | ||
|
778b25873c | ||
|
2196de252d | ||
|
3fcb20178f |
15
.github/workflows/L10n-update.yml
vendored
15
.github/workflows/L10n-update.yml
vendored
@ -6,15 +6,6 @@ on:
|
|||||||
- master
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
trigger-update:
|
update:
|
||||||
name: L10n Update Trigger
|
uses: icinga/github-actions/.github/workflows/L10n-update.yml@main
|
||||||
runs-on: ubuntu-latest
|
secrets: inherit
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Repository dispatch
|
|
||||||
uses: peter-evans/repository-dispatch@v3
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.ICINGABOT_TOKEN }}
|
|
||||||
repository: Icinga/L10n
|
|
||||||
event-type: update
|
|
||||||
client-payload: '{"origin": "${{ github.repository }}", "commit": "${{ github.sha }}"}'
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Director\Controllers;
|
namespace Icinga\Module\Director\Controllers;
|
||||||
|
|
||||||
|
use Icinga\Exception\NotFoundError;
|
||||||
use Icinga\Module\Director\Web\Controller\ObjectController;
|
use Icinga\Module\Director\Web\Controller\ObjectController;
|
||||||
use Icinga\Module\Director\Objects\IcingaHost;
|
use Icinga\Module\Director\Objects\IcingaHost;
|
||||||
use Icinga\Module\Director\Objects\IcingaNotification;
|
use Icinga\Module\Director\Objects\IcingaNotification;
|
||||||
@ -80,6 +81,10 @@ class NotificationController extends ObjectController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! $this->allowsObject($this->object)) {
|
||||||
|
throw new NotFoundError('No such object available');
|
||||||
|
}
|
||||||
|
|
||||||
return $this->object;
|
return $this->object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,14 +49,6 @@ class ServiceController extends ObjectController
|
|||||||
$this->host = $this->getOptionalRelatedObjectFromParams('host', 'host');
|
$this->host = $this->getOptionalRelatedObjectFromParams('host', 'host');
|
||||||
$this->set = $this->getOptionalRelatedObjectFromParams('service_set', 'set');
|
$this->set = $this->getOptionalRelatedObjectFromParams('service_set', 'set');
|
||||||
parent::init();
|
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->addOptionalHostTabs();
|
||||||
$this->addOptionalSetTabs();
|
$this->addOptionalSetTabs();
|
||||||
}
|
}
|
||||||
@ -77,6 +69,20 @@ class ServiceController extends ObjectController
|
|||||||
return null;
|
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)
|
protected function loadOptionalRelatedObject(IcingaObject $object, $relation)
|
||||||
{
|
{
|
||||||
$key = $object->getUnresolvedRelated($relation);
|
$key = $object->getUnresolvedRelated($relation);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace Icinga\Module\Director\Controllers;
|
namespace Icinga\Module\Director\Controllers;
|
||||||
|
|
||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
|
use Icinga\Exception\NotFoundError;
|
||||||
use Icinga\Module\Director\Forms\IcingaServiceSetForm;
|
use Icinga\Module\Director\Forms\IcingaServiceSetForm;
|
||||||
use Icinga\Module\Director\Objects\IcingaHost;
|
use Icinga\Module\Director\Objects\IcingaHost;
|
||||||
use Icinga\Module\Director\Objects\IcingaServiceSet;
|
use Icinga\Module\Director\Objects\IcingaServiceSet;
|
||||||
@ -136,6 +137,10 @@ class ServicesetController extends ObjectController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! $this->allowsObject($this->object)) {
|
||||||
|
throw new NotFoundError('No such object available');
|
||||||
|
}
|
||||||
|
|
||||||
return $this->object;
|
return $this->object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ trait DeployFormsBug7530
|
|||||||
if (parent::hasBeenSubmitted()) {
|
if (parent::hasBeenSubmitted()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return \strlen($this->getSentValue('confirm_7530')) > 0;
|
return strlen($this->getSentValue('confirm_7530', '')) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,13 @@ class IcingaAddServiceForm extends DirectorObjectForm
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addSingleImportElement();
|
$this->addSingleImportElement(true);
|
||||||
|
|
||||||
|
if (empty($this->enumServiceTemplates())) {
|
||||||
|
$this->setSubmitLabel(false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (! ($imports = $this->getSentOrObjectValue('imports'))) {
|
if (! ($imports = $this->getSentOrObjectValue('imports'))) {
|
||||||
$this->setSubmitLabel($this->translate('Next'));
|
$this->setSubmitLabel($this->translate('Next'));
|
||||||
|
@ -51,6 +51,7 @@ class IcingaMultiEditForm extends DirectorObjectForm
|
|||||||
$loader = new IcingaObjectFieldLoader($object);
|
$loader = new IcingaObjectFieldLoader($object);
|
||||||
$loader->prepareElements($this);
|
$loader->prepareElements($this);
|
||||||
$loader->addFieldsToForm($this);
|
$loader->addFieldsToForm($this);
|
||||||
|
$this->varNameMap = $loader->getNameMap();
|
||||||
|
|
||||||
if ($form = $this->relatedForm) {
|
if ($form = $this->relatedForm) {
|
||||||
if ($form instanceof DirectorObjectForm) {
|
if ($form instanceof DirectorObjectForm) {
|
||||||
@ -237,10 +238,6 @@ class IcingaMultiEditForm extends DirectorObjectForm
|
|||||||
$this->removeElement($key);
|
$this->removeElement($key);
|
||||||
$label = $element->getLabel();
|
$label = $element->getLabel();
|
||||||
|
|
||||||
if ($this->isCustomVar($key)) {
|
|
||||||
$this->varNameMap[$key] = $label;
|
|
||||||
}
|
|
||||||
|
|
||||||
$group = $this->getDisplayGroupForElement($element);
|
$group = $this->getDisplayGroupForElement($element);
|
||||||
$description = $element->getDescription();
|
$description = $element->getDescription();
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ and extract it to a folder named `director` in one of your Icinga Web module pat
|
|||||||
You might want to use a script as follows for this task:
|
You might want to use a script as follows for this task:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
MODULE_VERSION="1.11.3"
|
MODULE_VERSION="1.11.5"
|
||||||
ICINGAWEB_MODULEPATH="/usr/share/icingaweb2/modules"
|
ICINGAWEB_MODULEPATH="/usr/share/icingaweb2/modules"
|
||||||
REPO_URL="https://github.com/icinga/icingaweb2-module-director"
|
REPO_URL="https://github.com/icinga/icingaweb2-module-director"
|
||||||
TARGET_DIR="${ICINGAWEB_MODULEPATH}/director"
|
TARGET_DIR="${ICINGAWEB_MODULEPATH}/director"
|
||||||
@ -60,7 +60,7 @@ Simply clone the repository in one of your Icinga web module path directories.
|
|||||||
You might want to use a script as follows for this task:
|
You might want to use a script as follows for this task:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
MODULE_VERSION="1.11.3"
|
MODULE_VERSION="1.11.5"
|
||||||
ICINGAWEB_MODULEPATH="/usr/share/icingaweb2/modules"
|
ICINGAWEB_MODULEPATH="/usr/share/icingaweb2/modules"
|
||||||
REPO_URL="https://github.com/icinga/icingaweb2-module-director"
|
REPO_URL="https://github.com/icinga/icingaweb2-module-director"
|
||||||
TARGET_DIR="${ICINGAWEB_MODULEPATH}/director"
|
TARGET_DIR="${ICINGAWEB_MODULEPATH}/director"
|
||||||
|
@ -4,6 +4,50 @@
|
|||||||
Please make sure to always read our [Upgrading](05-Upgrading.md) documentation
|
Please make sure to always read our [Upgrading](05-Upgrading.md) documentation
|
||||||
before switching to a new version.
|
before switching to a new version.
|
||||||
|
|
||||||
|
v1.11.5
|
||||||
|
-------
|
||||||
|
|
||||||
|
## Database Schema
|
||||||
|
|
||||||
|
- FIX: Failed schema migration of MySQL to version 188 due Integrity constraint violation ([#2970](https://github.com/Icinga/icingaweb2-module-director/issues/2970))
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
- Fix: Deprecation notice that sometimes appears on deployment form (no issue)
|
||||||
|
|
||||||
|
### Fixed Issues
|
||||||
|
|
||||||
|
You can find issues related to this release on our [roadmap](https://github.com/Icinga/icingaweb2-module-director/milestone/40?closed=1)
|
||||||
|
|
||||||
|
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
|
v1.11.3
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace Icinga\Module\Director\Objects;
|
namespace Icinga\Module\Director\Objects;
|
||||||
|
|
||||||
use Icinga\Exception\NotFoundError;
|
use Icinga\Exception\NotFoundError;
|
||||||
|
use Icinga\Module\Director\Daemon\DaemonUtil;
|
||||||
use Icinga\Module\Director\Daemon\Logger;
|
use Icinga\Module\Director\Daemon\Logger;
|
||||||
use Icinga\Module\Director\Data\Db\DbObjectWithSettings;
|
use Icinga\Module\Director\Data\Db\DbObjectWithSettings;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
@ -84,7 +85,8 @@ class DirectorJob extends DbObjectWithSettings implements ExportInterface, Insta
|
|||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
$job = $this->getInstance();
|
$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 {
|
try {
|
||||||
$job->run();
|
$job->run();
|
||||||
@ -92,7 +94,7 @@ class DirectorJob extends DbObjectWithSettings implements ExportInterface, Insta
|
|||||||
$success = true;
|
$success = true;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
Logger::error($e->getMessage());
|
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_error_message', $e->getMessage());
|
||||||
$this->set('last_attempt_succeeded', 'n');
|
$this->set('last_attempt_succeeded', 'n');
|
||||||
$success = false;
|
$success = false;
|
||||||
@ -127,8 +129,8 @@ class DirectorJob extends DbObjectWithSettings implements ExportInterface, Insta
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
strtotime($this->get('ts_last_attempt')) + $this->get('run_interval') * 2
|
$this->get('ts_last_attempt') + $this->get('run_interval') * 2 * 1000
|
||||||
) < time();
|
) < DaemonUtil::timestampWithMilliseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasBeenDisabled()
|
public function hasBeenDisabled()
|
||||||
@ -145,7 +147,9 @@ class DirectorJob extends DbObjectWithSettings implements ExportInterface, Insta
|
|||||||
return $this->isWithinTimeperiod();
|
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();
|
return $this->isWithinTimeperiod();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Director\ProvidedHook\Icingadb;
|
|||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
use Icinga\Exception\NotFoundError;
|
use Icinga\Exception\NotFoundError;
|
||||||
|
use Icinga\Module\Director\CustomVariable\CustomVariableArray;
|
||||||
use Icinga\Module\Director\Daemon\Logger;
|
use Icinga\Module\Director\Daemon\Logger;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
use Icinga\Module\Director\Db\AppliedServiceSetLoader;
|
use Icinga\Module\Director\Db\AppliedServiceSetLoader;
|
||||||
@ -113,9 +114,30 @@ class CustomVarRenderer extends CustomVarRendererHook
|
|||||||
$appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery();
|
$appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery();
|
||||||
|
|
||||||
foreach ($appliedFilterQuery->fetchAll() as $appliedService) {
|
foreach ($appliedFilterQuery->fetchAll() as $appliedService) {
|
||||||
if ($appliedService->name === $serviceName) {
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $isAppliedService) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$query = $db->getDbAdapter()->select()->from('icinga_service')
|
$query = $db->getDbAdapter()->select()->from('icinga_service')
|
||||||
->where('object_name = ?', $serviceName)
|
->where('object_name = ?', $appliedService->name)
|
||||||
->where("object_type = 'apply'")
|
->where("object_type = 'apply'")
|
||||||
->where('assign_filter = ?', $appliedService->assign_filter);
|
->where('assign_filter = ?', $appliedService->assign_filter);
|
||||||
|
|
||||||
@ -129,7 +151,6 @@ class CustomVarRenderer extends CustomVarRendererHook
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} elseif ($serviceOrigin[$i] === 'service-set') {
|
} elseif ($serviceOrigin[$i] === 'service-set') {
|
||||||
$templateResolver = new IcingaTemplateResolver($directorHostObj);
|
$templateResolver = new IcingaTemplateResolver($directorHostObj);
|
||||||
|
|
||||||
@ -253,7 +274,24 @@ class CustomVarRenderer extends CustomVarRendererHook
|
|||||||
return '***';
|
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(
|
return new HtmlElement(
|
||||||
'span',
|
'span',
|
||||||
Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]),
|
Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]),
|
||||||
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Director\ProvidedHook\Monitoring;
|
|||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
use Icinga\Exception\NotFoundError;
|
use Icinga\Exception\NotFoundError;
|
||||||
|
use Icinga\Module\Director\CustomVariable\CustomVariableArray;
|
||||||
use Icinga\Module\Director\Daemon\Logger;
|
use Icinga\Module\Director\Daemon\Logger;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
use Icinga\Module\Director\Db\AppliedServiceSetLoader;
|
use Icinga\Module\Director\Db\AppliedServiceSetLoader;
|
||||||
@ -114,9 +115,30 @@ class CustomVarRenderer extends CustomVarRendererHook
|
|||||||
$appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery();
|
$appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery();
|
||||||
|
|
||||||
foreach ($appliedFilterQuery->fetchAll() as $appliedService) {
|
foreach ($appliedFilterQuery->fetchAll() as $appliedService) {
|
||||||
if ($appliedService->name === $serviceName) {
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $isAppliedService) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$query = $db->getDbAdapter()->select()->from('icinga_service')
|
$query = $db->getDbAdapter()->select()->from('icinga_service')
|
||||||
->where('object_name = ?', $serviceName)
|
->where('object_name = ?', $appliedService->name)
|
||||||
->where("object_type = 'apply'")
|
->where("object_type = 'apply'")
|
||||||
->where('assign_filter = ?', $appliedService->assign_filter);
|
->where('assign_filter = ?', $appliedService->assign_filter);
|
||||||
|
|
||||||
@ -130,7 +152,6 @@ class CustomVarRenderer extends CustomVarRendererHook
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} elseif ($serviceOrigin[$i] === 'service-set') {
|
} elseif ($serviceOrigin[$i] === 'service-set') {
|
||||||
$templateResolver = new IcingaTemplateResolver($directorHostObj);
|
$templateResolver = new IcingaTemplateResolver($directorHostObj);
|
||||||
|
|
||||||
@ -254,7 +275,24 @@ class CustomVarRenderer extends CustomVarRendererHook
|
|||||||
return '***';
|
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(
|
return new HtmlElement(
|
||||||
'span',
|
'span',
|
||||||
Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]),
|
Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]),
|
||||||
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Restriction;
|
|||||||
use gipfl\IcingaWeb2\Zf1\Db\FilterRenderer;
|
use gipfl\IcingaWeb2\Zf1\Db\FilterRenderer;
|
||||||
use Icinga\Authentication\Auth;
|
use Icinga\Authentication\Auth;
|
||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
|
use Icinga\Data\Filter\FilterEqual;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
use Icinga\Module\Director\Objects\IcingaObject;
|
use Icinga\Module\Director\Objects\IcingaObject;
|
||||||
use Zend_Db_Select as ZfSelect;
|
use Zend_Db_Select as ZfSelect;
|
||||||
@ -30,7 +31,11 @@ class FilterByNameRestriction extends ObjectRestriction
|
|||||||
|
|
||||||
protected function setNameForType($type)
|
protected function setNameForType($type)
|
||||||
{
|
{
|
||||||
|
if ($type === 'service_set') {
|
||||||
$this->name = "director/{$type}/filter-by-name";
|
$this->name = "director/{$type}/filter-by-name";
|
||||||
|
} else {
|
||||||
|
$this->name = "director/{$type}/apply/filter-by-name";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function allows(IcingaObject $object)
|
public function allows(IcingaObject $object)
|
||||||
@ -39,9 +44,9 @@ class FilterByNameRestriction extends ObjectRestriction
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getFilter()->matches([
|
return $this->getFilter()->matches(
|
||||||
(object) ['object_name' => $object->getObjectName()]
|
(object) ['object_name' => $object->getObjectName()]
|
||||||
]);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFilter()
|
public function getFilter()
|
||||||
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Web\Controller\Extension;
|
|||||||
use Icinga\Authentication\Auth;
|
use Icinga\Authentication\Auth;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
use Icinga\Module\Director\Objects\IcingaObject;
|
use Icinga\Module\Director\Objects\IcingaObject;
|
||||||
|
use Icinga\Module\Director\Restriction\FilterByNameRestriction;
|
||||||
use Icinga\Module\Director\Restriction\HostgroupRestriction;
|
use Icinga\Module\Director\Restriction\HostgroupRestriction;
|
||||||
use Icinga\Module\Director\Restriction\ObjectRestriction;
|
use Icinga\Module\Director\Restriction\ObjectRestriction;
|
||||||
|
|
||||||
@ -13,6 +14,9 @@ trait ObjectRestrictions
|
|||||||
/** @var ObjectRestriction[] */
|
/** @var ObjectRestriction[] */
|
||||||
private $objectRestrictions;
|
private $objectRestrictions;
|
||||||
|
|
||||||
|
/** @var IcingaObject */
|
||||||
|
private $dummyRestrictedObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ObjectRestriction[]
|
* @return ObjectRestriction[]
|
||||||
*/
|
*/
|
||||||
@ -30,13 +34,27 @@ trait ObjectRestrictions
|
|||||||
*/
|
*/
|
||||||
protected function loadObjectRestrictions(Db $db, Auth $auth)
|
protected function loadObjectRestrictions(Db $db, Auth $auth)
|
||||||
{
|
{
|
||||||
return [
|
$objectType = $this->dummyRestrictedObject->getShortTableName();
|
||||||
new HostgroupRestriction($db, $auth)
|
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)
|
public function allowsObject(IcingaObject $object)
|
||||||
{
|
{
|
||||||
|
$this->dummyRestrictedObject = $object;
|
||||||
foreach ($this->getObjectRestrictions() as $restriction) {
|
foreach ($this->getObjectRestrictions() as $restriction) {
|
||||||
if (! $restriction->allows($object)) {
|
if (! $restriction->allows($object)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -17,6 +17,7 @@ use Icinga\Module\Director\Objects\IcingaService;
|
|||||||
use Icinga\Module\Director\RestApi\IcingaObjectsHandler;
|
use Icinga\Module\Director\RestApi\IcingaObjectsHandler;
|
||||||
use Icinga\Module\Director\Web\ActionBar\ObjectsActionBar;
|
use Icinga\Module\Director\Web\ActionBar\ObjectsActionBar;
|
||||||
use Icinga\Module\Director\Web\ActionBar\TemplateActionBar;
|
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\Form\FormLoader;
|
||||||
use Icinga\Module\Director\Web\Table\ApplyRulesTable;
|
use Icinga\Module\Director\Web\Table\ApplyRulesTable;
|
||||||
use Icinga\Module\Director\Web\Table\ObjectSetTable;
|
use Icinga\Module\Director\Web\Table\ObjectSetTable;
|
||||||
@ -33,6 +34,7 @@ use Ramsey\Uuid\Uuid;
|
|||||||
abstract class ObjectsController extends ActionController
|
abstract class ObjectsController extends ActionController
|
||||||
{
|
{
|
||||||
use BranchHelper;
|
use BranchHelper;
|
||||||
|
use ObjectRestrictions;
|
||||||
|
|
||||||
protected $isApified = true;
|
protected $isApified = true;
|
||||||
|
|
||||||
@ -75,9 +77,13 @@ abstract class ObjectsController extends ActionController
|
|||||||
$table = $this->getTable();
|
$table = $this->getTable();
|
||||||
if (
|
if (
|
||||||
$request->getControllerName() === 'services'
|
$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'));
|
$table->getQuery()->where('o.host_id = ?', $host->get('id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,16 @@ class IcingaObjectFieldLoader
|
|||||||
return $this;
|
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)
|
public function loadFieldsForMultipleObjects($objects)
|
||||||
{
|
{
|
||||||
$fields = array();
|
$fields = array();
|
||||||
|
@ -4,6 +4,7 @@ namespace Icinga\Module\Director\Web\Table;
|
|||||||
|
|
||||||
use gipfl\IcingaWeb2\Link;
|
use gipfl\IcingaWeb2\Link;
|
||||||
use gipfl\IcingaWeb2\Table\ZfQueryBasedTable;
|
use gipfl\IcingaWeb2\Table\ZfQueryBasedTable;
|
||||||
|
use Icinga\Module\Director\Daemon\DaemonUtil;
|
||||||
|
|
||||||
class JobTable extends ZfQueryBasedTable
|
class JobTable extends ZfQueryBasedTable
|
||||||
{
|
{
|
||||||
@ -37,11 +38,11 @@ class JobTable extends ZfQueryBasedTable
|
|||||||
|
|
||||||
protected function getJobClasses($row)
|
protected function getJobClasses($row)
|
||||||
{
|
{
|
||||||
if ($row->unixts_last_attempt === null) {
|
if ($row->ts_last_attempt === null) {
|
||||||
return 'pending';
|
return 'pending';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($row->unixts_last_attempt + $row->run_interval < time()) {
|
if ($row->ts_last_attempt + $row->run_interval * 1000 < DaemonUtil::timestampWithMilliseconds()) {
|
||||||
return 'pending';
|
return 'pending';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +74,6 @@ class JobTable extends ZfQueryBasedTable
|
|||||||
'run_interval' => 'j.run_interval',
|
'run_interval' => 'j.run_interval',
|
||||||
'last_attempt_succeeded' => 'j.last_attempt_succeeded',
|
'last_attempt_succeeded' => 'j.last_attempt_succeeded',
|
||||||
'ts_last_attempt' => 'j.ts_last_attempt',
|
'ts_last_attempt' => 'j.ts_last_attempt',
|
||||||
'unixts_last_attempt' => 'UNIX_TIMESTAMP(j.ts_last_attempt)',
|
|
||||||
'ts_last_error' => 'j.ts_last_error',
|
'ts_last_error' => 'j.ts_last_error',
|
||||||
'last_error_message' => 'j.last_error_message',
|
'last_error_message' => 'j.last_error_message',
|
||||||
]
|
]
|
||||||
|
@ -226,11 +226,14 @@ class ObjectsTable extends ZfQueryBasedTable
|
|||||||
{
|
{
|
||||||
/** @var Db $db */
|
/** @var Db $db */
|
||||||
$db = $this->connection();
|
$db = $this->connection();
|
||||||
|
$dummyObject = $this->getDummyObject();
|
||||||
|
$type = $dummyObject->getShortTableName();
|
||||||
|
|
||||||
return [
|
if ($dummyObject->isApplyRule()) {
|
||||||
new HostgroupRestriction($db, $this->auth),
|
return [new FilterByNameRestriction($db, $this->auth, $type)];
|
||||||
new FilterByNameRestriction($db, $this->auth, $this->getDummyObject()->getShortTableName())
|
} else {
|
||||||
];
|
return [new HostgroupRestriction($db, $this->auth)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +45,7 @@ class JobDetails extends HtmlDocument
|
|||||||
|
|
||||||
$tsLastAttempt = $job->get('ts_last_attempt');
|
$tsLastAttempt = $job->get('ts_last_attempt');
|
||||||
if ($tsLastAttempt) {
|
if ($tsLastAttempt) {
|
||||||
$ts = \strtotime($tsLastAttempt);
|
$ts = $tsLastAttempt / 1000;
|
||||||
$timeAgo = Html::tag('span', [
|
$timeAgo = Html::tag('span', [
|
||||||
'class' => 'time-ago',
|
'class' => 'time-ago',
|
||||||
'title' => DateFormatter::formatDateTime($ts)
|
'title' => DateFormatter::formatDateTime($ts)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Name: Icinga Director
|
Name: Icinga Director
|
||||||
Version: 1.11.3
|
Version: 1.11.5
|
||||||
Depends: reactbundle (>=0.9.0), ipl (>=0.5.0), incubator (>=0.22.0)
|
Depends: reactbundle (>=0.9.0), ipl (>=0.5.0), incubator (>=0.22.0)
|
||||||
Description: Director - Config tool for Icinga 2
|
Description: Director - Config tool for Icinga 2
|
||||||
Icinga Director is a configuration tool that has been designed to make
|
Icinga Director is a configuration tool that has been designed to make
|
||||||
|
22
schema/mysql-migrations/upgrade_188.sql
Normal file
22
schema/mysql-migrations/upgrade_188.sql
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
ALTER TABLE director_generated_config
|
||||||
|
DROP FOREIGN KEY director_generated_config_activity;
|
||||||
|
|
||||||
|
# Delete all entries with duplicate checksum except the first entry
|
||||||
|
DELETE log1 FROM director_activity_log log1
|
||||||
|
INNER JOIN director_activity_log log2 ON log1.checksum = log2.checksum
|
||||||
|
WHERE log1.id > log2.id;
|
||||||
|
|
||||||
|
ALTER TABLE director_activity_log
|
||||||
|
DROP INDEX checksum,
|
||||||
|
ADD UNIQUE INDEX checksum (checksum);
|
||||||
|
|
||||||
|
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());
|
17
schema/mysql-migrations/upgrade_189.sql
Normal file
17
schema/mysql-migrations/upgrade_189.sql
Normal file
@ -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());
|
@ -46,7 +46,7 @@ CREATE TABLE director_activity_log (
|
|||||||
INDEX search_idx (object_name),
|
INDEX search_idx (object_name),
|
||||||
INDEX search_idx2 (object_type(32), object_name(64), change_time),
|
INDEX search_idx2 (object_type(32), object_name(64), change_time),
|
||||||
INDEX search_author (author),
|
INDEX search_author (author),
|
||||||
INDEX checksum (checksum)
|
UNIQUE INDEX checksum (checksum)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
CREATE TABLE director_activity_log_remark (
|
CREATE TABLE director_activity_log_remark (
|
||||||
@ -114,7 +114,7 @@ CREATE TABLE director_generated_config (
|
|||||||
last_activity_checksum VARBINARY(20) NOT NULL,
|
last_activity_checksum VARBINARY(20) NOT NULL,
|
||||||
PRIMARY KEY (checksum),
|
PRIMARY KEY (checksum),
|
||||||
CONSTRAINT director_generated_config_activity
|
CONSTRAINT director_generated_config_activity
|
||||||
FOREIGN KEY activity_checksum (last_activity_checksum)
|
FOREIGN KEY (last_activity_checksum)
|
||||||
REFERENCES director_activity_log (checksum)
|
REFERENCES director_activity_log (checksum)
|
||||||
ON DELETE RESTRICT
|
ON DELETE RESTRICT
|
||||||
ON UPDATE RESTRICT
|
ON UPDATE RESTRICT
|
||||||
@ -347,8 +347,8 @@ CREATE TABLE director_job (
|
|||||||
run_interval INT(10) UNSIGNED NOT NULL, -- seconds
|
run_interval INT(10) UNSIGNED NOT NULL, -- seconds
|
||||||
timeperiod_id INT(10) UNSIGNED DEFAULT NULL,
|
timeperiod_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
last_attempt_succeeded ENUM('y', 'n') DEFAULT NULL,
|
last_attempt_succeeded ENUM('y', 'n') DEFAULT NULL,
|
||||||
ts_last_attempt TIMESTAMP NULL DEFAULT NULL,
|
ts_last_attempt BIGINT(20) NULL DEFAULT NULL,
|
||||||
ts_last_error TIMESTAMP NULL DEFAULT NULL,
|
ts_last_error BIGINT(20) NULL DEFAULT NULL,
|
||||||
last_error_message TEXT DEFAULT NULL,
|
last_error_message TEXT DEFAULT NULL,
|
||||||
PRIMARY KEY (id),
|
PRIMARY KEY (id),
|
||||||
UNIQUE KEY (job_name),
|
UNIQUE KEY (job_name),
|
||||||
@ -2446,4 +2446,4 @@ CREATE TABLE branched_icinga_dependency (
|
|||||||
|
|
||||||
INSERT INTO director_schema_migration
|
INSERT INTO director_schema_migration
|
||||||
(schema_version, migration_time)
|
(schema_version, migration_time)
|
||||||
VALUES (187, NOW());
|
VALUES (189, NOW());
|
||||||
|
18
schema/pgsql-migrations/upgrade_189.sql
Normal file
18
schema/pgsql-migrations/upgrade_189.sql
Normal file
@ -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());
|
@ -448,8 +448,8 @@ CREATE TABLE director_job (
|
|||||||
run_interval integer NOT NULL, -- seconds
|
run_interval integer NOT NULL, -- seconds
|
||||||
timeperiod_id integer DEFAULT NULL,
|
timeperiod_id integer DEFAULT NULL,
|
||||||
last_attempt_succeeded enum_boolean DEFAULT NULL,
|
last_attempt_succeeded enum_boolean DEFAULT NULL,
|
||||||
ts_last_attempt timestamp with time zone DEFAULT NULL,
|
ts_last_attempt bigint DEFAULT NULL,
|
||||||
ts_last_error timestamp with time zone DEFAULT NULL,
|
ts_last_error bigint DEFAULT NULL,
|
||||||
last_error_message text NULL DEFAULT NULL,
|
last_error_message text NULL DEFAULT NULL,
|
||||||
CONSTRAINT director_job_period
|
CONSTRAINT director_job_period
|
||||||
FOREIGN KEY (timeperiod_id)
|
FOREIGN KEY (timeperiod_id)
|
||||||
@ -2781,4 +2781,4 @@ CREATE INDEX branched_dependency_search_object_name ON branched_icinga_dependenc
|
|||||||
|
|
||||||
INSERT INTO director_schema_migration
|
INSERT INTO director_schema_migration
|
||||||
(schema_version, migration_time)
|
(schema_version, migration_time)
|
||||||
VALUES (187, NOW());
|
VALUES (189, NOW());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user