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