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
{
private $whiteList = [];
protected function __construct($key, $value = null, $whiteList = [])
{
parent::__construct($key, $value);
$this->whiteList = $whiteList;
}
public function equals(CustomVariable $var)
{
if (! $var instanceof CustomVariableString) {
@ -46,17 +55,7 @@ class CustomVariableString extends CustomVariable
public function toConfigString($renderExpressions = false)
{
if ($renderExpressions) {
$whiteList = ['value'];
$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);
return c::renderStringWithVariables($this->getValue(), $this->whiteList);
} else {
return c::renderString($this->getValue());
}
@ -66,4 +65,11 @@ class CustomVariableString extends CustomVariable
{
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();
private $whiteList = [];
protected static $allTables = array(
'icinga_command_var',
'icinga_host_var',
@ -159,6 +161,18 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
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()
{
$this->idx = array();
@ -398,6 +412,10 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
*/
protected function renderSingleVar($key, $var, $renderExpressions = false)
{
if ($var instanceof CustomVariableString) {
$var->setWhiteList($this->whiteList);
}
if ($key === $this->overrideKeyName) {
return c::renderKeyOperatorValue(
$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\Resolver\HostServiceBlacklist;
use InvalidArgumentException;
use PDO;
use RuntimeException;
class IcingaService extends IcingaObject implements ExportInterface
@ -24,6 +25,8 @@ class IcingaService extends IcingaObject implements ExportInterface
protected $uuidColumn = 'uuid';
private $vars;
protected $defaultProperties = [
'id' => null,
'uuid' => null,
@ -660,6 +663,64 @@ class IcingaService extends IcingaObject implements ExportInterface
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