Skip to content

Commit dbacfa2

Browse files
raviks789nilmerg
authored andcommitted
Icingadb/CustomVarRenderer: Add error handling
1 parent 0e74463 commit dbacfa2

File tree

1 file changed

+170
-145
lines changed

1 file changed

+170
-145
lines changed

library/Director/ProvidedHook/Icingadb/CustomVarRenderer.php

Lines changed: 170 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Icinga\Application\Config;
66
use Icinga\Exception\ConfigurationError;
77
use Icinga\Exception\NotFoundError;
8+
use Icinga\Module\Director\Daemon\Logger;
89
use Icinga\Module\Director\Db;
910
use Icinga\Module\Director\Db\AppliedServiceSetLoader;
1011
use Icinga\Module\Director\Objects\IcingaHost;
@@ -22,6 +23,7 @@
2223
use ipl\Html\Text;
2324
use ipl\Html\ValidHtml;
2425
use ipl\Orm\Model;
26+
use Throwable;
2527

2628
class CustomVarRenderer extends CustomVarRendererHook
2729
{
@@ -61,185 +63,208 @@ protected function db(): Db
6163

6264
public function prefetchForObject(Model $object): bool
6365
{
64-
if ($object instanceof Host) {
65-
$host = $object;
66-
$service = null;
67-
} elseif ($object instanceof Service) {
68-
$host = $object->host;
69-
$service = $object;
70-
} else {
71-
return false;
72-
}
66+
try {
67+
if ($object instanceof Host) {
68+
$host = $object;
69+
$service = null;
70+
} elseif ($object instanceof Service) {
71+
$host = $object->host;
72+
$service = $object;
73+
} else {
74+
return false;
75+
}
7376

74-
$db = $this->db();
77+
$db = $this->db();
78+
79+
try {
80+
$directorHostObj = IcingaHost::load($host->name, $db);
81+
$directorServiceObj = null;
82+
if ($service !== null) {
83+
$serviceOrigin = ['direct', 'applied', 'inherited', 'service-set'];
84+
$serviceName = $service->name;
85+
$i = 0;
86+
do {
87+
if ($i > 3) {
88+
Logger::error("Failed to find service '%s' on host '%s'", $serviceName, $host->name);
89+
90+
return false;
91+
} elseif ($serviceOrigin[$i] === 'direct') {
92+
$directorServiceObj = IcingaService::loadOptional([
93+
'host_id' => $directorHostObj->get('id'),
94+
'object_name' => $serviceName
95+
], $db);
96+
} elseif ($serviceOrigin[$i] === 'inherited') {
97+
$templateResolver = new IcingaTemplateResolver($directorHostObj);
98+
99+
$parentIds = $templateResolver->listParentIds();
100+
101+
$query = $db->getDbAdapter()->select()->from('icinga_service')
102+
->where('object_name = ?', $serviceName)
103+
->where('host_id IN (?)', $parentIds);
104+
105+
$directorServices = IcingaService::loadAll(
106+
$db,
107+
$query,
108+
'object_name'
109+
);
75110

76-
try {
77-
$directorHostObj = IcingaHost::load($host->name, $db);
78-
$directorServiceObj = null;
79-
if ($service !== null) {
80-
$serviceOrigin = ['direct', 'applied', 'inherited', 'service-set'];
81-
$serviceName = $service->name;
82-
$i = 0;
83-
do {
84-
if ($i > 3) {
85-
return false;
86-
} elseif ($serviceOrigin[$i] === 'direct') {
87-
$directorServiceObj = IcingaService::loadOptional([
88-
'host_id' => $directorHostObj->get('id'),
89-
'object_name' => $serviceName
90-
], $db);
91-
} elseif ($serviceOrigin[$i] === 'inherited') {
92-
$templateResolver = new IcingaTemplateResolver($directorHostObj);
93-
94-
$parentIds = $templateResolver->listParentIds();
95-
96-
$query = $db->getDbAdapter()->select()->from('icinga_service')
97-
->where('object_name = ?', $serviceName)
98-
->where('host_id IN (?)', $parentIds);
99-
100-
$directorServices = IcingaService::loadAll(
101-
$db,
102-
$query,
103-
'object_name'
104-
);
105-
106-
$directorServiceObj = current($directorServices);
107-
} elseif ($serviceOrigin[$i] === 'applied') {
108-
$appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery();
109-
110-
foreach ($appliedFilterQuery->fetchAll() as $appliedService) {
111-
if ($appliedService->name === $serviceName) {
112-
$query = $db->getDbAdapter()->select()->from('icinga_service')
113-
->where('object_name = ?', $serviceName)
114-
->where("object_type = 'apply'")
115-
->where('assign_filter = ?', $appliedService->assign_filter);
116-
117-
$directorAppliedServices = IcingaService::loadAll(
118-
$db,
119-
$query,
120-
'object_name'
121-
);
122-
123-
$directorServiceObj = current($directorAppliedServices);
124-
125-
break;
111+
$directorServiceObj = current($directorServices);
112+
} elseif ($serviceOrigin[$i] === 'applied') {
113+
$appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery();
114+
115+
foreach ($appliedFilterQuery->fetchAll() as $appliedService) {
116+
if ($appliedService->name === $serviceName) {
117+
$query = $db->getDbAdapter()->select()->from('icinga_service')
118+
->where('object_name = ?', $serviceName)
119+
->where("object_type = 'apply'")
120+
->where('assign_filter = ?', $appliedService->assign_filter);
121+
122+
$directorAppliedServices = IcingaService::loadAll(
123+
$db,
124+
$query,
125+
'object_name'
126+
);
127+
128+
$directorServiceObj = current($directorAppliedServices);
129+
130+
break;
131+
}
126132
}
127-
}
128-
} elseif ($serviceOrigin[$i] === 'service-set') {
129-
$templateResolver = new IcingaTemplateResolver($directorHostObj);
133+
} elseif ($serviceOrigin[$i] === 'service-set') {
134+
$templateResolver = new IcingaTemplateResolver($directorHostObj);
130135

131-
$hostServiceSets = $directorHostObj->fetchServiceSets()
132-
+ AppliedServiceSetLoader::fetchForHost($directorHostObj);
136+
$hostServiceSets = $directorHostObj->fetchServiceSets()
137+
+ AppliedServiceSetLoader::fetchForHost($directorHostObj);
133138

134-
$parents = $templateResolver->fetchParents();
139+
$parents = $templateResolver->fetchParents();
135140

136-
foreach ($parents as $parent) {
137-
$hostServiceSets += $parent->fetchServiceSets();
138-
$hostServiceSets += AppliedServiceSetLoader::fetchForHost($parent);
139-
}
141+
foreach ($parents as $parent) {
142+
$hostServiceSets += $parent->fetchServiceSets();
143+
$hostServiceSets += AppliedServiceSetLoader::fetchForHost($parent);
144+
}
140145

141-
foreach ($hostServiceSets as $hostServiceSet) {
142-
foreach ($hostServiceSet->getServiceObjects() as $setServiceObject) {
143-
if ($setServiceObject->getObjectName() === $serviceName) {
144-
$directorServiceObj = $setServiceObject;
146+
foreach ($hostServiceSets as $hostServiceSet) {
147+
foreach ($hostServiceSet->getServiceObjects() as $setServiceObject) {
148+
if ($setServiceObject->getObjectName() === $serviceName) {
149+
$directorServiceObj = $setServiceObject;
145150

146-
break 2;
151+
break 2;
152+
}
147153
}
148154
}
149155
}
150-
}
151156

152-
$i++;
153-
} while (! $directorServiceObj);
154-
}
155-
} catch (NotFoundError $_) {
156-
return false;
157-
}
157+
$i++;
158+
} while (! $directorServiceObj);
159+
}
160+
} catch (NotFoundError $_) {
161+
if ($service !== null) {
162+
Logger::error("Failed to find service '%s' on host '%s'", $service->name, $host->name);
163+
} else {
164+
Logger::error('Failed to find host %s', $host->name);
165+
}
158166

159-
if ($service === null) {
160-
$fields = (new IcingaObjectFieldLoader($directorHostObj))->getFields();
161-
} else {
162-
$fields = (new IcingaObjectFieldLoader($directorServiceObj))->getFields();
163-
}
167+
return false;
168+
}
164169

165-
if (empty($fields)) {
166-
return false;
167-
}
170+
if ($service === null) {
171+
$fields = (new IcingaObjectFieldLoader($directorHostObj))->getFields();
172+
} else {
173+
$fields = (new IcingaObjectFieldLoader($directorServiceObj))->getFields();
174+
}
168175

169-
$fieldsWithDataLists = [];
170-
foreach ($fields as $field) {
171-
$this->fieldConfig[$field->get('varname')] = [
172-
'label' => $field->get('caption'),
173-
'group' => $field->getCategoryName(),
174-
'visibility' => $field->getSetting('visibility')
175-
];
176-
177-
if ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDatalist') {
178-
$fieldsWithDataLists[$field->get('id')] = $field;
179-
} elseif ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDictionary') {
180-
$this->dictionaryNames[] = $field->get('varname');
176+
if (empty($fields)) {
177+
return false;
181178
}
182-
}
183179

184-
if (! empty($fieldsWithDataLists)) {
185-
if ($this->db()->getDbType() === 'pgsql') {
186-
$joinCondition = 'CAST(dds.setting_value AS INTEGER) = dde.list_id';
187-
} else {
188-
$joinCondition = 'dds.setting_value = dde.list_id';
180+
$fieldsWithDataLists = [];
181+
foreach ($fields as $field) {
182+
$this->fieldConfig[$field->get('varname')] = [
183+
'label' => $field->get('caption'),
184+
'group' => $field->getCategoryName(),
185+
'visibility' => $field->getSetting('visibility')
186+
];
187+
188+
if ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDatalist') {
189+
$fieldsWithDataLists[$field->get('id')] = $field;
190+
} elseif ($field->get('datatype') === 'Icinga\Module\Director\DataType\DataTypeDictionary') {
191+
$this->dictionaryNames[] = $field->get('varname');
192+
}
189193
}
190194

191-
$dataListEntries = $db->select()->from(
192-
['dds' => 'director_datafield_setting'],
193-
[
194-
'dds.datafield_id',
195-
'dde.entry_name',
196-
'dde.entry_value'
197-
]
198-
)->join(
199-
['dde' => 'director_datalist_entry'],
200-
$joinCondition,
201-
[]
202-
)->where('dds.datafield_id', array_keys($fieldsWithDataLists))
203-
->where('dds.setting_name', 'datalist_id');
204-
205-
foreach ($dataListEntries as $dataListEntry) {
206-
$field = $fieldsWithDataLists[$dataListEntry->datafield_id];
207-
$this->datalistMaps[$field->get('varname')][$dataListEntry->entry_name] = $dataListEntry->entry_value;
195+
if (! empty($fieldsWithDataLists)) {
196+
if ($this->db()->getDbType() === 'pgsql') {
197+
$joinCondition = 'CAST(dds.setting_value AS INTEGER) = dde.list_id';
198+
} else {
199+
$joinCondition = 'dds.setting_value = dde.list_id';
200+
}
201+
202+
$dataListEntries = $db->select()->from(
203+
['dds' => 'director_datafield_setting'],
204+
[
205+
'dds.datafield_id',
206+
'dde.entry_name',
207+
'dde.entry_value'
208+
]
209+
)->join(
210+
['dde' => 'director_datalist_entry'],
211+
$joinCondition,
212+
[]
213+
)->where('dds.datafield_id', array_keys($fieldsWithDataLists))
214+
->where('dds.setting_name', 'datalist_id');
215+
216+
foreach ($dataListEntries as $dataListEntry) {
217+
$field = $fieldsWithDataLists[$dataListEntry->datafield_id];
218+
$this->datalistMaps[$field->get('varname')][$dataListEntry->entry_name]
219+
= $dataListEntry->entry_value;
220+
}
208221
}
209-
}
210222

211-
return true;
223+
return true;
224+
} catch (Throwable $e) {
225+
Logger::error("%s\n%s", $e, $e->getTraceAsString());
226+
227+
return false;
228+
}
212229
}
213230

214231
public function renderCustomVarKey(string $key)
215232
{
216-
if (isset($this->fieldConfig[$key]['label'])) {
217-
return new HtmlElement(
218-
'span',
219-
Attributes::create(['title' => $this->fieldConfig[$key]['label'] . " [$key]"]),
220-
Text::create($this->fieldConfig[$key]['label'])
221-
);
233+
try {
234+
if (isset($this->fieldConfig[$key]['label'])) {
235+
return new HtmlElement(
236+
'span',
237+
Attributes::create(['title' => $this->fieldConfig[$key]['label'] . " [$key]"]),
238+
Text::create($this->fieldConfig[$key]['label'])
239+
);
240+
}
241+
} catch (Throwable $e) {
242+
Logger::error("%s\n%s", $e, $e->getTraceAsString());
222243
}
223244

224245
return null;
225246
}
226247

227248
public function renderCustomVarValue(string $key, $value)
228249
{
229-
if (isset($this->fieldConfig[$key])) {
230-
if ($this->fieldConfig[$key]['visibility'] === 'hidden') {
231-
return '***';
232-
}
250+
try {
251+
if (isset($this->fieldConfig[$key])) {
252+
if ($this->fieldConfig[$key]['visibility'] === 'hidden') {
253+
return '***';
254+
}
233255

234-
if (isset($this->datalistMaps[$key][$value])) {
235-
return new HtmlElement(
236-
'span',
237-
Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]),
238-
Text::create($this->datalistMaps[$key][$value])
239-
);
240-
} elseif ($value !== null && in_array($key, $this->dictionaryNames)) {
241-
return $this->renderDictionaryVal($key, (array) $value);
256+
if (isset($this->datalistMaps[$key][$value])) {
257+
return new HtmlElement(
258+
'span',
259+
Attributes::create(['title' => $this->datalistMaps[$key][$value] . " [$value]"]),
260+
Text::create($this->datalistMaps[$key][$value])
261+
);
262+
} elseif ($value !== null && in_array($key, $this->dictionaryNames)) {
263+
return $this->renderDictionaryVal($key, (array) $value);
264+
}
242265
}
266+
} catch (Throwable $e) {
267+
Logger::error("%s\n%s", $e, $e->getTraceAsString());
243268
}
244269

245270
return null;

0 commit comments

Comments
 (0)