]> granicus.if.org Git - icinga2/blob - lib/livestatus/hoststable.cpp
Move the IDO specific compat notification filter logic into the 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         return CompatUtility::GetCheckableInNotificationPeriod(host);
883 }
884
885 Value HostsTable::InCheckPeriodAccessor(const Value& row)
886 {
887         Host::Ptr host = static_cast<Host::Ptr>(row);
888
889         if (!host)
890                 return Empty;
891
892         TimePeriod::Ptr timeperiod = host->GetCheckPeriod();
893
894         /* none set means always checked */
895         if (!timeperiod)
896                 return 1;
897
898         return Convert::ToLong(timeperiod->IsInside(Utility::GetTime()));
899 }
900
901 Value HostsTable::ContactsAccessor(const Value& row)
902 {
903         Host::Ptr host = static_cast<Host::Ptr>(row);
904
905         if (!host)
906                 return Empty;
907
908         Array::Ptr contact_names = new Array();
909
910         for (const User::Ptr& user : CompatUtility::GetCheckableNotificationUsers(host)) {
911                 contact_names->Add(user->GetName());
912         }
913
914         return contact_names;
915 }
916
917 Value HostsTable::DowntimesAccessor(const Value& row)
918 {
919         Host::Ptr host = static_cast<Host::Ptr>(row);
920
921         if (!host)
922                 return Empty;
923
924         Array::Ptr results = new Array();
925
926         for (const Downtime::Ptr& downtime : host->GetDowntimes()) {
927                 if (downtime->IsExpired())
928                         continue;
929
930                 results->Add(downtime->GetLegacyId());
931         }
932
933         return results;
934 }
935
936 Value HostsTable::DowntimesWithInfoAccessor(const Value& row)
937 {
938         Host::Ptr host = static_cast<Host::Ptr>(row);
939
940         if (!host)
941                 return Empty;
942
943         Array::Ptr results = new Array();
944
945         for (const Downtime::Ptr& downtime : host->GetDowntimes()) {
946                 if (downtime->IsExpired())
947                         continue;
948
949                 Array::Ptr downtime_info = new Array();
950                 downtime_info->Add(downtime->GetLegacyId());
951                 downtime_info->Add(downtime->GetAuthor());
952                 downtime_info->Add(downtime->GetComment());
953                 results->Add(downtime_info);
954         }
955
956         return results;
957 }
958
959 Value HostsTable::CommentsAccessor(const Value& row)
960 {
961         Host::Ptr host = static_cast<Host::Ptr>(row);
962
963         if (!host)
964                 return Empty;
965
966         Array::Ptr results = new Array();
967         for (const Comment::Ptr& comment : host->GetComments()) {
968                 if (comment->IsExpired())
969                         continue;
970
971                 results->Add(comment->GetLegacyId());
972         }
973
974         return results;
975 }
976
977 Value HostsTable::CommentsWithInfoAccessor(const Value& row)
978 {
979         Host::Ptr host = static_cast<Host::Ptr>(row);
980
981         if (!host)
982                 return Empty;
983
984         Array::Ptr results = new Array();
985
986         for (const Comment::Ptr& comment : host->GetComments()) {
987                 if (comment->IsExpired())
988                         continue;
989
990                 Array::Ptr comment_info = new Array();
991                 comment_info->Add(comment->GetLegacyId());
992                 comment_info->Add(comment->GetAuthor());
993                 comment_info->Add(comment->GetText());
994                 results->Add(comment_info);
995         }
996
997         return results;
998 }
999
1000 Value HostsTable::CommentsWithExtraInfoAccessor(const Value& row)
1001 {
1002         Host::Ptr host = static_cast<Host::Ptr>(row);
1003
1004         if (!host)
1005                 return Empty;
1006
1007         Array::Ptr results = new Array();
1008
1009         for (const Comment::Ptr& comment : host->GetComments()) {
1010                 if (comment->IsExpired())
1011                         continue;
1012
1013                 Array::Ptr comment_info = new Array();
1014                 comment_info->Add(comment->GetLegacyId());
1015                 comment_info->Add(comment->GetAuthor());
1016                 comment_info->Add(comment->GetText());
1017                 comment_info->Add(comment->GetEntryType());
1018                 comment_info->Add(static_cast<int>(comment->GetEntryTime()));
1019                 results->Add(comment_info);
1020         }
1021
1022         return results;
1023 }
1024
1025 Value HostsTable::CustomVariableNamesAccessor(const Value& row)
1026 {
1027         Host::Ptr host = static_cast<Host::Ptr>(row);
1028
1029         if (!host)
1030                 return Empty;
1031
1032         Dictionary::Ptr vars;
1033
1034         {
1035                 ObjectLock olock(host);
1036                 vars = host->GetVars();
1037         }
1038
1039         Array::Ptr cv = new Array();
1040
1041         if (!vars)
1042                 return cv;
1043
1044         ObjectLock olock(vars);
1045         for (const Dictionary::Pair& kv : vars) {
1046                 cv->Add(kv.first);
1047         }
1048
1049         return cv;
1050 }
1051
1052 Value HostsTable::CustomVariableValuesAccessor(const Value& row)
1053 {
1054         Host::Ptr host = static_cast<Host::Ptr>(row);
1055
1056         if (!host)
1057                 return Empty;
1058
1059         Dictionary::Ptr vars;
1060
1061         {
1062                 ObjectLock olock(host);
1063                 vars = host->GetVars();
1064         }
1065
1066         Array::Ptr cv = new Array();
1067
1068         if (!vars)
1069                 return cv;
1070
1071         ObjectLock olock(vars);
1072         for (const Dictionary::Pair& kv : vars) {
1073                 if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
1074                         cv->Add(JsonEncode(kv.second));
1075                 else
1076                         cv->Add(kv.second);
1077         }
1078
1079         return cv;
1080 }
1081
1082 Value HostsTable::CustomVariablesAccessor(const Value& row)
1083 {
1084         Host::Ptr host = static_cast<Host::Ptr>(row);
1085
1086         if (!host)
1087                 return Empty;
1088
1089         Dictionary::Ptr vars;
1090
1091         {
1092                 ObjectLock olock(host);
1093                 vars = host->GetVars();
1094         }
1095
1096         Array::Ptr cv = new Array();
1097
1098         if (!vars)
1099                 return cv;
1100
1101         ObjectLock olock(vars);
1102         for (const Dictionary::Pair& kv : vars) {
1103                 Array::Ptr key_val = new Array();
1104                 key_val->Add(kv.first);
1105
1106                 if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
1107                         key_val->Add(JsonEncode(kv.second));
1108                 else
1109                         key_val->Add(kv.second);
1110
1111                 cv->Add(key_val);
1112         }
1113
1114         return cv;
1115 }
1116
1117 Value HostsTable::CVIsJsonAccessor(const Value& row)
1118 {
1119         Host::Ptr host = static_cast<Host::Ptr>(row);
1120
1121         if (!host)
1122                 return Empty;
1123
1124         Dictionary::Ptr vars;
1125
1126         {
1127                 ObjectLock olock(host);
1128                 vars = host->GetVars();
1129         }
1130
1131         if (!vars)
1132                 return Empty;
1133
1134         bool cv_is_json = false;
1135
1136         ObjectLock olock(vars);
1137         for (const Dictionary::Pair& kv : vars) {
1138                 if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
1139                         cv_is_json = true;
1140         }
1141
1142         return cv_is_json;
1143 }
1144
1145 Value HostsTable::ParentsAccessor(const Value& row)
1146 {
1147         Host::Ptr host = static_cast<Host::Ptr>(row);
1148
1149         if (!host)
1150                 return Empty;
1151
1152         Array::Ptr parents = new Array();
1153
1154         for (const Checkable::Ptr& parent : host->GetParents()) {
1155                 Host::Ptr parent_host = dynamic_pointer_cast<Host>(parent);
1156
1157                 if (!parent_host)
1158                         continue;
1159
1160                 parents->Add(parent_host->GetName());
1161         }
1162
1163         return parents;
1164 }
1165
1166 Value HostsTable::ChildsAccessor(const Value& row)
1167 {
1168         Host::Ptr host = static_cast<Host::Ptr>(row);
1169
1170         if (!host)
1171                 return Empty;
1172
1173         Array::Ptr childs = new Array();
1174
1175         for (const Checkable::Ptr& child : host->GetChildren()) {
1176                 Host::Ptr child_host = dynamic_pointer_cast<Host>(child);
1177
1178                 if (!child_host)
1179                         continue;
1180
1181                 childs->Add(child_host->GetName());
1182         }
1183
1184         return childs;
1185 }
1186
1187 Value HostsTable::NumServicesAccessor(const Value& row)
1188 {
1189         /* duplicate of TotalServices */
1190         Host::Ptr host = static_cast<Host::Ptr>(row);
1191
1192         if (!host)
1193                 return Empty;
1194
1195         return host->GetTotalServices();
1196 }
1197
1198 Value HostsTable::WorstServiceStateAccessor(const Value& row)
1199 {
1200         Host::Ptr host = static_cast<Host::Ptr>(row);
1201
1202         if (!host)
1203                 return Empty;
1204
1205         Value worst_service = ServiceOK;
1206
1207         for (const Service::Ptr& service : host->GetServices()) {
1208                 if (service->GetState() > worst_service)
1209                         worst_service = service->GetState();
1210         }
1211
1212         return worst_service;
1213 }
1214
1215 Value HostsTable::NumServicesOkAccessor(const Value& row)
1216 {
1217         Host::Ptr host = static_cast<Host::Ptr>(row);
1218
1219         if (!host)
1220                 return Empty;
1221
1222         int num_services = 0;
1223
1224         for (const Service::Ptr& service : host->GetServices()) {
1225                 if (service->GetState() == ServiceOK)
1226                         num_services++;
1227         }
1228
1229         return num_services;
1230 }
1231
1232 Value HostsTable::NumServicesWarnAccessor(const Value& row)
1233 {
1234         Host::Ptr host = static_cast<Host::Ptr>(row);
1235
1236         if (!host)
1237                 return Empty;
1238
1239         int num_services = 0;
1240
1241         for (const Service::Ptr& service : host->GetServices()) {
1242                 if (service->GetState() == ServiceWarning)
1243                         num_services++;
1244         }
1245
1246         return num_services;
1247 }
1248
1249 Value HostsTable::NumServicesCritAccessor(const Value& row)
1250 {
1251         Host::Ptr host = static_cast<Host::Ptr>(row);
1252
1253         if (!host)
1254                 return Empty;
1255
1256         int num_services = 0;
1257
1258         for (const Service::Ptr& service : host->GetServices()) {
1259                 if (service->GetState() == ServiceCritical)
1260                         num_services++;
1261         }
1262
1263         return num_services;
1264 }
1265
1266 Value HostsTable::NumServicesUnknownAccessor(const Value& row)
1267 {
1268         Host::Ptr host = static_cast<Host::Ptr>(row);
1269
1270         if (!host)
1271                 return Empty;
1272
1273         int num_services = 0;
1274
1275         for (const Service::Ptr& service : host->GetServices()) {
1276                 if (service->GetState() == ServiceUnknown)
1277                         num_services++;
1278         }
1279
1280         return num_services;
1281 }
1282
1283 Value HostsTable::NumServicesPendingAccessor(const Value& row)
1284 {
1285         Host::Ptr host = static_cast<Host::Ptr>(row);
1286
1287         if (!host)
1288                 return Empty;
1289
1290         int num_services = 0;
1291
1292         for (const Service::Ptr& service : host->GetServices()) {
1293                 if (!service->GetLastCheckResult())
1294                         num_services++;
1295         }
1296
1297         return num_services;
1298 }
1299
1300 Value HostsTable::WorstServiceHardStateAccessor(const Value& row)
1301 {
1302         Host::Ptr host = static_cast<Host::Ptr>(row);
1303
1304         if (!host)
1305                 return Empty;
1306
1307         Value worst_service = ServiceOK;
1308
1309         for (const Service::Ptr& service : host->GetServices()) {
1310                 if (service->GetStateType() == StateTypeHard) {
1311                         if (service->GetState() > worst_service)
1312                                 worst_service = service->GetState();
1313                 }
1314         }
1315
1316         return worst_service;
1317 }
1318
1319 Value HostsTable::NumServicesHardOkAccessor(const Value& row)
1320 {
1321         Host::Ptr host = static_cast<Host::Ptr>(row);
1322
1323         if (!host)
1324                 return Empty;
1325
1326         int num_services = 0;
1327
1328         for (const Service::Ptr& service : host->GetServices()) {
1329                 if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceOK)
1330                         num_services++;
1331         }
1332
1333         return num_services;
1334 }
1335
1336 Value HostsTable::NumServicesHardWarnAccessor(const Value& row)
1337 {
1338         Host::Ptr host = static_cast<Host::Ptr>(row);
1339
1340         if (!host)
1341                 return Empty;
1342
1343         int num_services = 0;
1344
1345         for (const Service::Ptr& service : host->GetServices()) {
1346                 if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceWarning)
1347                         num_services++;
1348         }
1349
1350         return num_services;
1351 }
1352
1353 Value HostsTable::NumServicesHardCritAccessor(const Value& row)
1354 {
1355         Host::Ptr host = static_cast<Host::Ptr>(row);
1356
1357         if (!host)
1358                 return Empty;
1359
1360         int num_services = 0;
1361
1362         for (const Service::Ptr& service : host->GetServices()) {
1363                 if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceCritical)
1364                         num_services++;
1365         }
1366
1367         return num_services;
1368 }
1369
1370 Value HostsTable::NumServicesHardUnknownAccessor(const Value& row)
1371 {
1372         Host::Ptr host = static_cast<Host::Ptr>(row);
1373
1374         if (!host)
1375                 return Empty;
1376
1377         int num_services = 0;
1378
1379         for (const Service::Ptr& service : host->GetServices()) {
1380                 if (service->GetStateType() == StateTypeHard && service->GetState() == ServiceUnknown)
1381                         num_services++;
1382         }
1383
1384         return num_services;
1385 }
1386
1387 Value HostsTable::HardStateAccessor(const Value& row)
1388 {
1389         Host::Ptr host = static_cast<Host::Ptr>(row);
1390
1391         if (!host)
1392                 return Empty;
1393
1394         if (host->GetState() == HostUp)
1395                 return HostUp;
1396         else if (host->GetStateType() == StateTypeHard)
1397                 return host->GetState();
1398
1399         return host->GetLastHardState();
1400 }
1401
1402 Value HostsTable::StalenessAccessor(const Value& row)
1403 {
1404         Host::Ptr host = static_cast<Host::Ptr>(row);
1405
1406         if (!host)
1407                 return Empty;
1408
1409         if (host->HasBeenChecked() && host->GetLastCheck() > 0)
1410                 return (Utility::GetTime() - host->GetLastCheck()) / (host->GetCheckInterval() * 3600);
1411
1412         return 0.0;
1413 }
1414
1415 Value HostsTable::GroupsAccessor(const Value& row)
1416 {
1417         Host::Ptr host = static_cast<Host::Ptr>(row);
1418
1419         if (!host)
1420                 return Empty;
1421
1422         Array::Ptr groups = host->GetGroups();
1423
1424         if (!groups)
1425                 return Empty;
1426
1427         return groups;
1428 }
1429
1430 Value HostsTable::ContactGroupsAccessor(const Value& row)
1431 {
1432         Host::Ptr host = static_cast<Host::Ptr>(row);
1433
1434         if (!host)
1435                 return Empty;
1436
1437         Array::Ptr contactgroup_names = new Array();
1438
1439         for (const UserGroup::Ptr& usergroup : CompatUtility::GetCheckableNotificationUserGroups(host)) {
1440                 contactgroup_names->Add(usergroup->GetName());
1441         }
1442
1443         return contactgroup_names;
1444 }
1445
1446 Value HostsTable::ServicesAccessor(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                 services->Add(service->GetShortName());
1460         }
1461
1462         return services;
1463 }
1464
1465 Value HostsTable::ServicesWithStateAccessor(const Value& row)
1466 {
1467         Host::Ptr host = static_cast<Host::Ptr>(row);
1468
1469         if (!host)
1470                 return Empty;
1471
1472         std::vector<Service::Ptr> rservices = host->GetServices();
1473
1474         Array::Ptr services = new Array();
1475         services->Reserve(rservices.size());
1476
1477         for (const Service::Ptr& service : rservices) {
1478                 Array::Ptr svc_add = new Array();
1479
1480                 svc_add->Add(service->GetShortName());
1481                 svc_add->Add(service->GetState());
1482                 svc_add->Add(service->HasBeenChecked() ? 1 : 0);
1483                 services->Add(svc_add);
1484         }
1485
1486         return services;
1487 }
1488
1489 Value HostsTable::ServicesWithInfoAccessor(const Value& row)
1490 {
1491         Host::Ptr host = static_cast<Host::Ptr>(row);
1492
1493         if (!host)
1494                 return Empty;
1495
1496         std::vector<Service::Ptr> rservices = host->GetServices();
1497
1498         Array::Ptr services = new Array();
1499         services->Reserve(rservices.size());
1500
1501         for (const Service::Ptr& service : rservices) {
1502                 Array::Ptr svc_add = new Array();
1503
1504                 svc_add->Add(service->GetShortName());
1505                 svc_add->Add(service->GetState());
1506                 svc_add->Add(service->HasBeenChecked() ? 1 : 0);
1507
1508                 String output;
1509                 CheckResult::Ptr cr = service->GetLastCheckResult();
1510
1511                 if (cr)
1512                         output = CompatUtility::GetCheckResultOutput(cr);
1513
1514                 svc_add->Add(output);
1515                 services->Add(svc_add);
1516         }
1517
1518         return services;
1519 }
1520
1521 Value HostsTable::CheckSourceAccessor(const Value& row)
1522 {
1523         Host::Ptr host = static_cast<Host::Ptr>(row);
1524
1525         if (!host)
1526                 return Empty;
1527
1528         CheckResult::Ptr cr = host->GetLastCheckResult();
1529
1530         if (cr)
1531                 return cr->GetCheckSource();
1532
1533         return Empty;
1534 }
1535
1536 Value HostsTable::IsReachableAccessor(const Value& row)
1537 {
1538         Host::Ptr host = static_cast<Host::Ptr>(row);
1539
1540         if (!host)
1541                 return Empty;
1542
1543         return host->IsReachable();
1544 }
1545
1546 Value HostsTable::OriginalAttributesAccessor(const Value& row)
1547 {
1548         Host::Ptr host = static_cast<Host::Ptr>(row);
1549
1550         if (!host)
1551                 return Empty;
1552
1553         return JsonEncode(host->GetOriginalAttributes());
1554 }