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