1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2 
3 #include "livestatus/hoststable.hpp"
4 #include "livestatus/hostgroupstable.hpp"
5 #include "livestatus/endpointstable.hpp"
6 #include "icinga/host.hpp"
7 #include "icinga/service.hpp"
8 #include "icinga/hostgroup.hpp"
9 #include "icinga/checkcommand.hpp"
10 #include "icinga/eventcommand.hpp"
11 #include "icinga/timeperiod.hpp"
12 #include "icinga/macroprocessor.hpp"
13 #include "icinga/icingaapplication.hpp"
14 #include "icinga/compatutility.hpp"
15 #include "icinga/pluginutility.hpp"
16 #include "base/configtype.hpp"
17 #include "base/objectlock.hpp"
18 #include "base/json.hpp"
19 #include "base/convert.hpp"
20 #include "base/utility.hpp"
21 #include <boost/algorithm/string/replace.hpp>
22 
23 using namespace icinga;
24 
HostsTable(LivestatusGroupByType type)25 HostsTable::HostsTable(LivestatusGroupByType type)
26 	:Table(type)
27 {
28 	AddColumns(this);
29 }
30 
AddColumns(Table * table,const String & prefix,const Column::ObjectAccessor & objectAccessor)31 void HostsTable::AddColumns(Table *table, const String& prefix,
32 	const Column::ObjectAccessor& objectAccessor)
33 {
34 	table->AddColumn(prefix + "name", Column(&HostsTable::NameAccessor, objectAccessor));
35 	table->AddColumn(prefix + "host_name", Column(&HostsTable::NameAccessor, objectAccessor)); //ugly compatibility hack
36 	table->AddColumn(prefix + "display_name", Column(&HostsTable::DisplayNameAccessor, objectAccessor));
37 	table->AddColumn(prefix + "alias", Column(&HostsTable::DisplayNameAccessor, objectAccessor));
38 	table->AddColumn(prefix + "address", Column(&HostsTable::AddressAccessor, objectAccessor));
39 	table->AddColumn(prefix + "address6", Column(&HostsTable::Address6Accessor, objectAccessor));
40 	table->AddColumn(prefix + "check_command", Column(&HostsTable::CheckCommandAccessor, objectAccessor));
41 	table->AddColumn(prefix + "check_command_expanded", Column(&HostsTable::CheckCommandExpandedAccessor, objectAccessor));
42 	table->AddColumn(prefix + "event_handler", Column(&HostsTable::EventHandlerAccessor, objectAccessor));
43 	table->AddColumn(prefix + "notification_period", Column(&Table::EmptyStringAccessor, objectAccessor));
44 	table->AddColumn(prefix + "check_period", Column(&HostsTable::CheckPeriodAccessor, objectAccessor));
45 	table->AddColumn(prefix + "notes", Column(&HostsTable::NotesAccessor, objectAccessor));
46 	table->AddColumn(prefix + "notes_expanded", Column(&HostsTable::NotesExpandedAccessor, objectAccessor));
47 	table->AddColumn(prefix + "notes_url", Column(&HostsTable::NotesUrlAccessor, objectAccessor));
48 	table->AddColumn(prefix + "notes_url_expanded", Column(&HostsTable::NotesUrlExpandedAccessor, objectAccessor));
49 	table->AddColumn(prefix + "action_url", Column(&HostsTable::ActionUrlAccessor, objectAccessor));
50 	table->AddColumn(prefix + "action_url_expanded", Column(&HostsTable::ActionUrlExpandedAccessor, objectAccessor));
51 	table->AddColumn(prefix + "plugin_output", Column(&HostsTable::PluginOutputAccessor, objectAccessor));
52 	table->AddColumn(prefix + "perf_data", Column(&HostsTable::PerfDataAccessor, objectAccessor));
53 	table->AddColumn(prefix + "icon_image", Column(&HostsTable::IconImageAccessor, objectAccessor));
54 	table->AddColumn(prefix + "icon_image_expanded", Column(&HostsTable::IconImageExpandedAccessor, objectAccessor));
55 	table->AddColumn(prefix + "icon_image_alt", Column(&HostsTable::IconImageAltAccessor, objectAccessor));
56 	table->AddColumn(prefix + "statusmap_image", Column(&Table::EmptyStringAccessor, objectAccessor));
57 	table->AddColumn(prefix + "long_plugin_output", Column(&HostsTable::LongPluginOutputAccessor, objectAccessor));
58 	table->AddColumn(prefix + "initial_state", Column(&Table::EmptyStringAccessor, objectAccessor));
59 	table->AddColumn(prefix + "max_check_attempts", Column(&HostsTable::MaxCheckAttemptsAccessor, objectAccessor));
60 	table->AddColumn(prefix + "flap_detection_enabled", Column(&HostsTable::FlapDetectionEnabledAccessor, objectAccessor));
61 	table->AddColumn(prefix + "check_freshness", Column(&Table::OneAccessor, objectAccessor));
62 	table->AddColumn(prefix + "process_performance_data", Column(&HostsTable::ProcessPerformanceDataAccessor, objectAccessor));
63 	table->AddColumn(prefix + "accept_passive_checks", Column(&HostsTable::AcceptPassiveChecksAccessor, objectAccessor));
64 	table->AddColumn(prefix + "event_handler_enabled", Column(&HostsTable::EventHandlerEnabledAccessor, objectAccessor));
65 	table->AddColumn(prefix + "acknowledgement_type", Column(&HostsTable::AcknowledgementTypeAccessor, objectAccessor));
66 	table->AddColumn(prefix + "check_type", Column(&HostsTable::CheckTypeAccessor, objectAccessor));
67 	table->AddColumn(prefix + "last_state", Column(&HostsTable::LastStateAccessor, objectAccessor));
68 	table->AddColumn(prefix + "last_hard_state", Column(&HostsTable::LastHardStateAccessor, objectAccessor));
69 	table->AddColumn(prefix + "current_attempt", Column(&HostsTable::CurrentAttemptAccessor, objectAccessor));
70 	table->AddColumn(prefix + "last_notification", Column(&HostsTable::LastNotificationAccessor, objectAccessor));
71 	table->AddColumn(prefix + "next_notification", Column(&HostsTable::NextNotificationAccessor, objectAccessor));
72 	table->AddColumn(prefix + "next_check", Column(&HostsTable::NextCheckAccessor, objectAccessor));
73 	table->AddColumn(prefix + "last_hard_state_change", Column(&HostsTable::LastHardStateChangeAccessor, objectAccessor));
74 	table->AddColumn(prefix + "has_been_checked", Column(&HostsTable::HasBeenCheckedAccessor, objectAccessor));
75 	table->AddColumn(prefix + "current_notification_number", Column(&HostsTable::CurrentNotificationNumberAccessor, objectAccessor));
76 	table->AddColumn(prefix + "pending_flex_downtime", Column(&Table::ZeroAccessor, objectAccessor));
77 	table->AddColumn(prefix + "total_services", Column(&HostsTable::TotalServicesAccessor, objectAccessor));
78 	table->AddColumn(prefix + "checks_enabled", Column(&HostsTable::ChecksEnabledAccessor, objectAccessor));
79 	table->AddColumn(prefix + "notifications_enabled", Column(&HostsTable::NotificationsEnabledAccessor, objectAccessor));
80 	table->AddColumn(prefix + "acknowledged", Column(&HostsTable::AcknowledgedAccessor, objectAccessor));
81 	table->AddColumn(prefix + "state", Column(&HostsTable::StateAccessor, objectAccessor));
82 	table->AddColumn(prefix + "state_type", Column(&HostsTable::StateTypeAccessor, objectAccessor));
83 	table->AddColumn(prefix + "no_more_notifications", Column(&HostsTable::NoMoreNotificationsAccessor, objectAccessor));
84 	table->AddColumn(prefix + "check_flapping_recovery_notification", Column(&Table::ZeroAccessor, objectAccessor));
85 	table->AddColumn(prefix + "last_check", Column(&HostsTable::LastCheckAccessor, objectAccessor));
86 	table->AddColumn(prefix + "last_state_change", Column(&HostsTable::LastStateChangeAccessor, objectAccessor));
87 	table->AddColumn(prefix + "last_time_up", Column(&HostsTable::LastTimeUpAccessor, objectAccessor));
88 	table->AddColumn(prefix + "last_time_down", Column(&HostsTable::LastTimeDownAccessor, objectAccessor));
89 	table->AddColumn(prefix + "last_time_unreachable", Column(&HostsTable::LastTimeUnreachableAccessor, objectAccessor));
90 	table->AddColumn(prefix + "is_flapping", Column(&HostsTable::IsFlappingAccessor, objectAccessor));
91 	table->AddColumn(prefix + "scheduled_downtime_depth", Column(&HostsTable::ScheduledDowntimeDepthAccessor, objectAccessor));
92 	table->AddColumn(prefix + "is_executing", Column(&Table::ZeroAccessor, objectAccessor));
93 	table->AddColumn(prefix + "active_checks_enabled", Column(&HostsTable::ActiveChecksEnabledAccessor, objectAccessor));
94 	table->AddColumn(prefix + "check_options", Column(&Table::EmptyStringAccessor, objectAccessor));
95 	table->AddColumn(prefix + "obsess_over_host", Column(&Table::ZeroAccessor, objectAccessor));
96 	table->AddColumn(prefix + "modified_attributes", Column(&Table::ZeroAccessor, objectAccessor));
97 	table->AddColumn(prefix + "modified_attributes_list", Column(&Table::ZeroAccessor, objectAccessor));
98 	table->AddColumn(prefix + "check_interval", Column(&HostsTable::CheckIntervalAccessor, objectAccessor));
99 	table->AddColumn(prefix + "retry_interval", Column(&HostsTable::RetryIntervalAccessor, objectAccessor));
100 	table->AddColumn(prefix + "notification_interval", Column(&HostsTable::NotificationIntervalAccessor, objectAccessor));
101 	table->AddColumn(prefix + "first_notification_delay", Column(&Table::EmptyStringAccessor, objectAccessor));
102 	table->AddColumn(prefix + "low_flap_threshold", Column(&HostsTable::LowFlapThresholdAccessor, objectAccessor));
103 	table->AddColumn(prefix + "high_flap_threshold", Column(&HostsTable::HighFlapThresholdAccessor, objectAccessor));
104 	table->AddColumn(prefix + "x_3d", Column(&EmptyStringAccessor, objectAccessor));
105 	table->AddColumn(prefix + "y_3d", Column(&EmptyStringAccessor, objectAccessor));
106 	table->AddColumn(prefix + "z_3d", Column(&EmptyStringAccessor, objectAccessor));
107 	table->AddColumn(prefix + "x_2d", Column(&Table::EmptyStringAccessor, objectAccessor));
108 	table->AddColumn(prefix + "y_2d", Column(&Table::EmptyStringAccessor, objectAccessor));
109 	table->AddColumn(prefix + "latency", Column(&HostsTable::LatencyAccessor, objectAccessor));
110 	table->AddColumn(prefix + "execution_time", Column(&HostsTable::ExecutionTimeAccessor, objectAccessor));
111 	table->AddColumn(prefix + "percent_state_change", Column(&HostsTable::PercentStateChangeAccessor, objectAccessor));
112 	table->AddColumn(prefix + "in_notification_period", Column(&HostsTable::InNotificationPeriodAccessor, objectAccessor));
113 	table->AddColumn(prefix + "in_check_period", Column(&HostsTable::InCheckPeriodAccessor, objectAccessor));
114 	table->AddColumn(prefix + "contacts", Column(&HostsTable::ContactsAccessor, objectAccessor));
115 	table->AddColumn(prefix + "downtimes", Column(&HostsTable::DowntimesAccessor, objectAccessor));
116 	table->AddColumn(prefix + "downtimes_with_info", Column(&HostsTable::DowntimesWithInfoAccessor, objectAccessor));
117 	table->AddColumn(prefix + "comments", Column(&HostsTable::CommentsAccessor, objectAccessor));
118 	table->AddColumn(prefix + "comments_with_info", Column(&HostsTable::CommentsWithInfoAccessor, objectAccessor));
119 	table->AddColumn(prefix + "comments_with_extra_info", Column(&HostsTable::CommentsWithExtraInfoAccessor, objectAccessor));
120 	table->AddColumn(prefix + "custom_variable_names", Column(&HostsTable::CustomVariableNamesAccessor, objectAccessor));
121 	table->AddColumn(prefix + "custom_variable_values", Column(&HostsTable::CustomVariableValuesAccessor, objectAccessor));
122 	table->AddColumn(prefix + "custom_variables", Column(&HostsTable::CustomVariablesAccessor, objectAccessor));
123 	table->AddColumn(prefix + "filename", Column(&Table::EmptyStringAccessor, objectAccessor));
124 	table->AddColumn(prefix + "parents", Column(&HostsTable::ParentsAccessor, objectAccessor));
125 	table->AddColumn(prefix + "childs", Column(&HostsTable::ChildsAccessor, objectAccessor));
126 	table->AddColumn(prefix + "num_services", Column(&HostsTable::NumServicesAccessor, objectAccessor));
127 	table->AddColumn(prefix + "worst_service_state", Column(&HostsTable::WorstServiceStateAccessor, objectAccessor));
128 	table->AddColumn(prefix + "num_services_ok", Column(&HostsTable::NumServicesOkAccessor, objectAccessor));
129 	table->AddColumn(prefix + "num_services_warn", Column(&HostsTable::NumServicesWarnAccessor, objectAccessor));
130 	table->AddColumn(prefix + "num_services_crit", Column(&HostsTable::NumServicesCritAccessor, objectAccessor));
131 	table->AddColumn(prefix + "num_services_unknown", Column(&HostsTable::NumServicesUnknownAccessor, objectAccessor));
132 	table->AddColumn(prefix + "num_services_pending", Column(&HostsTable::NumServicesPendingAccessor, objectAccessor));
133 	table->AddColumn(prefix + "worst_service_hard_state", Column(&HostsTable::WorstServiceHardStateAccessor, objectAccessor));
134 	table->AddColumn(prefix + "num_services_hard_ok", Column(&HostsTable::NumServicesHardOkAccessor, objectAccessor));
135 	table->AddColumn(prefix + "num_services_hard_warn", Column(&HostsTable::NumServicesHardWarnAccessor, objectAccessor));
136 	table->AddColumn(prefix + "num_services_hard_crit", Column(&HostsTable::NumServicesHardCritAccessor, objectAccessor));
137 	table->AddColumn(prefix + "num_services_hard_unknown", Column(&HostsTable::NumServicesHardUnknownAccessor, objectAccessor));
138 	table->AddColumn(prefix + "hard_state", Column(&HostsTable::HardStateAccessor, objectAccessor));
139 	table->AddColumn(prefix + "pnpgraph_present", Column(&Table::ZeroAccessor, objectAccessor));
140 	table->AddColumn(prefix + "staleness", Column(&HostsTable::StalenessAccessor, objectAccessor));
141 	table->AddColumn(prefix + "groups", Column(&HostsTable::GroupsAccessor, objectAccessor));
142 	table->AddColumn(prefix + "contact_groups", Column(&HostsTable::ContactGroupsAccessor, objectAccessor));
143 	table->AddColumn(prefix + "services", Column(&HostsTable::ServicesAccessor, objectAccessor));
144 	table->AddColumn(prefix + "services_with_state", Column(&HostsTable::ServicesWithStateAccessor, objectAccessor));
145 	table->AddColumn(prefix + "services_with_info", Column(&HostsTable::ServicesWithInfoAccessor, objectAccessor));
146 	table->AddColumn(prefix + "check_source", Column(&HostsTable::CheckSourceAccessor, objectAccessor));
147 	table->AddColumn(prefix + "is_reachable", Column(&HostsTable::IsReachableAccessor, objectAccessor));
148 	table->AddColumn(prefix + "cv_is_json", Column(&HostsTable::CVIsJsonAccessor, objectAccessor));
149 	table->AddColumn(prefix + "original_attributes", Column(&HostsTable::OriginalAttributesAccessor, objectAccessor));
150 
151 	/* add additional group by values received through the object accessor */
152 	if (table->GetGroupByType() == LivestatusGroupByHostGroup) {
153 		/* _1 = row, _2 = groupByType, _3 = groupByObject */
154 		Log(LogDebug, "Livestatus")
155 			<< "Processing hosts group by hostgroup table.";
156 		HostGroupsTable::AddColumns(table, "hostgroup_", [](const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject) -> Value {
157 			return HostGroupAccessor(row, groupByType, groupByObject);
158 		});
159 	}
160 }
161 
GetName() const162 String HostsTable::GetName() const
163 {
164 	return "hosts";
165 }
166 
GetPrefix() const167 String HostsTable::GetPrefix() const
168 {
169 	return "host";
170 }
171 
FetchRows(const AddRowFunction & addRowFn)172 void HostsTable::FetchRows(const AddRowFunction& addRowFn)
173 {
174 	if (GetGroupByType() == LivestatusGroupByHostGroup) {
175 		for (const HostGroup::Ptr& hg : ConfigType::GetObjectsByType<HostGroup>()) {
176 			for (const Host::Ptr& host : hg->GetMembers()) {
177 				/* the caller must know which groupby type and value are set for this row */
178 				if (!addRowFn(host, LivestatusGroupByHostGroup, hg))
179 					return;
180 			}
181 		}
182 	} else {
183 		for (const Host::Ptr& host : ConfigType::GetObjectsByType<Host>()) {
184 			if (!addRowFn(host, LivestatusGroupByNone, Empty))
185 				return;
186 		}
187 	}
188 }
189 
HostGroupAccessor(const Value & row,LivestatusGroupByType groupByType,const Object::Ptr & groupByObject)190 Object::Ptr HostsTable::HostGroupAccessor(const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject)
191 {
192 	/* return the current group by value set from within FetchRows()
193 	 * this is the hostgrouo object used for the table join inside
194 	 * in AddColumns()
195 	 */
196 	if (groupByType == LivestatusGroupByHostGroup)
197 		return groupByObject;
198 
199 	return nullptr;
200 }
201 
NameAccessor(const Value & row)202 Value HostsTable::NameAccessor(const Value& row)
203 {
204 	Host::Ptr host = static_cast<Host::Ptr>(row);
205 
206 	if (!host)
207 		return Empty;
208 
209 	return host->GetName();
210 }
211 
DisplayNameAccessor(const Value & row)212 Value HostsTable::DisplayNameAccessor(const Value& row)
213 {
214 	Host::Ptr host = static_cast<Host::Ptr>(row);
215 
216 	if (!host)
217 		return Empty;
218 
219 	return host->GetDisplayName();
220 }
221 
AddressAccessor(const Value & row)222 Value HostsTable::AddressAccessor(const Value& row)
223 {
224 	Host::Ptr host = static_cast<Host::Ptr>(row);
225 
226 	if (!host)
227 		return Empty;
228 
229 	return host->GetAddress();
230 }
231 
Address6Accessor(const Value & row)232 Value HostsTable::Address6Accessor(const Value& row)
233 {
234 	Host::Ptr host = static_cast<Host::Ptr>(row);
235 
236 	if (!host)
237 		return Empty;
238 
239 	return host->GetAddress6();
240 }
241 
CheckCommandAccessor(const Value & row)242 Value HostsTable::CheckCommandAccessor(const Value& row)
243 {
244 	Host::Ptr host = static_cast<Host::Ptr>(row);
245 
246 	if (!host)
247 		return Empty;
248 
249 	CheckCommand::Ptr checkcommand = host->GetCheckCommand();
250 	if (checkcommand)
251 		return CompatUtility::GetCommandName(checkcommand) + "!" + CompatUtility::GetCheckableCommandArgs(host);
252 
253 	return Empty;
254 }
255 
CheckCommandExpandedAccessor(const Value & row)256 Value HostsTable::CheckCommandExpandedAccessor(const Value& row)
257 {
258 	Host::Ptr host = static_cast<Host::Ptr>(row);
259 
260 	if (!host)
261 		return Empty;
262 
263 	CheckCommand::Ptr checkcommand = host->GetCheckCommand();
264 	if (checkcommand)
265 		return CompatUtility::GetCommandName(checkcommand) + "!" + CompatUtility::GetCheckableCommandArgs(host);
266 
267 	return Empty;
268 }
269 
EventHandlerAccessor(const Value & row)270 Value HostsTable::EventHandlerAccessor(const Value& row)
271 {
272 	Host::Ptr host = static_cast<Host::Ptr>(row);
273 
274 	if (!host)
275 		return Empty;
276 
277 	EventCommand::Ptr eventcommand = host->GetEventCommand();
278 	if (eventcommand)
279 		return CompatUtility::GetCommandName(eventcommand);
280 
281 	return Empty;
282 }
283 
CheckPeriodAccessor(const Value & row)284 Value HostsTable::CheckPeriodAccessor(const Value& row)
285 {
286 	Host::Ptr host = static_cast<Host::Ptr>(row);
287 
288 	if (!host)
289 		return Empty;
290 
291 	TimePeriod::Ptr checkPeriod = host->GetCheckPeriod();
292 
293 	if (!checkPeriod)
294 		return Empty;
295 
296 	return checkPeriod->GetName();
297 }
298 
NotesAccessor(const Value & row)299 Value HostsTable::NotesAccessor(const Value& row)
300 {
301 	Host::Ptr host = static_cast<Host::Ptr>(row);
302 
303 	if (!host)
304 		return Empty;
305 
306 	return host->GetNotes();
307 }
308 
NotesExpandedAccessor(const Value & row)309 Value HostsTable::NotesExpandedAccessor(const Value& row)
310 {
311 	Host::Ptr host = static_cast<Host::Ptr>(row);
312 
313 	if (!host)
314 		return Empty;
315 
316 	MacroProcessor::ResolverList resolvers {
317 		{ "host", host },
318 		{ "icinga", IcingaApplication::GetInstance() }
319 	};
320 
321 	return MacroProcessor::ResolveMacros(host->GetNotes(), resolvers);
322 }
323 
NotesUrlAccessor(const Value & row)324 Value HostsTable::NotesUrlAccessor(const Value& row)
325 {
326 	Host::Ptr host = static_cast<Host::Ptr>(row);
327 
328 	if (!host)
329 		return Empty;
330 
331 	return host->GetNotesUrl();
332 }
333 
NotesUrlExpandedAccessor(const Value & row)334 Value HostsTable::NotesUrlExpandedAccessor(const Value& row)
335 {
336 	Host::Ptr host = static_cast<Host::Ptr>(row);
337 
338 	if (!host)
339 		return Empty;
340 
341 	MacroProcessor::ResolverList resolvers {
342 		{ "host", host },
343 		{ "icinga", IcingaApplication::GetInstance() }
344 	};
345 
346 	return MacroProcessor::ResolveMacros(host->GetNotesUrl(), resolvers);
347 }
348 
ActionUrlAccessor(const Value & row)349 Value HostsTable::ActionUrlAccessor(const Value& row)
350 {
351 	Host::Ptr host = static_cast<Host::Ptr>(row);
352 
353 	if (!host)
354 		return Empty;
355 
356 	return host->GetActionUrl();
357 }
358 
ActionUrlExpandedAccessor(const Value & row)359 Value HostsTable::ActionUrlExpandedAccessor(const Value& row)
360 {
361 	Host::Ptr host = static_cast<Host::Ptr>(row);
362 
363 	if (!host)
364 		return Empty;
365 
366 	MacroProcessor::ResolverList resolvers {
367 		{ "host", host },
368 		{ "icinga", IcingaApplication::GetInstance() }
369 	};
370 
371 	return MacroProcessor::ResolveMacros(host->GetActionUrl(), resolvers);
372 }
373 
PluginOutputAccessor(const Value & row)374 Value HostsTable::PluginOutputAccessor(const Value& row)
375 {
376 	Host::Ptr host = static_cast<Host::Ptr>(row);
377 
378 	if (!host)
379 		return Empty;
380 
381 	String output;
382 	CheckResult::Ptr cr = host->GetLastCheckResult();
383 
384 	if (cr)
385 		output = CompatUtility::GetCheckResultOutput(cr);
386 
387 	return output;
388 }
389 
PerfDataAccessor(const Value & row)390 Value HostsTable::PerfDataAccessor(const Value& row)
391 {
392 	Host::Ptr host = static_cast<Host::Ptr>(row);
393 
394 	if (!host)
395 		return Empty;
396 
397 	String perfdata;
398 	CheckResult::Ptr cr = host->GetLastCheckResult();
399 
400 	if (!cr)
401 		return Empty;
402 
403 	return PluginUtility::FormatPerfdata(cr->GetPerformanceData());
404 }
405 
IconImageAccessor(const Value & row)406 Value HostsTable::IconImageAccessor(const Value& row)
407 {
408 	Host::Ptr host = static_cast<Host::Ptr>(row);
409 
410 	if (!host)
411 		return Empty;
412 
413 	return host->GetIconImage();
414 }
415 
IconImageExpandedAccessor(const Value & row)416 Value HostsTable::IconImageExpandedAccessor(const Value& row)
417 {
418 	Host::Ptr host = static_cast<Host::Ptr>(row);
419 
420 	if (!host)
421 		return Empty;
422 
423 	MacroProcessor::ResolverList resolvers {
424 		{ "host", host },
425 		{ "icinga", IcingaApplication::GetInstance() }
426 	};
427 
428 	return MacroProcessor::ResolveMacros(host->GetIconImage(), resolvers);
429 }
430 
IconImageAltAccessor(const Value & row)431 Value HostsTable::IconImageAltAccessor(const Value& row)
432 {
433 	Host::Ptr host = static_cast<Host::Ptr>(row);
434 
435 	if (!host)
436 		return Empty;
437 
438 	return host->GetIconImageAlt();
439 }
440 
LongPluginOutputAccessor(const Value & row)441 Value HostsTable::LongPluginOutputAccessor(const Value& row)
442 {
443 	Host::Ptr host = static_cast<Host::Ptr>(row);
444 
445 	if (!host)
446 		return Empty;
447 
448 	String long_output;
449 	CheckResult::Ptr cr = host->GetLastCheckResult();
450 
451 	if (cr)
452 		long_output = CompatUtility::GetCheckResultLongOutput(cr);
453 
454 	return long_output;
455 }
456 
MaxCheckAttemptsAccessor(const Value & row)457 Value HostsTable::MaxCheckAttemptsAccessor(const Value& row)
458 {
459 	Host::Ptr host = static_cast<Host::Ptr>(row);
460 
461 	if (!host)
462 		return Empty;
463 
464 	return host->GetMaxCheckAttempts();
465 }
466 
FlapDetectionEnabledAccessor(const Value & row)467 Value HostsTable::FlapDetectionEnabledAccessor(const Value& row)
468 {
469 	Host::Ptr host = static_cast<Host::Ptr>(row);
470 
471 	if (!host)
472 		return Empty;
473 
474 	return Convert::ToLong(host->GetEnableFlapping());
475 }
476 
AcceptPassiveChecksAccessor(const Value & row)477 Value HostsTable::AcceptPassiveChecksAccessor(const Value& row)
478 {
479 	Host::Ptr host = static_cast<Host::Ptr>(row);
480 
481 	if (!host)
482 		return Empty;
483 
484 	return Convert::ToLong(host->GetEnablePassiveChecks());
485 }
486 
EventHandlerEnabledAccessor(const Value & row)487 Value HostsTable::EventHandlerEnabledAccessor(const Value& row)
488 {
489 	Host::Ptr host = static_cast<Host::Ptr>(row);
490 
491 	if (!host)
492 		return Empty;
493 
494 	return Convert::ToLong(host->GetEnableEventHandler());
495 }
496 
AcknowledgementTypeAccessor(const Value & row)497 Value HostsTable::AcknowledgementTypeAccessor(const Value& row)
498 {
499 	Host::Ptr host = static_cast<Host::Ptr>(row);
500 
501 	if (!host)
502 		return Empty;
503 
504 	ObjectLock olock(host);
505 	return host->GetAcknowledgement();
506 }
507 
CheckTypeAccessor(const Value & row)508 Value HostsTable::CheckTypeAccessor(const Value& row)
509 {
510 	Host::Ptr host = static_cast<Host::Ptr>(row);
511 
512 	if (!host)
513 		return Empty;
514 
515 	return (host->GetEnableActiveChecks() ? 0 : 1); /* 0 .. active, 1 .. passive */
516 }
517 
LastStateAccessor(const Value & row)518 Value HostsTable::LastStateAccessor(const Value& row)
519 {
520 	Host::Ptr host = static_cast<Host::Ptr>(row);
521 
522 	if (!host)
523 		return Empty;
524 
525 	return host->GetLastState();
526 }
527 
LastHardStateAccessor(const Value & row)528 Value HostsTable::LastHardStateAccessor(const Value& row)
529 {
530 	Host::Ptr host = static_cast<Host::Ptr>(row);
531 
532 	if (!host)
533 		return Empty;
534 
535 	return host->GetLastHardState();
536 }
537 
CurrentAttemptAccessor(const Value & row)538 Value HostsTable::CurrentAttemptAccessor(const Value& row)
539 {
540 	Host::Ptr host = static_cast<Host::Ptr>(row);
541 
542 	if (!host)
543 		return Empty;
544 
545 	return host->GetCheckAttempt();
546 }
547 
LastNotificationAccessor(const Value & row)548 Value HostsTable::LastNotificationAccessor(const Value& row)
549 {
550 	Host::Ptr host = static_cast<Host::Ptr>(row);
551 
552 	if (!host)
553 		return Empty;
554 
555 	return CompatUtility::GetCheckableNotificationLastNotification(host);
556 }
557 
NextNotificationAccessor(const Value & row)558 Value HostsTable::NextNotificationAccessor(const Value& row)
559 {
560 	Host::Ptr host = static_cast<Host::Ptr>(row);
561 
562 	if (!host)
563 		return Empty;
564 
565 	return CompatUtility::GetCheckableNotificationNextNotification(host);
566 }
567 
NextCheckAccessor(const Value & row)568 Value HostsTable::NextCheckAccessor(const Value& row)
569 {
570 	Host::Ptr host = static_cast<Host::Ptr>(row);
571 
572 	if (!host)
573 		return Empty;
574 
575 	return static_cast<int>(host->GetNextCheck());
576 }
577 
LastHardStateChangeAccessor(const Value & row)578 Value HostsTable::LastHardStateChangeAccessor(const Value& row)
579 {
580 	Host::Ptr host = static_cast<Host::Ptr>(row);
581 
582 	if (!host)
583 		return Empty;
584 
585 	return static_cast<int>(host->GetLastHardStateChange());
586 }
587 
HasBeenCheckedAccessor(const Value & row)588 Value HostsTable::HasBeenCheckedAccessor(const Value& row)
589 {
590 	Host::Ptr host = static_cast<Host::Ptr>(row);
591 
592 	if (!host)
593 		return Empty;
594 
595 	return Convert::ToLong(host->HasBeenChecked());
596 }
597 
CurrentNotificationNumberAccessor(const Value & row)598 Value HostsTable::CurrentNotificationNumberAccessor(const Value& row)
599 {
600 	Host::Ptr host = static_cast<Host::Ptr>(row);
601 
602 	if (!host)
603 		return Empty;
604 
605 	return CompatUtility::GetCheckableNotificationNotificationNumber(host);
606 }
607 
TotalServicesAccessor(const Value & row)608 Value HostsTable::TotalServicesAccessor(const Value& row)
609 {
610 	Host::Ptr host = static_cast<Host::Ptr>(row);
611 
612 	if (!host)
613 		return Empty;
614 
615 	return host->GetTotalServices();
616 }
617 
ChecksEnabledAccessor(const Value & row)618 Value HostsTable::ChecksEnabledAccessor(const Value& row)
619 {
620 	Host::Ptr host = static_cast<Host::Ptr>(row);
621 
622 	if (!host)
623 		return Empty;
624 
625 	return Convert::ToLong(host->GetEnableActiveChecks());
626 }
627 
NotificationsEnabledAccessor(const Value & row)628 Value HostsTable::NotificationsEnabledAccessor(const Value& row)
629 {
630 	Host::Ptr host = static_cast<Host::Ptr>(row);
631 
632 	if (!host)
633 		return Empty;
634 
635 	return Convert::ToLong(host->GetEnableNotifications());
636 }
637 
ProcessPerformanceDataAccessor(const Value & row)638 Value HostsTable::ProcessPerformanceDataAccessor(const Value& row)
639 {
640 	Host::Ptr host = static_cast<Host::Ptr>(row);
641 
642 	if (!host)
643 		return Empty;
644 
645 	return Convert::ToLong(host->GetEnablePerfdata());
646 }
647 
AcknowledgedAccessor(const Value & row)648 Value HostsTable::AcknowledgedAccessor(const Value& row)
649 {
650 	Host::Ptr host = static_cast<Host::Ptr>(row);
651 
652 	if (!host)
653 		return Empty;
654 
655 	ObjectLock olock(host);
656 	return host->IsAcknowledged();
657 }
658 
StateAccessor(const Value & row)659 Value HostsTable::StateAccessor(const Value& row)
660 {
661 	Host::Ptr host = static_cast<Host::Ptr>(row);
662 
663 	if (!host)
664 		return Empty;
665 
666 	return host->IsReachable() ? host->GetState() : 2;
667 }
668 
StateTypeAccessor(const Value & row)669 Value HostsTable::StateTypeAccessor(const Value& row)
670 {
671 	Host::Ptr host = static_cast<Host::Ptr>(row);
672 
673 	if (!host)
674 		return Empty;
675 
676 	return host->GetStateType();
677 }
678 
NoMoreNotificationsAccessor(const Value & row)679 Value HostsTable::NoMoreNotificationsAccessor(const Value& row)
680 {
681 	Host::Ptr host = static_cast<Host::Ptr>(row);
682 
683 	if (!host)
684 		return Empty;
685 
686 	return (CompatUtility::GetCheckableNotificationNotificationInterval(host) == 0 && !host->GetVolatile()) ? 1 : 0;
687 }
688 
LastCheckAccessor(const Value & row)689 Value HostsTable::LastCheckAccessor(const Value& row)
690 {
691 	Host::Ptr host = static_cast<Host::Ptr>(row);
692 
693 	if (!host)
694 		return Empty;
695 
696 	return static_cast<int>(host->GetLastCheck());
697 }
698 
LastStateChangeAccessor(const Value & row)699 Value HostsTable::LastStateChangeAccessor(const Value& row)
700 {
701 	Host::Ptr host = static_cast<Host::Ptr>(row);
702 
703 	if (!host)
704 		return Empty;
705 
706 	return static_cast<int>(host->GetLastStateChange());
707 }
708 
LastTimeUpAccessor(const Value & row)709 Value HostsTable::LastTimeUpAccessor(const Value& row)
710 {
711 	Host::Ptr host = static_cast<Host::Ptr>(row);
712 
713 	if (!host)
714 		return Empty;
715 
716 	return static_cast<int>(host->GetLastStateUp());
717 }
718 
LastTimeDownAccessor(const Value & row)719 Value HostsTable::LastTimeDownAccessor(const Value& row)
720 {
721 	Host::Ptr host = static_cast<Host::Ptr>(row);
722 
723 	if (!host)
724 		return Empty;
725 
726 	return static_cast<int>(host->GetLastStateDown());
727 }
728 
LastTimeUnreachableAccessor(const Value & row)729 Value HostsTable::LastTimeUnreachableAccessor(const Value& row)
730 {
731 	Host::Ptr host = static_cast<Host::Ptr>(row);
732 
733 	if (!host)
734 		return Empty;
735 
736 	return static_cast<int>(host->GetLastStateUnreachable());
737 }
738 
IsFlappingAccessor(const Value & row)739 Value HostsTable::IsFlappingAccessor(const Value& row)
740 {
741 	Host::Ptr host = static_cast<Host::Ptr>(row);
742 
743 	if (!host)
744 		return Empty;
745 
746 	return host->IsFlapping();
747 }
748 
ScheduledDowntimeDepthAccessor(const Value & row)749 Value HostsTable::ScheduledDowntimeDepthAccessor(const Value& row)
750 {
751 	Host::Ptr host = static_cast<Host::Ptr>(row);
752 
753 	if (!host)
754 		return Empty;
755 
756 	return host->GetDowntimeDepth();
757 }
758 
ActiveChecksEnabledAccessor(const Value & row)759 Value HostsTable::ActiveChecksEnabledAccessor(const Value& row)
760 {
761 	Host::Ptr host = static_cast<Host::Ptr>(row);
762 
763 	if (!host)
764 		return Empty;
765 
766 	return Convert::ToLong(host->GetEnableActiveChecks());
767 }
768 
CheckIntervalAccessor(const Value & row)769 Value HostsTable::CheckIntervalAccessor(const Value& row)
770 {
771 	Host::Ptr host = static_cast<Host::Ptr>(row);
772 
773 	if (!host)
774 		return Empty;
775 
776 	return host->GetCheckInterval() / LIVESTATUS_INTERVAL_LENGTH;
777 }
778 
RetryIntervalAccessor(const Value & row)779 Value HostsTable::RetryIntervalAccessor(const Value& row)
780 {
781 	Host::Ptr host = static_cast<Host::Ptr>(row);
782 
783 	if (!host)
784 		return Empty;
785 
786 	return host->GetRetryInterval() / LIVESTATUS_INTERVAL_LENGTH;
787 }
788 
NotificationIntervalAccessor(const Value & row)789 Value HostsTable::NotificationIntervalAccessor(const Value& row)
790 {
791 	Host::Ptr host = static_cast<Host::Ptr>(row);
792 
793 	if (!host)
794 		return Empty;
795 
796 	return CompatUtility::GetCheckableNotificationNotificationInterval(host);
797 }
798 
LowFlapThresholdAccessor(const Value & row)799 Value HostsTable::LowFlapThresholdAccessor(const Value& row)
800 {
801 	Host::Ptr host = static_cast<Host::Ptr>(row);
802 
803 	if (!host)
804 		return Empty;
805 
806 	return host->GetFlappingThresholdLow();
807 }
808 
HighFlapThresholdAccessor(const Value & row)809 Value HostsTable::HighFlapThresholdAccessor(const Value& row)
810 {
811 	Host::Ptr host = static_cast<Host::Ptr>(row);
812 
813 	if (!host)
814 		return Empty;
815 
816 	return host->GetFlappingThresholdHigh();
817 }
818 
LatencyAccessor(const Value & row)819 Value HostsTable::LatencyAccessor(const Value& row)
820 {
821 	Host::Ptr host = static_cast<Host::Ptr>(row);
822 
823 	if (!host)
824 		return Empty;
825 
826 	CheckResult::Ptr cr = host->GetLastCheckResult();
827 
828 	if (!cr)
829 		return Empty;
830 
831 	return cr->CalculateLatency();
832 }
833 
ExecutionTimeAccessor(const Value & row)834 Value HostsTable::ExecutionTimeAccessor(const Value& row)
835 {
836 	Host::Ptr host = static_cast<Host::Ptr>(row);
837 
838 	if (!host)
839 		return Empty;
840 
841 	CheckResult::Ptr cr = host->GetLastCheckResult();
842 
843 	if (!cr)
844 		return Empty;
845 
846 	return cr->CalculateExecutionTime();
847 }
848 
PercentStateChangeAccessor(const Value & row)849 Value HostsTable::PercentStateChangeAccessor(const Value& row)
850 {
851 	Host::Ptr host = static_cast<Host::Ptr>(row);
852 
853 	if (!host)
854 		return Empty;
855 
856 	return host->GetFlappingCurrent();
857 }
858 
InNotificationPeriodAccessor(const Value & row)859 Value HostsTable::InNotificationPeriodAccessor(const Value& row)
860 {
861 	Host::Ptr host = static_cast<Host::Ptr>(row);
862 
863 	if (!host)
864 		return Empty;
865 
866 	for (const Notification::Ptr& notification : host->GetNotifications()) {
867 		TimePeriod::Ptr timeperiod = notification->GetPeriod();
868 
869 		if (!timeperiod || timeperiod->IsInside(Utility::GetTime()))
870 			return 1;
871 	}
872 
873 	return 0;
874 }
875 
InCheckPeriodAccessor(const Value & row)876 Value HostsTable::InCheckPeriodAccessor(const Value& row)
877 {
878 	Host::Ptr host = static_cast<Host::Ptr>(row);
879 
880 	if (!host)
881 		return Empty;
882 
883 	TimePeriod::Ptr timeperiod = host->GetCheckPeriod();
884 
885 	/* none set means always checked */
886 	if (!timeperiod)
887 		return 1;
888 
889 	return Convert::ToLong(timeperiod->IsInside(Utility::GetTime()));
890 }
891 
ContactsAccessor(const Value & row)892 Value HostsTable::ContactsAccessor(const Value& row)
893 {
894 	Host::Ptr host = static_cast<Host::Ptr>(row);
895 
896 	if (!host)
897 		return Empty;
898 
899 	ArrayData result;
900 
901 	for (const User::Ptr& user : CompatUtility::GetCheckableNotificationUsers(host)) {
902 		result.push_back(user->GetName());
903 	}
904 
905 	return new Array(std::move(result));
906 }
907 
DowntimesAccessor(const Value & row)908 Value HostsTable::DowntimesAccessor(const Value& row)
909 {
910 	Host::Ptr host = static_cast<Host::Ptr>(row);
911 
912 	if (!host)
913 		return Empty;
914 
915 	ArrayData result;
916 
917 	for (const Downtime::Ptr& downtime : host->GetDowntimes()) {
918 		if (downtime->IsExpired())
919 			continue;
920 
921 		result.push_back(downtime->GetLegacyId());
922 	}
923 
924 	return new Array(std::move(result));
925 }
926 
DowntimesWithInfoAccessor(const Value & row)927 Value HostsTable::DowntimesWithInfoAccessor(const Value& row)
928 {
929 	Host::Ptr host = static_cast<Host::Ptr>(row);
930 
931 	if (!host)
932 		return Empty;
933 
934 	ArrayData result;
935 
936 	for (const Downtime::Ptr& downtime : host->GetDowntimes()) {
937 		if (downtime->IsExpired())
938 			continue;
939 
940 		result.push_back(new Array({
941 			downtime->GetLegacyId(),
942 			downtime->GetAuthor(),
943 			downtime->GetComment()
944 		}));
945 	}
946 
947 	return new Array(std::move(result));
948 }
949 
CommentsAccessor(const Value & row)950 Value HostsTable::CommentsAccessor(const Value& row)
951 {
952 	Host::Ptr host = static_cast<Host::Ptr>(row);
953 
954 	if (!host)
955 		return Empty;
956 
957 	ArrayData result;
958 
959 	for (const Comment::Ptr& comment : host->GetComments()) {
960 		if (comment->IsExpired())
961 			continue;
962 
963 		result.push_back(comment->GetLegacyId());
964 	}
965 
966 	return new Array(std::move(result));
967 }
968 
CommentsWithInfoAccessor(const Value & row)969 Value HostsTable::CommentsWithInfoAccessor(const Value& row)
970 {
971 	Host::Ptr host = static_cast<Host::Ptr>(row);
972 
973 	if (!host)
974 		return Empty;
975 
976 	ArrayData result;
977 
978 	for (const Comment::Ptr& comment : host->GetComments()) {
979 		if (comment->IsExpired())
980 			continue;
981 
982 		result.push_back(new Array({
983 			comment->GetLegacyId(),
984 			comment->GetAuthor(),
985 			comment->GetText()
986 		}));
987 	}
988 
989 	return new Array(std::move(result));
990 }
991 
CommentsWithExtraInfoAccessor(const Value & row)992 Value HostsTable::CommentsWithExtraInfoAccessor(const Value& row)
993 {
994 	Host::Ptr host = static_cast<Host::Ptr>(row);
995 
996 	if (!host)
997 		return Empty;
998 
999 	ArrayData result;
1000 
1001 	for (const Comment::Ptr& comment : host->GetComments()) {
1002 		if (comment->IsExpired())
1003 			continue;
1004 
1005 		result.push_back(new Array({
1006 			comment->GetLegacyId(),
1007 			comment->GetAuthor(),
1008 			comment->GetText(),
1009 			comment->GetEntryType(),
1010 			static_cast<int>(comment->GetEntryTime())
1011 		}));
1012 	}
1013 
1014 	return new Array(std::move(result));
1015 }
1016 
CustomVariableNamesAccessor(const Value & row)1017 Value HostsTable::CustomVariableNamesAccessor(const Value& row)
1018 {
1019 	Host::Ptr host = static_cast<Host::Ptr>(row);
1020 
1021 	if (!host)
1022 		return Empty;
1023 
1024 	Dictionary::Ptr vars = host->GetVars();
1025 
1026 	ArrayData result;
1027 
1028 	if (vars) {
1029 		ObjectLock olock(vars);
1030 		for (const Dictionary::Pair& kv : vars) {
1031 			result.push_back(kv.first);
1032 		}
1033 	}
1034 
1035 	return new Array(std::move(result));
1036 }
1037 
CustomVariableValuesAccessor(const Value & row)1038 Value HostsTable::CustomVariableValuesAccessor(const Value& row)
1039 {
1040 	Host::Ptr host = static_cast<Host::Ptr>(row);
1041 
1042 	if (!host)
1043 		return Empty;
1044 
1045 	Dictionary::Ptr vars = host->GetVars();
1046 
1047 	ArrayData result;
1048 
1049 	if (vars) {
1050 		ObjectLock olock(vars);
1051 		for (const Dictionary::Pair& kv : vars) {
1052 			if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
1053 				result.push_back(JsonEncode(kv.second));
1054 			else
1055 				result.push_back(kv.second);
1056 		}
1057 	}
1058 
1059 	return new Array(std::move(result));
1060 }
1061 
CustomVariablesAccessor(const Value & row)1062 Value HostsTable::CustomVariablesAccessor(const Value& row)
1063 {
1064 	Host::Ptr host = static_cast<Host::Ptr>(row);
1065 
1066 	if (!host)
1067 		return Empty;
1068 
1069 	Dictionary::Ptr vars = host->GetVars();
1070 
1071 	ArrayData result;
1072 
1073 	if (vars) {
1074 		ObjectLock olock(vars);
1075 		for (const Dictionary::Pair& kv : vars) {
1076 			Value val;
1077 
1078 			if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
1079 				val = JsonEncode(kv.second);
1080 			else
1081 				val = kv.second;
1082 
1083 			result.push_back(new Array({
1084 				kv.first,
1085 				val
1086 			}));
1087 		}
1088 	}
1089 
1090 	return new Array(std::move(result));
1091 }
1092 
CVIsJsonAccessor(const Value & row)1093 Value HostsTable::CVIsJsonAccessor(const Value& row)
1094 {
1095 	Host::Ptr host = static_cast<Host::Ptr>(row);
1096 
1097 	if (!host)
1098 		return Empty;
1099 
1100 	Dictionary::Ptr vars = host->GetVars();
1101 
1102 	if (!vars)
1103 		return Empty;
1104 
1105 	bool cv_is_json = false;
1106 
1107 	ObjectLock olock(vars);
1108 	for (const Dictionary::Pair& kv : vars) {
1109 		if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
1110 			cv_is_json = true;
1111 	}
1112 
1113 	return cv_is_json;
1114 }
1115 
ParentsAccessor(const Value & row)1116 Value HostsTable::ParentsAccessor(const Value& row)
1117 {
1118 	Host::Ptr host = static_cast<Host::Ptr>(row);
1119 
1120 	if (!host)
1121 		return Empty;
1122 
1123 	ArrayData result;
1124 
1125 	for (const Checkable::Ptr& parent : host->GetParents()) {
1126 		Host::Ptr parent_host = dynamic_pointer_cast<Host>(parent);
1127 
1128 		if (!parent_host)
1129 			continue;
1130 
1131 		result.push_back(parent_host->GetName());
1132 	}
1133 
1134 	return new Array(std::move(result));
1135 }
1136 
ChildsAccessor(const Value & row)1137 Value HostsTable::ChildsAccessor(const Value& row)
1138 {
1139 	Host::Ptr host = static_cast<Host::Ptr>(row);
1140 
1141 	if (!host)
1142 		return Empty;
1143 
1144 	ArrayData result;
1145 
1146 	for (const Checkable::Ptr& child : host->GetChildren()) {
1147 		Host::Ptr child_host = dynamic_pointer_cast<Host>(child);
1148 
1149 		if (!child_host)
1150 			continue;
1151 
1152 		result.push_back(child_host->GetName());
1153 	}
1154 
1155 	return new Array(std::move(result));
1156 }
1157 
NumServicesAccessor(const Value & row)1158 Value HostsTable::NumServicesAccessor(const Value& row)
1159 {
1160 	/* duplicate of TotalServices */
1161 	Host::Ptr host = static_cast<Host::Ptr>(row);
1162 
1163 	if (!host)
1164 		return Empty;
1165 
1166 	return host->GetTotalServices();
1167 }
1168 
WorstServiceStateAccessor(const Value & row)1169 Value HostsTable::WorstServiceStateAccessor(const Value& row)
1170 {
1171 	Host::Ptr host = static_cast<Host::Ptr>(row);
1172 
1173 	if (!host)
1174 		return Empty;
1175 
1176 	Value worst_service = ServiceOK;
1177 
1178 	for (const Service::Ptr& service : host->GetServices()) {
1179 		if (service->GetState() > worst_service)
1180 			worst_service = service->GetState();
1181 	}
1182 
1183 	return worst_service;
1184 }
1185 
NumServicesOkAccessor(const Value & row)1186 Value HostsTable::NumServicesOkAccessor(const Value& row)
1187 {
1188 	Host::Ptr host = static_cast<Host::Ptr>(row);
1189 
1190 	if (!host)
1191 		return Empty;
1192 
1193 	int num_services = 0;
1194 
1195 	for (const Service::Ptr& service : host->GetServices()) {
1196 		if (service->GetState() == ServiceOK)
1197 			num_services++;
1198 	}
1199 
1200 	return num_services;
1201 }
1202 
NumServicesWarnAccessor(const Value & row)1203 Value HostsTable::NumServicesWarnAccessor(const Value& row)
1204 {
1205 	Host::Ptr host = static_cast<Host::Ptr>(row);
1206 
1207 	if (!host)
1208 		return Empty;
1209 
1210 	int num_services = 0;
1211 
1212 	for (const Service::Ptr& service : host->GetServices()) {
1213 		if (service->GetState() == ServiceWarning)
1214 			num_services++;
1215 	}
1216 
1217 	return num_services;
1218 }
1219 
NumServicesCritAccessor(const Value & row)1220 Value HostsTable::NumServicesCritAccessor(const Value& row)
1221 {
1222 	Host::Ptr host = static_cast<Host::Ptr>(row);
1223 
1224 	if (!host)
1225 		return Empty;
1226 
1227 	int num_services = 0;
1228 
1229 	for (const Service::Ptr& service : host->GetServices()) {
1230 		if (service->GetState() == ServiceCritical)
1231 			num_services++;
1232 	}
1233 
1234 	return num_services;
1235 }
1236 
NumServicesUnknownAccessor(const Value & row)1237 Value HostsTable::NumServicesUnknownAccessor(const Value& row)
1238 {
1239 	Host::Ptr host = static_cast<Host::Ptr>(row);
1240 
1241 	if (!host)
1242 		return Empty;
1243 
1244 	int num_services = 0;
1245 
1246 	for (const Service::Ptr& service : host->GetServices()) {
1247 		if (service->GetState() == ServiceUnknown)
1248 			num_services++;
1249 	}
1250 
1251 	return num_services;
1252 }
1253 
NumServicesPendingAccessor(const Value & row)1254 Value HostsTable::NumServicesPendingAccessor(const Value& row)
1255 {
1256 	Host::Ptr host = static_cast<Host::Ptr>(row);
1257 
1258 	if (!host)
1259 		return Empty;
1260 
1261 	int num_services = 0;
1262 
1263 	for (const Service::Ptr& service : host->GetServices()) {
1264 		if (!service->GetLastCheckResult())
1265 			num_services++;
1266 	}
1267 
1268 	return num_services;
1269 }
1270 
WorstServiceHardStateAccessor(const Value & row)1271 Value HostsTable::WorstServiceHardStateAccessor(const Value& row)
1272 {
1273 	Host::Ptr host = static_cast<Host::Ptr>(row);
1274 
1275 	if (!host)
1276 		return Empty;
1277 
1278 	Value worst_service = ServiceOK;
1279 
1280 	for (const Service::Ptr& service : host->GetServices()) {
1281 		if (service->GetStateType() == StateTypeHard) {
1282 			if (service->GetState() > worst_service)
1283 				worst_service = service->GetState();
1284 		}
1285 	}
1286 
1287 	return worst_service;
1288 }
1289 
NumServicesHardOkAccessor(const Value & row)1290 Value HostsTable::NumServicesHardOkAccessor(const Value& row)
1291 {
1292 	Host::Ptr host = static_cast<Host::Ptr>(row);
1293 
1294 	if (!host)
1295 		return Empty;
1296 
1297 	int num_services = 0;
1298 
1299 	for (const Service::Ptr& service : host->GetServices()) {
1300 		if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceOK)
1301 			num_services++;
1302 	}
1303 
1304 	return num_services;
1305 }
1306 
NumServicesHardWarnAccessor(const Value & row)1307 Value HostsTable::NumServicesHardWarnAccessor(const Value& row)
1308 {
1309 	Host::Ptr host = static_cast<Host::Ptr>(row);
1310 
1311 	if (!host)
1312 		return Empty;
1313 
1314 	int num_services = 0;
1315 
1316 	for (const Service::Ptr& service : host->GetServices()) {
1317 		if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceWarning)
1318 			num_services++;
1319 	}
1320 
1321 	return num_services;
1322 }
1323 
NumServicesHardCritAccessor(const Value & row)1324 Value HostsTable::NumServicesHardCritAccessor(const Value& row)
1325 {
1326 	Host::Ptr host = static_cast<Host::Ptr>(row);
1327 
1328 	if (!host)
1329 		return Empty;
1330 
1331 	int num_services = 0;
1332 
1333 	for (const Service::Ptr& service : host->GetServices()) {
1334 		if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceCritical)
1335 			num_services++;
1336 	}
1337 
1338 	return num_services;
1339 }
1340 
NumServicesHardUnknownAccessor(const Value & row)1341 Value HostsTable::NumServicesHardUnknownAccessor(const Value& row)
1342 {
1343 	Host::Ptr host = static_cast<Host::Ptr>(row);
1344 
1345 	if (!host)
1346 		return Empty;
1347 
1348 	int num_services = 0;
1349 
1350 	for (const Service::Ptr& service : host->GetServices()) {
1351 		if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceUnknown)
1352 			num_services++;
1353 	}
1354 
1355 	return num_services;
1356 }
1357 
HardStateAccessor(const Value & row)1358 Value HostsTable::HardStateAccessor(const Value& row)
1359 {
1360 	Host::Ptr host = static_cast<Host::Ptr>(row);
1361 
1362 	if (!host)
1363 		return Empty;
1364 
1365 	if (host->GetState() == HostUp)
1366 		return HostUp;
1367 	else if (host->GetStateType() == StateTypeHard)
1368 		return host->GetState();
1369 
1370 	return host->GetLastHardState();
1371 }
1372 
StalenessAccessor(const Value & row)1373 Value HostsTable::StalenessAccessor(const Value& row)
1374 {
1375 	Host::Ptr host = static_cast<Host::Ptr>(row);
1376 
1377 	if (!host)
1378 		return Empty;
1379 
1380 	if (host->HasBeenChecked() && host->GetLastCheck() > 0)
1381 		return (Utility::GetTime() - host->GetLastCheck()) / (host->GetCheckInterval() * 3600);
1382 
1383 	return 0.0;
1384 }
1385 
GroupsAccessor(const Value & row)1386 Value HostsTable::GroupsAccessor(const Value& row)
1387 {
1388 	Host::Ptr host = static_cast<Host::Ptr>(row);
1389 
1390 	if (!host)
1391 		return Empty;
1392 
1393 	Array::Ptr groups = host->GetGroups();
1394 
1395 	if (!groups)
1396 		return Empty;
1397 
1398 	return groups;
1399 }
1400 
ContactGroupsAccessor(const Value & row)1401 Value HostsTable::ContactGroupsAccessor(const Value& row)
1402 {
1403 	Host::Ptr host = static_cast<Host::Ptr>(row);
1404 
1405 	if (!host)
1406 		return Empty;
1407 
1408 	ArrayData result;
1409 
1410 	for (const UserGroup::Ptr& usergroup : CompatUtility::GetCheckableNotificationUserGroups(host)) {
1411 		result.push_back(usergroup->GetName());
1412 	}
1413 
1414 	return new Array(std::move(result));
1415 }
1416 
ServicesAccessor(const Value & row)1417 Value HostsTable::ServicesAccessor(const Value& row)
1418 {
1419 	Host::Ptr host = static_cast<Host::Ptr>(row);
1420 
1421 	if (!host)
1422 		return Empty;
1423 
1424 	std::vector<Service::Ptr> rservices = host->GetServices();
1425 
1426 	ArrayData result;
1427 	result.reserve(rservices.size());
1428 
1429 	for (const Service::Ptr& service : rservices) {
1430 		result.push_back(service->GetShortName());
1431 	}
1432 
1433 	return new Array(std::move(result));
1434 }
1435 
ServicesWithStateAccessor(const Value & row)1436 Value HostsTable::ServicesWithStateAccessor(const Value& row)
1437 {
1438 	Host::Ptr host = static_cast<Host::Ptr>(row);
1439 
1440 	if (!host)
1441 		return Empty;
1442 
1443 	std::vector<Service::Ptr> rservices = host->GetServices();
1444 
1445 	ArrayData result;
1446 	result.reserve(rservices.size());
1447 
1448 	for (const Service::Ptr& service : rservices) {
1449 		result.push_back(new Array({
1450 			service->GetShortName(),
1451 			service->GetState(),
1452 			service->HasBeenChecked() ? 1 : 0
1453 		}));
1454 	}
1455 
1456 	return new Array(std::move(result));
1457 }
1458 
ServicesWithInfoAccessor(const Value & row)1459 Value HostsTable::ServicesWithInfoAccessor(const Value& row)
1460 {
1461 	Host::Ptr host = static_cast<Host::Ptr>(row);
1462 
1463 	if (!host)
1464 		return Empty;
1465 
1466 	std::vector<Service::Ptr> rservices = host->GetServices();
1467 
1468 	ArrayData result;
1469 	result.reserve(rservices.size());
1470 
1471 	for (const Service::Ptr& service : rservices) {
1472 		String output;
1473 		CheckResult::Ptr cr = service->GetLastCheckResult();
1474 
1475 		if (cr)
1476 			output = CompatUtility::GetCheckResultOutput(cr);
1477 
1478 		result.push_back(new Array({
1479 			service->GetShortName(),
1480 			service->GetState(),
1481 			service->HasBeenChecked() ? 1 : 0,
1482 			output
1483 		}));
1484 	}
1485 
1486 	return new Array(std::move(result));
1487 }
1488 
CheckSourceAccessor(const Value & row)1489 Value HostsTable::CheckSourceAccessor(const Value& row)
1490 {
1491 	Host::Ptr host = static_cast<Host::Ptr>(row);
1492 
1493 	if (!host)
1494 		return Empty;
1495 
1496 	CheckResult::Ptr cr = host->GetLastCheckResult();
1497 
1498 	if (cr)
1499 		return cr->GetCheckSource();
1500 
1501 	return Empty;
1502 }
1503 
IsReachableAccessor(const Value & row)1504 Value HostsTable::IsReachableAccessor(const Value& row)
1505 {
1506 	Host::Ptr host = static_cast<Host::Ptr>(row);
1507 
1508 	if (!host)
1509 		return Empty;
1510 
1511 	return host->IsReachable();
1512 }
1513 
OriginalAttributesAccessor(const Value & row)1514 Value HostsTable::OriginalAttributesAccessor(const Value& row)
1515 {
1516 	Host::Ptr host = static_cast<Host::Ptr>(row);
1517 
1518 	if (!host)
1519 		return Empty;
1520 
1521 	return JsonEncode(host->GetOriginalAttributes());
1522 }
1523