mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-09-25 10:57:41 +02:00
Icingadb/CustomVarRenderer: Add error handling
This commit is contained in:
parent
0e744630d7
commit
dbacfa21c0
@ -5,6 +5,7 @@ namespace Icinga\Module\Director\ProvidedHook\Icingadb;
|
|||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
use Icinga\Exception\NotFoundError;
|
use Icinga\Exception\NotFoundError;
|
||||||
|
use Icinga\Module\Director\Daemon\Logger;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
use Icinga\Module\Director\Db\AppliedServiceSetLoader;
|
use Icinga\Module\Director\Db\AppliedServiceSetLoader;
|
||||||
use Icinga\Module\Director\Objects\IcingaHost;
|
use Icinga\Module\Director\Objects\IcingaHost;
|
||||||
@ -22,6 +23,7 @@ use ipl\Html\HtmlElement;
|
|||||||
use ipl\Html\Text;
|
use ipl\Html\Text;
|
||||||
use ipl\Html\ValidHtml;
|
use ipl\Html\ValidHtml;
|
||||||
use ipl\Orm\Model;
|
use ipl\Orm\Model;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
class CustomVarRenderer extends CustomVarRendererHook
|
class CustomVarRenderer extends CustomVarRendererHook
|
||||||
{
|
{
|
||||||
@ -61,164 +63,183 @@ class CustomVarRenderer extends CustomVarRendererHook
|
|||||||
|
|
||||||
public function prefetchForObject(Model $object): bool
|
public function prefetchForObject(Model $object): bool
|
||||||
{
|
{
|
||||||
if ($object instanceof Host) {
|
|
||||||
$host = $object;
|
|
||||||
$service = null;
|
|
||||||
} elseif ($object instanceof Service) {
|
|
||||||
$host = $object->host;
|
|
||||||
$service = $object;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$db = $this->db();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$directorHostObj = IcingaHost::load($host->name, $db);
|
if ($object instanceof Host) {
|
||||||
$directorServiceObj = null;
|
$host = $object;
|
||||||
if ($service !== null) {
|
$service = null;
|
||||||
$serviceOrigin = ['direct', 'applied', 'inherited', 'service-set'];
|
} elseif ($object instanceof Service) {
|
||||||
$serviceName = $service->name;
|
$host = $object->host;
|
||||||
$i = 0;
|
$service = $object;
|
||||||
do {
|
} else {
|
||||||
if ($i > 3) {
|
return false;
|
||||||
return false;
|
}
|
||||||
} elseif ($serviceOrigin[$i] === 'direct') {
|
|
||||||
$directorServiceObj = IcingaService::loadOptional([
|
|
||||||
'host_id' => $directorHostObj->get('id'),
|
|
||||||
'object_name' => $serviceName
|
|
||||||
], $db);
|
|
||||||
} elseif ($serviceOrigin[$i] === 'inherited') {
|
|
||||||
$templateResolver = new IcingaTemplateResolver($directorHostObj);
|
|
||||||
|
|
||||||
$parentIds = $templateResolver->listParentIds();
|
$db = $this->db();
|
||||||
|
|
||||||
$query = $db->getDbAdapter()->select()->from('icinga_service')
|
try {
|
||||||
->where('object_name = ?', $serviceName)
|
$directorHostObj = IcingaHost::load($host->name, $db);
|
||||||
->where('host_id IN (?)', $parentIds);
|
$directorServiceObj = null;
|
||||||
|
if ($service !== null) {
|
||||||
|
$serviceOrigin = ['direct', 'applied', 'inherited', 'service-set'];
|
||||||
|
$serviceName = $service->name;
|
||||||
|
$i = 0;
|
||||||
|
do {
|
||||||
|
if ($i > 3) {
|
||||||
|
Logger::error("Failed to find service '%s' on host '%s'", $serviceName, $host->name);
|
||||||
|
|
||||||
$directorServices = IcingaService::loadAll(
|
return false;
|
||||||
$db,
|
} elseif ($serviceOrigin[$i] === 'direct') {
|
||||||
$query,
|
$directorServiceObj = IcingaService::loadOptional([
|
||||||
'object_name'
|
'host_id' => $directorHostObj->get('id'),
|
||||||
);
|
'object_name' => $serviceName
|
||||||
|
], $db);
|
||||||
|
} elseif ($serviceOrigin[$i] === 'inherited') {
|
||||||
|
$templateResolver = new IcingaTemplateResolver($directorHostObj);
|
||||||
|
|
||||||
$directorServiceObj = current($directorServices);
|
$parentIds = $templateResolver->listParentIds();
|
||||||
} elseif ($serviceOrigin[$i] === 'applied') {
|
|
||||||
$appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery();
|
|
||||||
|
|
||||||
foreach ($appliedFilterQuery->fetchAll() as $appliedService) {
|
$query = $db->getDbAdapter()->select()->from('icinga_service')
|
||||||
if ($appliedService->name === $serviceName) {
|
->where('object_name = ?', $serviceName)
|
||||||
$query = $db->getDbAdapter()->select()->from('icinga_service')
|
->where('host_id IN (?)', $parentIds);
|
||||||
->where('object_name = ?', $serviceName)
|
|
||||||
->where("object_type = 'apply'")
|
|
||||||
->where('assign_filter = ?', $appliedService->assign_filter);
|
|
||||||
|
|
||||||
$directorAppliedServices = IcingaService::loadAll(
|
$directorServices = IcingaService::loadAll(
|
||||||
$db,
|
$db,
|
||||||
$query,
|
$query,
|
||||||
'object_name'
|
'object_name'
|
||||||
);
|
);
|
||||||
|
|
||||||
$directorServiceObj = current($directorAppliedServices);
|
$directorServiceObj = current($directorServices);
|
||||||
|
} elseif ($serviceOrigin[$i] === 'applied') {
|
||||||
|
$appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery();
|
||||||
|
|
||||||
break;
|
foreach ($appliedFilterQuery->fetchAll() as $appliedService) {
|
||||||
|
if ($appliedService->name === $serviceName) {
|
||||||
|
$query = $db->getDbAdapter()->select()->from('icinga_service')
|
||||||
|
->where('object_name = ?', $serviceName)
|
||||||
|
->where("object_type = 'apply'")
|
||||||
|
->where('assign_filter = ?', $appliedService->assign_filter);
|
||||||
|
|
||||||
|
$directorAppliedServices = IcingaService::loadAll(
|
||||||
|
$db,
|
||||||
|
$query,
|
||||||
|
'object_name'
|
||||||
|
);
|
||||||
|
|
||||||
|
$directorServiceObj = current($directorAppliedServices);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} elseif ($serviceOrigin[$i] === 'service-set') {
|
||||||
} elseif ($serviceOrigin[$i] === 'service-set') {
|
$templateResolver = new IcingaTemplateResolver($directorHostObj);
|
||||||
$templateResolver = new IcingaTemplateResolver($directorHostObj);
|
|
||||||
|
|
||||||
$hostServiceSets = $directorHostObj->fetchServiceSets()
|
$hostServiceSets = $directorHostObj->fetchServiceSets()
|
||||||
+ AppliedServiceSetLoader::fetchForHost($directorHostObj);
|
+ AppliedServiceSetLoader::fetchForHost($directorHostObj);
|
||||||
|
|
||||||
$parents = $templateResolver->fetchParents();
|
$parents = $templateResolver->fetchParents();
|
||||||
|
|
||||||
foreach ($parents as $parent) {
|
foreach ($parents as $parent) {
|
||||||
$hostServiceSets += $parent->fetchServiceSets();
|
$hostServiceSets += $parent->fetchServiceSets();
|
||||||
$hostServiceSets += AppliedServiceSetLoader::fetchForHost($parent);
|
$hostServiceSets += AppliedServiceSetLoader::fetchForHost($parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($hostServiceSets as $hostServiceSet) {
|
foreach ($hostServiceSets as $hostServiceSet) {
|
||||||
foreach ($hostServiceSet->getServiceObjects() as $setServiceObject) {
|
foreach ($hostServiceSet->getServiceObjects() as $setServiceObject) {
|
||||||
if ($setServiceObject->getObjectName() === $serviceName) {
|
if ($setServiceObject->getObjectName() === $serviceName) {
|
||||||
$directorServiceObj = $setServiceObject;
|
$directorServiceObj = $setServiceObject;
|
||||||
|
|
||||||
break 2;
|
break 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$i++;
|
$i++;
|
||||||
} while (! $directorServiceObj);
|
} while (! $directorServiceObj);
|
||||||
|
}
|
||||||
|
} catch (NotFoundError $_) {
|
||||||
|
if ($service !== null) {
|
||||||
|
Logger::error("Failed to find service '%s' on host '%s'", $service->name, $host->name);
|
||||||
|
} else {
|
||||||
|
Logger::error('Failed to find host %s', $host->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} catch (NotFoundError $_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($service === null) {
|
if ($service === null) {
|
||||||
$fields = (new IcingaObjectFieldLoader($directorHostObj))->getFields();
|
$fields = (new IcingaObjectFieldLoader($directorHostObj))->getFields();
|
||||||
} else {
|
|
||||||
$fields = (new IcingaObjectFieldLoader($directorServiceObj))->getFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($fields)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fieldsWithDataLists = [];
|
|
||||||
foreach ($fields as $field) {
|
|
||||||
$this->fieldConfig[$field->get('varname')] = [
|
|
||||||
'label' => $field->get('caption'),
|
|
||||||
'group' => $field->getCategoryName(),
|
|
||||||
'visibility' => $field->getSetting('visibility')
|
|
||||||
];
|
|
||||||
|
|
||||||
if ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDatalist') {
|
|
||||||
$fieldsWithDataLists[$field->get('id')] = $field;
|
|
||||||
} elseif ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDictionary') {
|
|
||||||
$this->dictionaryNames[] = $field->get('varname');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! empty($fieldsWithDataLists)) {
|
|
||||||
if ($this->db()->getDbType() === 'pgsql') {
|
|
||||||
$joinCondition = 'CAST(dds.setting_value AS INTEGER) = dde.list_id';
|
|
||||||
} else {
|
} else {
|
||||||
$joinCondition = 'dds.setting_value = dde.list_id';
|
$fields = (new IcingaObjectFieldLoader($directorServiceObj))->getFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
$dataListEntries = $db->select()->from(
|
if (empty($fields)) {
|
||||||
['dds' => 'director_datafield_setting'],
|
return false;
|
||||||
[
|
|
||||||
'dds.datafield_id',
|
|
||||||
'dde.entry_name',
|
|
||||||
'dde.entry_value'
|
|
||||||
]
|
|
||||||
)->join(
|
|
||||||
['dde' => 'director_datalist_entry'],
|
|
||||||
$joinCondition,
|
|
||||||
[]
|
|
||||||
)->where('dds.datafield_id', array_keys($fieldsWithDataLists))
|
|
||||||
->where('dds.setting_name', 'datalist_id');
|
|
||||||
|
|
||||||
foreach ($dataListEntries as $dataListEntry) {
|
|
||||||
$field = $fieldsWithDataLists[$dataListEntry->datafield_id];
|
|
||||||
$this->datalistMaps[$field->get('varname')][$dataListEntry->entry_name] = $dataListEntry->entry_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$fieldsWithDataLists = [];
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$this->fieldConfig[$field->get('varname')] = [
|
||||||
|
'label' => $field->get('caption'),
|
||||||
|
'group' => $field->getCategoryName(),
|
||||||
|
'visibility' => $field->getSetting('visibility')
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDatalist') {
|
||||||
|
$fieldsWithDataLists[$field->get('id')] = $field;
|
||||||
|
} elseif ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDictionary') {
|
||||||
|
$this->dictionaryNames[] = $field->get('varname');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! empty($fieldsWithDataLists)) {
|
||||||
|
if ($this->db()->getDbType() === 'pgsql') {
|
||||||
|
$joinCondition = 'CAST(dds.setting_value AS INTEGER) = dde.list_id';
|
||||||
|
} else {
|
||||||
|
$joinCondition = 'dds.setting_value = dde.list_id';
|
||||||
|
}
|
||||||
|
|
||||||
|
$dataListEntries = $db->select()->from(
|
||||||
|
['dds' => 'director_datafield_setting'],
|
||||||
|
[
|
||||||
|
'dds.datafield_id',
|
||||||
|
'dde.entry_name',
|
||||||
|
'dde.entry_value'
|
||||||
|
]
|
||||||
|
)->join(
|
||||||
|
['dde' => 'director_datalist_entry'],
|
||||||
|
$joinCondition,
|
||||||
|
[]
|
||||||
|
)->where('dds.datafield_id', array_keys($fieldsWithDataLists))
|
||||||
|
->where('dds.setting_name', 'datalist_id');
|
||||||
|
|
||||||
|
foreach ($dataListEntries as $dataListEntry) {
|
||||||
|
$field = $fieldsWithDataLists[$dataListEntry->datafield_id];
|
||||||
|
$this->datalistMaps[$field->get('varname')][$dataListEntry->entry_name]
|
||||||
|
= $dataListEntry->entry_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
Logger::error("%s\n%s", $e, $e->getTraceAsString());
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderCustomVarKey(string $key)
|
public function renderCustomVarKey(string $key)
|
||||||
{
|
{
|
||||||
if (isset($this->fieldConfig[$key]['label'])) {
|
try {
|
||||||
return new HtmlElement(
|
if (isset($this->fieldConfig[$key]['label'])) {
|
||||||
'span',
|
return new HtmlElement(
|
||||||
Attributes::create(['title' => $this->fieldConfig[$key]['label'] . " [$key]"]),
|
'span',
|
||||||
Text::create($this->fieldConfig[$key]['label'])
|
Attributes::create(['title' => $this->fieldConfig[$key]['label'] . " [$key]"]),
|
||||||
);
|
Text::create($this->fieldConfig[$key]['label'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
Logger::error("%s\n%s", $e, $e->getTraceAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -226,20 +247,24 @@ class CustomVarRenderer extends CustomVarRendererHook
|
|||||||
|
|
||||||
public function renderCustomVarValue(string $key, $value)
|
public function renderCustomVarValue(string $key, $value)
|
||||||
{
|
{
|
||||||
if (isset($this->fieldConfig[$key])) {
|
try {
|
||||||
if ($this->fieldConfig[$key]['visibility'] === 'hidden') {
|
if (isset($this->fieldConfig[$key])) {
|
||||||
return '***';
|
if ($this->fieldConfig[$key]['visibility'] === 'hidden') {
|
||||||
}
|
return '***';
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($this->datalistMaps[$key][$value])) {
|
if (isset($this->datalistMaps[$key][$value])) {
|
||||||
return new HtmlElement(
|
return new HtmlElement(
|
||||||
'span',
|
'span',
|
||||||
Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]),
|
Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]),
|
||||||
Text::create($this->datalistMaps[$key][$value])
|
Text::create($this->datalistMaps[$key][$value])
|
||||||
);
|
);
|
||||||
} elseif ($value !== null && in_array($key, $this->dictionaryNames)) {
|
} elseif ($value !== null && in_array($key, $this->dictionaryNames)) {
|
||||||
return $this->renderDictionaryVal($key, (array) $value);
|
return $this->renderDictionaryVal($key, (array) $value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
Logger::error("%s\n%s", $e, $e->getTraceAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user