Render the host dictionary items as variable in apply-for-rule

This commit is contained in:
raviks789 2025-05-27 13:27:40 +02:00
parent 79a4e32b3e
commit 3e4e00c8af
No known key found for this signature in database
3 changed files with 96 additions and 11 deletions

View File

@ -7,6 +7,15 @@ use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1;
class CustomVariableString extends CustomVariable class CustomVariableString extends CustomVariable
{ {
private $whiteList = [];
protected function __construct($key, $value = null, $whiteList = [])
{
parent::__construct($key, $value);
$this->whiteList = $whiteList;
}
public function equals(CustomVariable $var) public function equals(CustomVariable $var)
{ {
if (! $var instanceof CustomVariableString) { if (! $var instanceof CustomVariableString) {
@ -46,17 +55,7 @@ class CustomVariableString extends CustomVariable
public function toConfigString($renderExpressions = false) public function toConfigString($renderExpressions = false)
{ {
if ($renderExpressions) { if ($renderExpressions) {
$whiteList = ['value']; return c::renderStringWithVariables($this->getValue(), $this->whiteList);
$value = $this->getValue();
if (
str_starts_with($value, '$')
&& str_ends_with($value, '$')
&& str_contains($value, 'value.')
) {
$whiteList[] = trim($value, '$');
}
return c::renderStringWithVariables($this->getValue(), $whiteList);
} else { } else {
return c::renderString($this->getValue()); return c::renderString($this->getValue());
} }
@ -66,4 +65,11 @@ class CustomVariableString extends CustomVariable
{ {
return c1::renderString($this->getValue()); return c1::renderString($this->getValue());
} }
public function setWhiteList(array $whiteList): self
{
$this->whiteList = $whiteList;
return $this;
}
} }

View File

@ -27,6 +27,8 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
protected $idx = array(); protected $idx = array();
private $whiteList = [];
protected static $allTables = array( protected static $allTables = array(
'icinga_command_var', 'icinga_command_var',
'icinga_host_var', 'icinga_host_var',
@ -159,6 +161,18 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
return $this; return $this;
} }
public function setWhiteList(array $whitelist): self
{
$this->whiteList = $whitelist;
return $this;
}
public function getWhiteList(array $whitelist): array
{
return $this->whiteList;
}
protected function refreshIndex() protected function refreshIndex()
{ {
$this->idx = array(); $this->idx = array();
@ -398,6 +412,10 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
*/ */
protected function renderSingleVar($key, $var, $renderExpressions = false) protected function renderSingleVar($key, $var, $renderExpressions = false)
{ {
if ($var instanceof CustomVariableString) {
$var->setWhiteList($this->whiteList);
}
if ($key === $this->overrideKeyName) { if ($key === $this->overrideKeyName) {
return c::renderKeyOperatorValue( return c::renderKeyOperatorValue(
$this->renderKeyName($key), $this->renderKeyName($key),

View File

@ -14,6 +14,7 @@ use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1;
use Icinga\Module\Director\Objects\Extension\FlappingSupport; use Icinga\Module\Director\Objects\Extension\FlappingSupport;
use Icinga\Module\Director\Resolver\HostServiceBlacklist; use Icinga\Module\Director\Resolver\HostServiceBlacklist;
use InvalidArgumentException; use InvalidArgumentException;
use PDO;
use RuntimeException; use RuntimeException;
class IcingaService extends IcingaObject implements ExportInterface class IcingaService extends IcingaObject implements ExportInterface
@ -24,6 +25,8 @@ class IcingaService extends IcingaObject implements ExportInterface
protected $uuidColumn = 'uuid'; protected $uuidColumn = 'uuid';
private $vars;
protected $defaultProperties = [ protected $defaultProperties = [
'id' => null, 'id' => null,
'uuid' => null, 'uuid' => null,
@ -660,6 +663,64 @@ class IcingaService extends IcingaObject implements ExportInterface
return $where; return $where;
} }
public function vars()
{
$vars = parent::vars();
if ($this->isApplyRule() && $vars) {
$applyFor = substr($this->get('apply_for'), strlen('host.vars.'));
$query = $this->db
->select()
->from(
['dp' => 'director_property'],
[
'key_name' => 'dp.key_name',
'uuid' => 'dp.uuid',
'value_type' => 'dp.value_type'
]
)
->join(['parent_dp' => 'director_property'], 'dp.parent_uuid = parent_dp.uuid', [])
->where("parent_dp.value_type = 'dict'")
->where("parent_dp.key_name = ?", $applyFor);
$result = $this->db->fetchAll($query, fetchMode: PDO::FETCH_ASSOC);
$whiteList = ['$value$'];
foreach ($result as $row) {
$whiteList[] = sprintf('value.%s', $row['key_name']);
if ($row['value_type'] === 'dict') {
foreach ($this->fetchItemsForDictionary($row['uuid']) as $value) {
$whiteList[] = sprintf('value.%s.%s', $row['key_name'], $value['key_name']);
}
}
}
$vars->setWhiteList($whiteList);
}
return $vars;
}
protected function fetchItemsForDictionary(string $uuid): array
{
$query = $this->db
->select()
->from(
['dp' => 'director_property'],
[
'key_name' => 'dp.key_name',
'uuid' => 'dp.uuid',
'value_type' => 'dp.value_type',
]
)
->join(['parent_dp' => 'director_property'], 'dp.parent_uuid = parent_dp.uuid', [])
->where("dp.parent_uuid = ?", $uuid);
return $this->db->fetchAll($query, fetchMode: PDO::FETCH_ASSOC);
}
/** /**
* TODO: Duplicate code, clean this up, split it into multiple methods * TODO: Duplicate code, clean this up, split it into multiple methods