IcingaNotification: implement users_var

fixes #462
This commit is contained in:
Thomas Gelf 2022-12-01 12:03:45 +01:00
parent 20785af8e7
commit 616d329be3
8 changed files with 158 additions and 20 deletions

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Director\Forms;
use Icinga\Module\Director\DataType\DataTypeDirectorObject;
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
class IcingaNotificationForm extends DirectorObjectForm
@ -121,20 +122,32 @@ class IcingaNotificationForm extends DirectorObjectForm
{
$users = $this->enumUsers();
if (empty($users)) {
return $this;
}
$this->addElement(
'extensibleSet',
'users',
array(
$this->addElement('select', 'users', [
'label' => $this->translate('Users'),
'description' => $this->translate('No User object has been created yet'),
'multiOptions' => $this->optionalEnum([]),
]);
} else {
$this->addElement('extensibleSet', 'users', [
'label' => $this->translate('Users'),
'description' => $this->translate(
'Users that should be notified by this notifications'
),
'multiOptions' => $this->optionalEnum($users)
]);
}
$this->addElement('select', 'users_var', [
'label' => $this->translate('Users Custom Variable'),
'multiOptions' => $this->enumDirectorObjectFields('user'),
'description' => $this->translate(
'If defined, Users from this Custom Variable will be combined with single users chosen below. '
. ' e.g.: when set to notification_contacts, this notification will pick Users from the Array'
. ' service.vars.notification_contacts and fall back to host.vars.notification_contacts, in'
. ' case the former one does not exist.'
. ' Only Array type DirectorObject Fields for User objects are eligible for this feature.'
)
);
]);
return $this;
}
@ -146,24 +159,59 @@ class IcingaNotificationForm extends DirectorObjectForm
{
$groups = $this->enumUsergroups();
if (empty($groups)) {
return $this;
}
$this->addElement(
'extensibleSet',
'user_groups',
array(
$this->addElement('select', 'user_groups', [
'label' => $this->translate('Users'),
'description' => $this->translate('No UserGroup object has been created yet'),
'multiOptions' => $this->optionalEnum([]),
]);
} else {
$this->addElement('extensibleSet', 'user_groups', [
'label' => $this->translate('User groups'),
'description' => $this->translate(
'User groups that should be notified by this notifications'
),
'multiOptions' => $this->optionalEnum($groups)
]);
}
$this->addElement('select', 'user_groups_var', [
'label' => $this->translate('User Groups Custom Variable'),
'multiOptions' => $this->enumDirectorObjectFields('user_group'),
'description' => $this->translate(
'If defined, User Groups from this Custom Variable will be combined with single Groups chosen below. '
. ' e.g.: when set to notification_groups, this notification will pick User Groups from the Array'
. ' service.vars.notification_groups and fall back to host.vars.notification_groups, in'
. ' case the former one does not exist'
. ' Only Array type DirectorObject Fields for User objects are eligible for this feature.'
)
);
]);
return $this;
}
protected function enumDirectorObjectFields($objectType, $dataType = 'array')
{
$db = $this->db->getDbAdapter();
$query = $db->select()
->from(['df' => 'director_datafield'], ['k' => 'df.varname', 'v' => 'df.varname'])
->join(
['dfs' => 'director_datafield_setting'],
$db->quoteInto('df.id = dfs.datafield_id AND dfs.setting_name = ?', 'icinga_object_type'),
[]
)
->join(
['dft' => 'director_datafield_setting'],
$db->quoteInto('df.id = dft.datafield_id AND dft.setting_name = ?', 'data_type'),
[]
)
->where('df.datatype = ?', DataTypeDirectorObject::class)
->where('dfs.setting_value = ?', $objectType)
->where('dft.setting_value = ?', $dataType)
->order('df.varname');
return $this->optionalEnum($db->fetchPairs($query));
}
/**
* @return self
*/

View File

@ -413,11 +413,16 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
}
protected function renderKeyName($key)
{
return 'vars' . self::renderKeySuffix($key);
}
public static function renderKeySuffix($key)
{
if (preg_match('/^[a-z][a-z0-9_]*$/i', $key)) {
return 'vars.' . c::escapeIfReserved($key);
return '.' . c::escapeIfReserved($key);
} else {
return 'vars[' . c::renderString($key) . ']';
return '[' . c::renderString($key) . ']';
}
}

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Director\Objects;
use Icinga\Module\Director\CustomVariable\CustomVariables;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\DirectorObject\Automation\ExportInterface;
use Icinga\Module\Director\Exception\DuplicateKeyException;
@ -29,6 +30,8 @@ class IcingaNotification extends IcingaObject implements ExportInterface
'notification_interval' => null,
'period_id' => null,
'zone_id' => null,
'users_var' => null,
'user_groups_var' => null,
'assign_filter' => null,
];
@ -81,6 +84,64 @@ class IcingaNotification extends IcingaObject implements ExportInterface
return c::renderKeyValue('times.begin', c::renderInterval($this->get('times_begin')));
}
/**
* @codingStandardsIgnoreStart
* @return string
*/
protected function renderUsers_var()
{
// @codingStandardsIgnoreEnd
return '';
}
/**
* @codingStandardsIgnoreStart
* @return string
*/
protected function renderUser_groups_var()
{
// @codingStandardsIgnoreEnd
return '';
}
protected function renderUserVarsSuffixFor($property)
{
$varName = $this->getResolvedProperty("{$property}_var");
if ($varName === null) {
return '';
}
$varSuffix = CustomVariables::renderKeySuffix($varName);
$indent = ' ';
$objectType = $this->get('apply_to');
if ($objectType === 'service') {
return "{$indent}if (service.vars$varSuffix) {\n"
. c::renderKeyOperatorValue($property, '+=', "service.vars$varSuffix", $indent . ' ')
. "$indent} else {\n"
. $this->getHostSnippet($indent . ' ')
. c::renderKeyOperatorValue($property, '+=', "host.vars$varSuffix", $indent . ' ')
. "$indent}\n";
} elseif ($objectType === 'host') {
return $this->getHostSnippet() . c::renderKeyOperatorValue($property, '+=', "host.vars$varSuffix");
}
return '';
}
protected function getHostSnippet($indent = ' ')
{
return "{$indent}if (! host) {\n"
. "$indent var host = get_host(host_name)\n"
. "$indent}\n";
}
protected function renderSuffix()
{
return $this->renderUserVarsSuffixFor('users')
. $this->renderUserVarsSuffixFor('user_groups')
. parent::renderSuffix();
}
/**
* @codingStandardsIgnoreStart
* @return string

View File

@ -540,7 +540,9 @@ abstract class DirectorObjectForm extends DirectorForm
'inherited_groups',
'applied_groups',
'users',
'users_var',
'user_groups',
'user_groups_var',
'apply_to',
'command_id', // Notification
'notification_interval',

View File

@ -0,0 +1,9 @@
ALTER TABLE icinga_notification
ADD COLUMN users_var VARCHAR(255) DEFAULT NULL AFTER zone_id;
ALTER TABLE icinga_notification
ADD COLUMN user_groups_var VARCHAR(255) DEFAULT NULL AFTER users_var;
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES (183, NOW());

View File

@ -1260,6 +1260,8 @@ CREATE TABLE icinga_notification (
command_id INT(10) UNSIGNED DEFAULT NULL,
period_id INT(10) UNSIGNED DEFAULT NULL,
zone_id INT(10) UNSIGNED DEFAULT NULL,
users_var VARCHAR(255) DEFAULT NULL,
user_groups_var VARCHAR(255) DEFAULT NULL,
assign_filter TEXT DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE INDEX uuid (uuid),
@ -2439,4 +2441,4 @@ CREATE TABLE branched_icinga_dependency (
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES (182, NOW());
VALUES (183, NOW());

View File

@ -0,0 +1,9 @@
ALTER TABLE icinga_notification
ADD COLUMN users_var character varying(255) DEFAULT NULL;
ALTER TABLE icinga_notification
ADD COLUMN user_groups_var character varying(255) DEFAULT NULL;
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES (183, NOW());

View File

@ -1503,6 +1503,8 @@ CREATE TABLE icinga_notification (
command_id integer DEFAULT NULL,
period_id integer DEFAULT NULL,
zone_id integer DEFAULT NULL,
users_var character varying(255) DEFAULT NULL,
user_groups_var character varying(255) DEFAULT NULL,
assign_filter text DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT icinga_notification_host
@ -2778,4 +2780,4 @@ CREATE INDEX branched_dependency_search_object_name ON branched_icinga_dependenc
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES (182, NOW());
VALUES (183, NOW());