Apply for rule: Configurable for both dictionaries and arrays

This commit is contained in:
raviks789 2025-05-09 16:07:47 +02:00
parent d52a7f9af9
commit d3e358207b
No known key found for this signature in database
3 changed files with 102 additions and 13 deletions

View File

@ -612,6 +612,35 @@ class IcingaServiceForm extends DirectorObjectForm
return $this; return $this;
} }
protected function applyForVars(): ?array
{
$query = $this->db->getDbAdapter()
->select()
->from(
['dp' => 'director_property'],
[
'key_name' => 'dp.key_name',
'uuid' => 'dp.uuid',
'value_type' => 'dp.value_type',
'label' => 'dp.label',
'instantiable' => 'dp.instantiable',
'required' => 'iop.required'
]
)
->join(['iop' => 'icinga_host_property'], 'dp.uuid = iop.property_uuid', [])
->where("value_type = 'array' AND instantiable = 'y'")
->orWhere("value_type = 'dict'");
$vars = $this->db->getDbAdapter()->fetchAll($query);
$properties = [];
foreach ($vars as $var) {
$properties['host.vars.' . $var->key_name] = $var->label . ' (' . $var->key_name . ')';
}
return [t('director', 'Custom variables') => $properties];
}
/** /**
* @return $this * @return $this
* @throws \Zend_Form_Exception * @throws \Zend_Form_Exception
@ -619,11 +648,7 @@ class IcingaServiceForm extends DirectorObjectForm
protected function addApplyForElement() protected function addApplyForElement()
{ {
if ($this->object->isApplyRule()) { if ($this->object->isApplyRule()) {
$hostProperties = IcingaHost::enumProperties( $hostProperties = $this->applyForVars();
$this->object->getConnection(),
'host.',
new ArrayCustomVariablesFilter()
);
$this->addElement('select', 'apply_for', array( $this->addElement('select', 'apply_for', array(
'label' => $this->translate('Apply For'), 'label' => $this->translate('Apply For'),

View File

@ -46,7 +46,17 @@ class CustomVariableString extends CustomVariable
public function toConfigString($renderExpressions = false) public function toConfigString($renderExpressions = false)
{ {
if ($renderExpressions) { if ($renderExpressions) {
return c::renderStringWithVariables($this->getValue(), ['config']); $whiteList = ['config'];
$value = $this->getValue();
if (
str_starts_with($value, '$')
&& str_ends_with($value, '$')
&& str_contains($value, 'vars.')
) {
$whiteList[] = trim($value, '$');
}
return c::renderStringWithVariables($this->getValue(), $whiteList);
} else { } else {
return c::renderString($this->getValue()); return c::renderString($this->getValue());
} }

View File

@ -343,6 +343,24 @@ class IcingaService extends IcingaObject implements ExportInterface
} }
} }
/**
* @return string
*/
protected function renderCustomVars()
{
$vars = '';
if (
$this->isApplyRule()
&& !$this->hasBeenAssignedToHostTemplate()
&& $this->get('apply_for') !== null
&& $this->isApplyRuleforDictionary(substr($this->get('apply_for'), strlen('host.vars.')))
) {
$vars .= "\n vars += config\n";
}
return $vars . parent::renderCustomVars();
}
/** /**
* @return string * @return string
*/ */
@ -363,13 +381,25 @@ class IcingaService extends IcingaObject implements ExportInterface
$name = ' ' . c::renderString($name); $name = ' ' . c::renderString($name);
} }
return sprintf( if ($this->isApplyRuleforDictionary(substr($this->get('apply_for'), strlen('host.vars.')))) {
"%s %s%s for (config in %s) {\n", $applyForConfig = sprintf(
$this->getObjectTypeName(), "%s %s%s for (key => config in %s) {\n",
$this->getType(), $this->getObjectTypeName(),
$name, $this->getType(),
$this->get('apply_for') $name,
) . $extraName; $this->get('apply_for')
);
} else {
$applyForConfig = sprintf(
"%s %s%s for (config in %s) {\n",
$this->getObjectTypeName(),
$this->getType(),
$name,
$this->get('apply_for')
) . $extraName;
}
return $applyForConfig;
} }
return parent::renderObjectHeader(); return parent::renderObjectHeader();
@ -387,6 +417,30 @@ class IcingaService extends IcingaObject implements ExportInterface
} }
} }
protected function isApplyRuleforDictionary(string $applyFor): bool
{
$query = $this->db
->select()
->from(
['dp' => 'director_property'],
[
'key_name' => 'dp.key_name',
'uuid' => 'dp.uuid',
'value_type' => 'dp.value_type',
'label' => 'dp.label',
'instantiable' => 'dp.instantiable',
'required' => 'iop.required'
]
)
->join(['iop' => 'icinga_host_property'], 'dp.uuid = iop.property_uuid', [])
->where("value_type = 'dict'")
->where("key_name = ?", $applyFor);
$result = $this->db->fetchOne($query) ?? false;
return $result !== false;
}
protected function rendersConditionalTemplate(): bool protected function rendersConditionalTemplate(): bool
{ {
return $this->getRenderingZone() === self::ALL_NON_GLOBAL_ZONES; return $this->getRenderingZone() === self::ALL_NON_GLOBAL_ZONES;