|
5 | 5 | use Icinga\Application\Config; |
6 | 6 | use Icinga\Exception\ConfigurationError; |
7 | 7 | use Icinga\Exception\NotFoundError; |
| 8 | +use Icinga\Module\Director\Daemon\Logger; |
8 | 9 | use Icinga\Module\Director\Db; |
9 | 10 | use Icinga\Module\Director\Db\AppliedServiceSetLoader; |
10 | 11 | use Icinga\Module\Director\Objects\IcingaHost; |
|
22 | 23 | use ipl\Html\Text; |
23 | 24 | use ipl\Html\ValidHtml; |
24 | 25 | use ipl\Orm\Model; |
| 26 | +use Throwable; |
25 | 27 |
|
26 | 28 | class CustomVarRenderer extends CustomVarRendererHook |
27 | 29 | { |
@@ -61,185 +63,208 @@ protected function db(): Db |
61 | 63 |
|
62 | 64 | public function prefetchForObject(Model $object): bool |
63 | 65 | { |
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 | + } |
73 | 76 |
|
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 | + ); |
75 | 110 |
|
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 | + } |
126 | 132 | } |
127 | | - } |
128 | | - } elseif ($serviceOrigin[$i] === 'service-set') { |
129 | | - $templateResolver = new IcingaTemplateResolver($directorHostObj); |
| 133 | + } elseif ($serviceOrigin[$i] === 'service-set') { |
| 134 | + $templateResolver = new IcingaTemplateResolver($directorHostObj); |
130 | 135 |
|
131 | | - $hostServiceSets = $directorHostObj->fetchServiceSets() |
132 | | - + AppliedServiceSetLoader::fetchForHost($directorHostObj); |
| 136 | + $hostServiceSets = $directorHostObj->fetchServiceSets() |
| 137 | + + AppliedServiceSetLoader::fetchForHost($directorHostObj); |
133 | 138 |
|
134 | | - $parents = $templateResolver->fetchParents(); |
| 139 | + $parents = $templateResolver->fetchParents(); |
135 | 140 |
|
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 | + } |
140 | 145 |
|
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; |
145 | 150 |
|
146 | | - break 2; |
| 151 | + break 2; |
| 152 | + } |
147 | 153 | } |
148 | 154 | } |
149 | 155 | } |
150 | | - } |
151 | 156 |
|
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 | + } |
158 | 166 |
|
159 | | - if ($service === null) { |
160 | | - $fields = (new IcingaObjectFieldLoader($directorHostObj))->getFields(); |
161 | | - } else { |
162 | | - $fields = (new IcingaObjectFieldLoader($directorServiceObj))->getFields(); |
163 | | - } |
| 167 | + return false; |
| 168 | + } |
164 | 169 |
|
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 | + } |
168 | 175 |
|
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; |
181 | 178 | } |
182 | | - } |
183 | 179 |
|
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 | + } |
189 | 193 | } |
190 | 194 |
|
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 | + } |
208 | 221 | } |
209 | | - } |
210 | 222 |
|
211 | | - return true; |
| 223 | + return true; |
| 224 | + } catch (Throwable $e) { |
| 225 | + Logger::error("%s\n%s", $e, $e->getTraceAsString()); |
| 226 | + |
| 227 | + return false; |
| 228 | + } |
212 | 229 | } |
213 | 230 |
|
214 | 231 | public function renderCustomVarKey(string $key) |
215 | 232 | { |
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()); |
222 | 243 | } |
223 | 244 |
|
224 | 245 | return null; |
225 | 246 | } |
226 | 247 |
|
227 | 248 | public function renderCustomVarValue(string $key, $value) |
228 | 249 | { |
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 | + } |
233 | 255 |
|
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 | + } |
242 | 265 | } |
| 266 | + } catch (Throwable $e) { |
| 267 | + Logger::error("%s\n%s", $e, $e->getTraceAsString()); |
243 | 268 | } |
244 | 269 |
|
245 | 270 | return null; |
|
0 commit comments