mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2026-06-04 22:32:55 -04:00
Introduce a first-class DirectorProperty concept that extends the existing
data-fields model with rich, structured variable types. Custom variables can
now be defined globally under a new "Custom Variables" section and assigned
to Icinga objects (hosts, services, commands, etc.).
Supported types: string, number, boolean, fixed-array, dynamic-array,
datalist-strict, datalist-non-strict, fixed-dictionary, and
dynamic-dictionary (one level of nesting allowed).
Key changes:
- DirectorProperty object with CRUD, inheritance, and apply-for rule support
- New form elements: Dictionary, DictionaryItem, NestedDictionary,
NestedDictionaryItem, ArrayElement, IplBoolean
- CustomvarController for managing global property definitions
- VariablesController for per-object variable assignment
- BasketSnapshotCustomVariableResolver for basket import/export of properties
- REST API: IcingaObjectHandler extended to expose and accept structured vars
- IcingaConfigHelper: renders dictionaries/arrays to valid Icinga 2 DSL
- CustomVarRenderer updated for icingadb hook display
- DB migration upgrade_192.sql: new director_property and related tables
- CLI: MigrateCommand for migrating legacy vars to properties;
HostsCommand for bulk host custom variable management
69 lines
2.3 KiB
PHP
69 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace Icinga\Module\Director\Controllers;
|
|
|
|
use Icinga\Application\Config;
|
|
use Icinga\Data\Filter\Filter;
|
|
use Icinga\Module\Director\Db;
|
|
use ipl\Stdlib\Filter as iplFilter;
|
|
use ipl\Web\Compat\CompatController;
|
|
use ipl\Web\Filter\QueryString;
|
|
use ipl\Web\FormElement\SearchSuggestions;
|
|
use Ramsey\Uuid\Uuid;
|
|
use Ramsey\Uuid\UuidInterface;
|
|
|
|
class SuggestionsController extends CompatController
|
|
{
|
|
/** @var Db */
|
|
protected $db;
|
|
|
|
/** @var UuidInterface */
|
|
private UuidInterface $uuid;
|
|
|
|
public function datalistEntryAction(): void
|
|
{
|
|
$excludes = iplFilter::none();
|
|
$uuid = Uuid::fromString($this->params->shiftRequired('uuid'));
|
|
$this->db = Db::fromResourceName(
|
|
Config::module('director')->get('db', 'resource')
|
|
);
|
|
|
|
$excludeTerms = [];
|
|
|
|
if ($this->params->has('exclude')) {
|
|
$excludeTerms = explode(',', $this->params->get('exclude'));
|
|
}
|
|
|
|
if (! empty($excludeTerms)) {
|
|
foreach ($excludeTerms as $excludeTerm) {
|
|
$excludes->add(iplFilter::equal('entry_name', $excludeTerm));
|
|
}
|
|
}
|
|
|
|
$suggestions = new SearchSuggestions((function () use ($uuid, $excludes, &$suggestions) {
|
|
foreach ($suggestions->getExcludeTerms() as $excludeTerm) {
|
|
$excludes->add(iplFilter::equal('entry_name', $excludeTerm));
|
|
}
|
|
|
|
$query = $this->db->select()->from(['dle' => 'director_datalist_entry'], ['entry_name', 'entry_value'])
|
|
->join(['dl' => 'director_datalist'], 'dl.id = dle.list_id', [])
|
|
->join(['dpl' => 'director_property_datalist'], 'dl.uuid = dpl.list_uuid', [])
|
|
->where('dpl.property_uuid', $uuid->getBytes());
|
|
|
|
$filterString = QueryString::render(iplFilter::all($excludes));
|
|
if ($filterString !== '') {
|
|
$query->addFilter(Filter::fromQueryString($filterString));
|
|
}
|
|
|
|
foreach ($this->db->fetchPairs($query) as $name => $value) {
|
|
yield [
|
|
'search' => $name,
|
|
'label' => $value,
|
|
'class' => 'list-entry'
|
|
];
|
|
}
|
|
})());
|
|
|
|
$this->getDocument()->addHtml($suggestions->forRequest($this->getServerRequest()));
|
|
}
|
|
}
|