]> granicus.if.org Git - icinga2/blob - lib/icinga/externalcommandprocessor.cpp
Remove unused includes
[icinga2] / lib / icinga / externalcommandprocessor.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 "icinga/externalcommandprocessor.hpp"
21 #include "icinga/host.hpp"
22 #include "icinga/service.hpp"
23 #include "icinga/user.hpp"
24 #include "icinga/hostgroup.hpp"
25 #include "icinga/servicegroup.hpp"
26 #include "icinga/pluginutility.hpp"
27 #include "icinga/icingaapplication.hpp"
28 #include "icinga/checkcommand.hpp"
29 #include "icinga/eventcommand.hpp"
30 #include "icinga/notificationcommand.hpp"
31 #include "icinga/compatutility.hpp"
32 #include "remote/apifunction.hpp"
33 #include "base/convert.hpp"
34 #include "base/logger.hpp"
35 #include "base/objectlock.hpp"
36 #include "base/application.hpp"
37 #include "base/utility.hpp"
38 #include "base/exception.hpp"
39 #include <fstream>
40 #include <boost/thread/once.hpp>
41
42 using namespace icinga;
43
44 boost::signals2::signal<void(double, const String&, const std::vector<String>&)> ExternalCommandProcessor::OnNewExternalCommand;
45
46 void ExternalCommandProcessor::Execute(const String& line)
47 {
48         if (line.IsEmpty())
49                 return;
50
51         if (line[0] != '[')
52                 BOOST_THROW_EXCEPTION(std::invalid_argument("Missing timestamp in command: " + line));
53
54         size_t pos = line.FindFirstOf("]");
55
56         if (pos == String::NPos)
57                 BOOST_THROW_EXCEPTION(std::invalid_argument("Missing timestamp in command: " + line));
58
59         String timestamp = line.SubStr(1, pos - 1);
60         String args = line.SubStr(pos + 2, String::NPos);
61
62         double ts = Convert::ToDouble(timestamp);
63
64         if (ts == 0)
65                 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid timestamp in command: " + line));
66
67         std::vector<String> argv = args.Split(";");
68
69         if (argv.empty())
70                 BOOST_THROW_EXCEPTION(std::invalid_argument("Missing arguments in command: " + line));
71
72         std::vector<String> argvExtra(argv.begin() + 1, argv.end());
73         Execute(ts, argv[0], argvExtra);
74 }
75
76 void ExternalCommandProcessor::Execute(double time, const String& command, const std::vector<String>& arguments)
77 {
78         ExternalCommandInfo eci;
79
80         static boost::once_flag once = BOOST_ONCE_INIT;
81
82         boost::call_once(once, []() {
83                 RegisterCommands();
84         });
85
86         {
87                 boost::mutex::scoped_lock lock(GetMutex());
88
89                 auto it = GetCommands().find(command);
90
91                 if (it == GetCommands().end())
92                         BOOST_THROW_EXCEPTION(std::invalid_argument("The external command '" + command + "' does not exist."));
93
94                 eci = it->second;
95         }
96
97         if (arguments.size() < eci.MinArgs)
98                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected " + Convert::ToString(eci.MinArgs) + " arguments"));
99
100         size_t argnum = std::min(arguments.size(), eci.MaxArgs);
101
102         std::vector<String> realArguments;
103         realArguments.resize(argnum);
104
105         if (argnum > 0) {
106                 std::copy(arguments.begin(), arguments.begin() + argnum - 1, realArguments.begin());
107
108                 String last_argument;
109                 for (std::vector<String>::size_type i = argnum - 1; i < arguments.size(); i++) {
110                         if (!last_argument.IsEmpty())
111                                 last_argument += ";";
112
113                         last_argument += arguments[i];
114                 }
115
116                 realArguments[argnum - 1] = last_argument;
117         }
118
119         OnNewExternalCommand(time, command, realArguments);
120
121         eci.Callback(time, realArguments);
122 }
123
124 void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandCallback& callback, size_t minArgs, size_t maxArgs)
125 {
126         boost::mutex::scoped_lock lock(GetMutex());
127         ExternalCommandInfo eci;
128         eci.Callback = callback;
129         eci.MinArgs = minArgs;
130         eci.MaxArgs = (maxArgs == UINT_MAX) ? minArgs : maxArgs;
131         GetCommands()[command] = eci;
132 }
133
134 void ExternalCommandProcessor::RegisterCommands()
135 {
136         RegisterCommand("PROCESS_HOST_CHECK_RESULT", &ExternalCommandProcessor::ProcessHostCheckResult, 3);
137         RegisterCommand("PROCESS_SERVICE_CHECK_RESULT", &ExternalCommandProcessor::ProcessServiceCheckResult, 4);
138         RegisterCommand("SCHEDULE_HOST_CHECK", &ExternalCommandProcessor::ScheduleHostCheck, 2);
139         RegisterCommand("SCHEDULE_FORCED_HOST_CHECK", &ExternalCommandProcessor::ScheduleForcedHostCheck, 2);
140         RegisterCommand("SCHEDULE_SVC_CHECK", &ExternalCommandProcessor::ScheduleSvcCheck, 3);
141         RegisterCommand("SCHEDULE_FORCED_SVC_CHECK", &ExternalCommandProcessor::ScheduleForcedSvcCheck, 3);
142         RegisterCommand("ENABLE_HOST_CHECK", &ExternalCommandProcessor::EnableHostCheck, 1);
143         RegisterCommand("DISABLE_HOST_CHECK", &ExternalCommandProcessor::DisableHostCheck, 1);
144         RegisterCommand("ENABLE_SVC_CHECK", &ExternalCommandProcessor::EnableSvcCheck, 2);
145         RegisterCommand("DISABLE_SVC_CHECK", &ExternalCommandProcessor::DisableSvcCheck, 2);
146         RegisterCommand("SHUTDOWN_PROCESS", &ExternalCommandProcessor::ShutdownProcess);
147         RegisterCommand("RESTART_PROCESS", &ExternalCommandProcessor::RestartProcess);
148         RegisterCommand("SCHEDULE_FORCED_HOST_SVC_CHECKS", &ExternalCommandProcessor::ScheduleForcedHostSvcChecks, 2);
149         RegisterCommand("SCHEDULE_HOST_SVC_CHECKS", &ExternalCommandProcessor::ScheduleHostSvcChecks, 2);
150         RegisterCommand("ENABLE_HOST_SVC_CHECKS", &ExternalCommandProcessor::EnableHostSvcChecks, 1);
151         RegisterCommand("DISABLE_HOST_SVC_CHECKS", &ExternalCommandProcessor::DisableHostSvcChecks, 1);
152         RegisterCommand("ACKNOWLEDGE_SVC_PROBLEM", &ExternalCommandProcessor::AcknowledgeSvcProblem, 7);
153         RegisterCommand("ACKNOWLEDGE_SVC_PROBLEM_EXPIRE", &ExternalCommandProcessor::AcknowledgeSvcProblemExpire, 8);
154         RegisterCommand("REMOVE_SVC_ACKNOWLEDGEMENT", &ExternalCommandProcessor::RemoveSvcAcknowledgement, 2);
155         RegisterCommand("ACKNOWLEDGE_HOST_PROBLEM", &ExternalCommandProcessor::AcknowledgeHostProblem, 6);
156         RegisterCommand("ACKNOWLEDGE_HOST_PROBLEM_EXPIRE", &ExternalCommandProcessor::AcknowledgeHostProblemExpire, 7);
157         RegisterCommand("REMOVE_HOST_ACKNOWLEDGEMENT", &ExternalCommandProcessor::RemoveHostAcknowledgement, 1);
158         RegisterCommand("DISABLE_HOST_FLAP_DETECTION", &ExternalCommandProcessor::DisableHostFlapping, 1);
159         RegisterCommand("ENABLE_HOST_FLAP_DETECTION", &ExternalCommandProcessor::EnableHostFlapping, 1);
160         RegisterCommand("DISABLE_SVC_FLAP_DETECTION", &ExternalCommandProcessor::DisableSvcFlapping, 2);
161         RegisterCommand("ENABLE_SVC_FLAP_DETECTION", &ExternalCommandProcessor::EnableSvcFlapping, 2);
162         RegisterCommand("ENABLE_HOSTGROUP_SVC_CHECKS", &ExternalCommandProcessor::EnableHostgroupSvcChecks, 1);
163         RegisterCommand("DISABLE_HOSTGROUP_SVC_CHECKS", &ExternalCommandProcessor::DisableHostgroupSvcChecks, 1);
164         RegisterCommand("ENABLE_SERVICEGROUP_SVC_CHECKS", &ExternalCommandProcessor::EnableServicegroupSvcChecks, 1);
165         RegisterCommand("DISABLE_SERVICEGROUP_SVC_CHECKS", &ExternalCommandProcessor::DisableServicegroupSvcChecks, 1);
166         RegisterCommand("ENABLE_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::EnablePassiveHostChecks, 1);
167         RegisterCommand("DISABLE_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::DisablePassiveHostChecks, 1);
168         RegisterCommand("ENABLE_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnablePassiveSvcChecks, 2);
169         RegisterCommand("DISABLE_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisablePassiveSvcChecks, 2);
170         RegisterCommand("ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnableServicegroupPassiveSvcChecks, 1);
171         RegisterCommand("DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisableServicegroupPassiveSvcChecks, 1);
172         RegisterCommand("ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnableHostgroupPassiveSvcChecks, 1);
173         RegisterCommand("DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks, 1);
174         RegisterCommand("PROCESS_FILE", &ExternalCommandProcessor::ProcessFile, 2);
175         RegisterCommand("SCHEDULE_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleSvcDowntime, 9);
176         RegisterCommand("DEL_SVC_DOWNTIME", &ExternalCommandProcessor::DelSvcDowntime, 1);
177         RegisterCommand("SCHEDULE_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleHostDowntime, 8);
178         RegisterCommand("SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleAndPropagateHostDowntime, 8);
179         RegisterCommand("SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime, 8);
180         RegisterCommand("DEL_HOST_DOWNTIME", &ExternalCommandProcessor::DelHostDowntime, 1);
181         RegisterCommand("DEL_DOWNTIME_BY_HOST_NAME", &ExternalCommandProcessor::DelDowntimeByHostName, 1, 4);
182         RegisterCommand("SCHEDULE_HOST_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleHostSvcDowntime, 8);
183         RegisterCommand("SCHEDULE_HOSTGROUP_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleHostgroupHostDowntime, 8);
184         RegisterCommand("SCHEDULE_HOSTGROUP_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleHostgroupSvcDowntime, 8);
185         RegisterCommand("SCHEDULE_SERVICEGROUP_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleServicegroupHostDowntime, 8);
186         RegisterCommand("SCHEDULE_SERVICEGROUP_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleServicegroupSvcDowntime, 8);
187         RegisterCommand("ADD_HOST_COMMENT", &ExternalCommandProcessor::AddHostComment, 4);
188         RegisterCommand("DEL_HOST_COMMENT", &ExternalCommandProcessor::DelHostComment, 1);
189         RegisterCommand("ADD_SVC_COMMENT", &ExternalCommandProcessor::AddSvcComment, 5);
190         RegisterCommand("DEL_SVC_COMMENT", &ExternalCommandProcessor::DelSvcComment, 1);
191         RegisterCommand("DEL_ALL_HOST_COMMENTS", &ExternalCommandProcessor::DelAllHostComments, 1);
192         RegisterCommand("DEL_ALL_SVC_COMMENTS", &ExternalCommandProcessor::DelAllSvcComments, 2);
193         RegisterCommand("SEND_CUSTOM_HOST_NOTIFICATION", &ExternalCommandProcessor::SendCustomHostNotification, 4);
194         RegisterCommand("SEND_CUSTOM_SVC_NOTIFICATION", &ExternalCommandProcessor::SendCustomSvcNotification, 5);
195         RegisterCommand("DELAY_HOST_NOTIFICATION", &ExternalCommandProcessor::DelayHostNotification, 2);
196         RegisterCommand("DELAY_SVC_NOTIFICATION", &ExternalCommandProcessor::DelaySvcNotification, 3);
197         RegisterCommand("ENABLE_HOST_NOTIFICATIONS", &ExternalCommandProcessor::EnableHostNotifications, 1);
198         RegisterCommand("DISABLE_HOST_NOTIFICATIONS", &ExternalCommandProcessor::DisableHostNotifications, 1);
199         RegisterCommand("ENABLE_SVC_NOTIFICATIONS", &ExternalCommandProcessor::EnableSvcNotifications, 2);
200         RegisterCommand("DISABLE_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableSvcNotifications, 2);
201         RegisterCommand("ENABLE_HOST_SVC_NOTIFICATIONS", &ExternalCommandProcessor::EnableHostSvcNotifications, 1);
202         RegisterCommand("DISABLE_HOST_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableHostSvcNotifications, 1);
203         RegisterCommand("DISABLE_HOSTGROUP_HOST_CHECKS", &ExternalCommandProcessor::DisableHostgroupHostChecks, 1);
204         RegisterCommand("DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::DisableHostgroupPassiveHostChecks, 1);
205         RegisterCommand("DISABLE_SERVICEGROUP_HOST_CHECKS", &ExternalCommandProcessor::DisableServicegroupHostChecks, 1);
206         RegisterCommand("DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::DisableServicegroupPassiveHostChecks, 1);
207         RegisterCommand("ENABLE_HOSTGROUP_HOST_CHECKS", &ExternalCommandProcessor::EnableHostgroupHostChecks, 1);
208         RegisterCommand("ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::EnableHostgroupPassiveHostChecks, 1);
209         RegisterCommand("ENABLE_SERVICEGROUP_HOST_CHECKS", &ExternalCommandProcessor::EnableServicegroupHostChecks, 1);
210         RegisterCommand("ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::EnableServicegroupPassiveHostChecks, 1);
211         RegisterCommand("ENABLE_NOTIFICATIONS", &ExternalCommandProcessor::EnableNotifications);
212         RegisterCommand("DISABLE_NOTIFICATIONS", &ExternalCommandProcessor::DisableNotifications);
213         RegisterCommand("ENABLE_FLAP_DETECTION", &ExternalCommandProcessor::EnableFlapDetection);
214         RegisterCommand("DISABLE_FLAP_DETECTION", &ExternalCommandProcessor::DisableFlapDetection);
215         RegisterCommand("ENABLE_EVENT_HANDLERS", &ExternalCommandProcessor::EnableEventHandlers);
216         RegisterCommand("DISABLE_EVENT_HANDLERS", &ExternalCommandProcessor::DisableEventHandlers);
217         RegisterCommand("ENABLE_PERFORMANCE_DATA", &ExternalCommandProcessor::EnablePerformanceData);
218         RegisterCommand("DISABLE_PERFORMANCE_DATA", &ExternalCommandProcessor::DisablePerformanceData);
219         RegisterCommand("START_EXECUTING_SVC_CHECKS", &ExternalCommandProcessor::StartExecutingSvcChecks);
220         RegisterCommand("STOP_EXECUTING_SVC_CHECKS", &ExternalCommandProcessor::StopExecutingSvcChecks);
221         RegisterCommand("START_EXECUTING_HOST_CHECKS", &ExternalCommandProcessor::StartExecutingHostChecks);
222         RegisterCommand("STOP_EXECUTING_HOST_CHECKS", &ExternalCommandProcessor::StopExecutingHostChecks);
223         RegisterCommand("CHANGE_NORMAL_SVC_CHECK_INTERVAL", &ExternalCommandProcessor::ChangeNormalSvcCheckInterval, 3);
224         RegisterCommand("CHANGE_NORMAL_HOST_CHECK_INTERVAL", &ExternalCommandProcessor::ChangeNormalHostCheckInterval, 2);
225         RegisterCommand("CHANGE_RETRY_SVC_CHECK_INTERVAL", &ExternalCommandProcessor::ChangeRetrySvcCheckInterval, 3);
226         RegisterCommand("CHANGE_RETRY_HOST_CHECK_INTERVAL", &ExternalCommandProcessor::ChangeRetryHostCheckInterval, 2);
227         RegisterCommand("ENABLE_HOST_EVENT_HANDLER", &ExternalCommandProcessor::EnableHostEventHandler, 1);
228         RegisterCommand("DISABLE_HOST_EVENT_HANDLER", &ExternalCommandProcessor::DisableHostEventHandler, 1);
229         RegisterCommand("ENABLE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::EnableSvcEventHandler, 2);
230         RegisterCommand("DISABLE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::DisableSvcEventHandler, 2);
231         RegisterCommand("CHANGE_HOST_EVENT_HANDLER", &ExternalCommandProcessor::ChangeHostEventHandler, 2);
232         RegisterCommand("CHANGE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::ChangeSvcEventHandler, 3);
233         RegisterCommand("CHANGE_HOST_CHECK_COMMAND", &ExternalCommandProcessor::ChangeHostCheckCommand, 2);
234         RegisterCommand("CHANGE_SVC_CHECK_COMMAND", &ExternalCommandProcessor::ChangeSvcCheckCommand, 3);
235         RegisterCommand("CHANGE_MAX_HOST_CHECK_ATTEMPTS", &ExternalCommandProcessor::ChangeMaxHostCheckAttempts, 2);
236         RegisterCommand("CHANGE_MAX_SVC_CHECK_ATTEMPTS", &ExternalCommandProcessor::ChangeMaxSvcCheckAttempts, 3);
237         RegisterCommand("CHANGE_HOST_CHECK_TIMEPERIOD", &ExternalCommandProcessor::ChangeHostCheckTimeperiod, 2);
238         RegisterCommand("CHANGE_SVC_CHECK_TIMEPERIOD", &ExternalCommandProcessor::ChangeSvcCheckTimeperiod, 3);
239         RegisterCommand("CHANGE_CUSTOM_HOST_VAR", &ExternalCommandProcessor::ChangeCustomHostVar, 3);
240         RegisterCommand("CHANGE_CUSTOM_SVC_VAR", &ExternalCommandProcessor::ChangeCustomSvcVar, 4);
241         RegisterCommand("CHANGE_CUSTOM_USER_VAR", &ExternalCommandProcessor::ChangeCustomUserVar, 3);
242         RegisterCommand("CHANGE_CUSTOM_CHECKCOMMAND_VAR", &ExternalCommandProcessor::ChangeCustomCheckcommandVar, 3);
243         RegisterCommand("CHANGE_CUSTOM_EVENTCOMMAND_VAR", &ExternalCommandProcessor::ChangeCustomEventcommandVar, 3);
244         RegisterCommand("CHANGE_CUSTOM_NOTIFICATIONCOMMAND_VAR", &ExternalCommandProcessor::ChangeCustomNotificationcommandVar, 3);
245
246         RegisterCommand("ENABLE_HOSTGROUP_HOST_NOTIFICATIONS", &ExternalCommandProcessor::EnableHostgroupHostNotifications, 1);
247         RegisterCommand("ENABLE_HOSTGROUP_SVC_NOTIFICATIONS", &ExternalCommandProcessor::EnableHostgroupSvcNotifications, 1);
248         RegisterCommand("DISABLE_HOSTGROUP_HOST_NOTIFICATIONS", &ExternalCommandProcessor::DisableHostgroupHostNotifications, 1);
249         RegisterCommand("DISABLE_HOSTGROUP_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableHostgroupSvcNotifications, 1);
250         RegisterCommand("ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS", &ExternalCommandProcessor::EnableServicegroupHostNotifications, 1);
251         RegisterCommand("DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS", &ExternalCommandProcessor::DisableServicegroupHostNotifications, 1);
252         RegisterCommand("ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS", &ExternalCommandProcessor::EnableServicegroupSvcNotifications, 1);
253         RegisterCommand("DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableServicegroupSvcNotifications, 1);
254 }
255
256 void ExternalCommandProcessor::ExecuteFromFile(const String& line, std::deque< std::vector<String> >& file_queue)
257 {
258         if (line.IsEmpty())
259                 return;
260
261         if (line[0] != '[')
262                 BOOST_THROW_EXCEPTION(std::invalid_argument("Missing timestamp in command: " + line));
263
264         size_t pos = line.FindFirstOf("]");
265
266         if (pos == String::NPos)
267                 BOOST_THROW_EXCEPTION(std::invalid_argument("Missing timestamp in command: " + line));
268
269         String timestamp = line.SubStr(1, pos - 1);
270         String args = line.SubStr(pos + 2, String::NPos);
271
272         double ts = Convert::ToDouble(timestamp);
273
274         if (ts == 0)
275                 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid timestamp in command: " + line));
276
277         std::vector<String> argv = args.Split(";");
278
279         if (argv.empty())
280                 BOOST_THROW_EXCEPTION(std::invalid_argument("Missing arguments in command: " + line));
281
282         std::vector<String> argvExtra(argv.begin() + 1, argv.end());
283
284         if (argv[0] == "PROCESS_FILE") {
285                 Log(LogDebug, "ExternalCommandProcessor")
286                         << "Enqueing external command file " << argvExtra[0];
287                 file_queue.push_back(argvExtra);
288         } else {
289                 Execute(ts, argv[0], argvExtra);
290         }
291 }
292
293 void ExternalCommandProcessor::ProcessHostCheckResult(double time, const std::vector<String>& arguments)
294 {
295         Host::Ptr host = Host::GetByName(arguments[0]);
296
297         if (!host)
298                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot process passive host check result for non-existent host '" + arguments[0] + "'"));
299
300         if (!host->GetEnablePassiveChecks())
301                 BOOST_THROW_EXCEPTION(std::invalid_argument("Got passive check result for host '" + arguments[0] + "' which has passive checks disabled."));
302
303         int exitStatus = Convert::ToDouble(arguments[1]);
304         CheckResult::Ptr result = new CheckResult();
305         std::pair<String, String> co = PluginUtility::ParseCheckOutput(arguments[2]);
306         result->SetOutput(co.first);
307         result->SetPerformanceData(PluginUtility::SplitPerfdata(co.second));
308
309         ServiceState state;
310
311         if (exitStatus == 0)
312                 state = ServiceOK;
313         else if (exitStatus == 1)
314                 state = ServiceCritical;
315         else
316                 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid status code: " + arguments[1]));
317
318         result->SetState(state);
319
320         result->SetScheduleStart(time);
321         result->SetScheduleEnd(time);
322         result->SetExecutionStart(time);
323         result->SetExecutionEnd(time);
324
325         /* Mark this check result as passive. */
326         result->SetActive(false);
327
328         Log(LogNotice, "ExternalCommandProcessor")
329                 << "Processing passive check result for host '" << arguments[0] << "'";
330
331         host->ProcessCheckResult(result);
332 }
333
334 void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const std::vector<String>& arguments)
335 {
336         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
337
338         if (!service)
339                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot process passive service check result for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
340
341         if (!service->GetEnablePassiveChecks())
342                 BOOST_THROW_EXCEPTION(std::invalid_argument("Got passive check result for service '" + arguments[1] + "' which has passive checks disabled."));
343
344         int exitStatus = Convert::ToDouble(arguments[2]);
345         CheckResult::Ptr result = new CheckResult();
346         String output = CompatUtility::UnEscapeString(arguments[3]);
347         std::pair<String, String> co = PluginUtility::ParseCheckOutput(output);
348         result->SetOutput(co.first);
349         result->SetPerformanceData(PluginUtility::SplitPerfdata(co.second));
350         result->SetState(PluginUtility::ExitStatusToState(exitStatus));
351
352         result->SetScheduleStart(time);
353         result->SetScheduleEnd(time);
354         result->SetExecutionStart(time);
355         result->SetExecutionEnd(time);
356
357         /* Mark this check result as passive. */
358         result->SetActive(false);
359
360         Log(LogNotice, "ExternalCommandProcessor")
361                 << "Processing passive check result for service '" << arguments[1] << "'";
362
363         service->ProcessCheckResult(result);
364 }
365
366 void ExternalCommandProcessor::ScheduleHostCheck(double, const std::vector<String>& arguments)
367 {
368         Host::Ptr host = Host::GetByName(arguments[0]);
369
370         if (!host)
371                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot reschedule host check for non-existent host '" + arguments[0] + "'"));
372
373         double planned_check = Convert::ToDouble(arguments[1]);
374
375         if (planned_check > host->GetNextCheck()) {
376                 Log(LogNotice, "ExternalCommandProcessor")
377                         << "Ignoring reschedule request for host '"
378                         << arguments[0] << "' (next check is already sooner than requested check time)";
379                 return;
380         }
381
382         Log(LogNotice, "ExternalCommandProcessor")
383                 << "Rescheduling next check for host '" << arguments[0] << "'";
384
385         if (planned_check < Utility::GetTime())
386                 planned_check = Utility::GetTime();
387
388         host->SetNextCheck(planned_check);
389
390         /* trigger update event for DB IDO */
391         Checkable::OnNextCheckUpdated(host);
392 }
393
394 void ExternalCommandProcessor::ScheduleForcedHostCheck(double, const std::vector<String>& arguments)
395 {
396         Host::Ptr host = Host::GetByName(arguments[0]);
397
398         if (!host)
399                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot reschedule forced host check for non-existent host '" + arguments[0] + "'"));
400
401         Log(LogNotice, "ExternalCommandProcessor")
402                 << "Rescheduling next check for host '" << arguments[0] << "'";
403
404         host->SetForceNextCheck(true);
405         host->SetNextCheck(Convert::ToDouble(arguments[1]));
406
407         /* trigger update event for DB IDO */
408         Checkable::OnNextCheckUpdated(host);
409 }
410
411 void ExternalCommandProcessor::ScheduleSvcCheck(double, const std::vector<String>& arguments)
412 {
413         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
414
415         if (!service)
416                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot reschedule service check for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
417
418         double planned_check = Convert::ToDouble(arguments[2]);
419
420         if (planned_check > service->GetNextCheck()) {
421                 Log(LogNotice, "ExternalCommandProcessor")
422                         << "Ignoring reschedule request for service '"
423                         << arguments[1] << "' (next check is already sooner than requested check time)";
424                 return;
425         }
426
427         Log(LogNotice, "ExternalCommandProcessor")
428                 << "Rescheduling next check for service '" << arguments[1] << "'";
429
430         if (planned_check < Utility::GetTime())
431                 planned_check = Utility::GetTime();
432
433         service->SetNextCheck(planned_check);
434
435         /* trigger update event for DB IDO */
436         Checkable::OnNextCheckUpdated(service);
437 }
438
439 void ExternalCommandProcessor::ScheduleForcedSvcCheck(double, const std::vector<String>& arguments)
440 {
441         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
442
443         if (!service)
444                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot reschedule forced service check for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
445
446         Log(LogNotice, "ExternalCommandProcessor")
447                 << "Rescheduling next check for service '" << arguments[1] << "'";
448
449         service->SetForceNextCheck(true);
450         service->SetNextCheck(Convert::ToDouble(arguments[2]));
451
452         /* trigger update event for DB IDO */
453         Checkable::OnNextCheckUpdated(service);
454 }
455
456 void ExternalCommandProcessor::EnableHostCheck(double, const std::vector<String>& arguments)
457 {
458         Host::Ptr host = Host::GetByName(arguments[0]);
459
460         if (!host)
461                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable host checks for non-existent host '" + arguments[0] + "'"));
462
463         Log(LogNotice, "ExternalCommandProcessor")
464                 << "Enabling active checks for host '" << arguments[0] << "'";
465
466         host->ModifyAttribute("enable_active_checks", true);
467 }
468
469 void ExternalCommandProcessor::DisableHostCheck(double, const std::vector<String>& arguments)
470 {
471         Host::Ptr host = Host::GetByName(arguments[0]);
472
473         if (!host)
474                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable host check non-existent host '" + arguments[0] + "'"));
475
476         Log(LogNotice, "ExternalCommandProcessor")
477                 << "Disabling active checks for host '" << arguments[0] << "'";
478
479         host->ModifyAttribute("enable_active_checks", false);
480 }
481
482 void ExternalCommandProcessor::EnableSvcCheck(double, const std::vector<String>& arguments)
483 {
484         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
485
486         if (!service)
487                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable service check for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
488
489         Log(LogNotice, "ExternalCommandProcessor")
490                 << "Enabling active checks for service '" << arguments[1] << "'";
491
492         service->ModifyAttribute("enable_active_checks", true);
493 }
494
495 void ExternalCommandProcessor::DisableSvcCheck(double, const std::vector<String>& arguments)
496 {
497         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
498
499         if (!service)
500                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable service check for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
501
502         Log(LogNotice, "ExternalCommandProcessor")
503                 << "Disabling active checks for service '" << arguments[1] << "'";
504
505         service->ModifyAttribute("enable_active_checks", false);
506 }
507
508 void ExternalCommandProcessor::ShutdownProcess(double, const std::vector<String>&)
509 {
510         Log(LogNotice, "ExternalCommandProcessor", "Shutting down Icinga via external command.");
511         Application::RequestShutdown();
512 }
513
514 void ExternalCommandProcessor::RestartProcess(double, const std::vector<String>&)
515 {
516         Log(LogNotice, "ExternalCommandProcessor", "Restarting Icinga via external command.");
517         Application::RequestRestart();
518 }
519
520 void ExternalCommandProcessor::ScheduleForcedHostSvcChecks(double, const std::vector<String>& arguments)
521 {
522         double planned_check = Convert::ToDouble(arguments[1]);
523
524         Host::Ptr host = Host::GetByName(arguments[0]);
525
526         if (!host)
527                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot reschedule forced host service checks for non-existent host '" + arguments[0] + "'"));
528
529         for (const Service::Ptr& service : host->GetServices()) {
530                 Log(LogNotice, "ExternalCommandProcessor")
531                         << "Rescheduling next check for service '" << service->GetName() << "'";
532
533                 service->SetNextCheck(planned_check);
534                 service->SetForceNextCheck(true);
535
536                 /* trigger update event for DB IDO */
537                 Checkable::OnNextCheckUpdated(service);
538         }
539 }
540
541 void ExternalCommandProcessor::ScheduleHostSvcChecks(double, const std::vector<String>& arguments)
542 {
543         double planned_check = Convert::ToDouble(arguments[1]);
544
545         Host::Ptr host = Host::GetByName(arguments[0]);
546
547         if (!host)
548                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot reschedule host service checks for non-existent host '" + arguments[0] + "'"));
549
550         if (planned_check < Utility::GetTime())
551                 planned_check = Utility::GetTime();
552
553         for (const Service::Ptr& service : host->GetServices()) {
554                 if (planned_check > service->GetNextCheck()) {
555                         Log(LogNotice, "ExternalCommandProcessor")
556                                 << "Ignoring reschedule request for service '"
557                                 << service->GetName() << "' (next check is already sooner than requested check time)";
558                         continue;
559                 }
560
561                 Log(LogNotice, "ExternalCommandProcessor")
562                         << "Rescheduling next check for service '" << service->GetName() << "'";
563
564                 service->SetNextCheck(planned_check);
565
566                 /* trigger update event for DB IDO */
567                 Checkable::OnNextCheckUpdated(service);
568         }
569 }
570
571 void ExternalCommandProcessor::EnableHostSvcChecks(double, const std::vector<String>& arguments)
572 {
573         Host::Ptr host = Host::GetByName(arguments[0]);
574
575         if (!host)
576                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable host service checks for non-existent host '" + arguments[0] + "'"));
577
578         for (const Service::Ptr& service : host->GetServices()) {
579                 Log(LogNotice, "ExternalCommandProcessor")
580                         << "Enabling active checks for service '" << service->GetName() << "'";
581
582                 service->ModifyAttribute("enable_active_checks", true);
583         }
584 }
585
586 void ExternalCommandProcessor::DisableHostSvcChecks(double, const std::vector<String>& arguments)
587 {
588         Host::Ptr host = Host::GetByName(arguments[0]);
589
590         if (!host)
591                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable host service checks for non-existent host '" + arguments[0] + "'"));
592
593         for (const Service::Ptr& service : host->GetServices()) {
594                 Log(LogNotice, "ExternalCommandProcessor")
595                         << "Disabling active checks for service '" << service->GetName() << "'";
596
597                 service->ModifyAttribute("enable_active_checks", false);
598         }
599 }
600
601 void ExternalCommandProcessor::AcknowledgeSvcProblem(double, const std::vector<String>& arguments)
602 {
603         bool sticky = (Convert::ToLong(arguments[2]) == 2 ? true : false);
604         bool notify = (Convert::ToLong(arguments[3]) > 0 ? true : false);
605         bool persistent = (Convert::ToLong(arguments[4]) > 0 ? true : false);
606
607         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
608
609         if (!service)
610                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot acknowledge service problem for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
611
612         if (service->GetState() == ServiceOK)
613                 BOOST_THROW_EXCEPTION(std::invalid_argument("The service '" + arguments[1] + "' is OK."));
614
615         Log(LogNotice, "ExternalCommandProcessor")
616                 << "Setting acknowledgement for service '" << service->GetName() << "'" << (notify ? "" : ". Disabled notification");
617
618         Comment::AddComment(service, CommentAcknowledgement, arguments[5], arguments[6], persistent, 0);
619         service->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, persistent);
620 }
621
622 void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const std::vector<String>& arguments)
623 {
624         bool sticky = (Convert::ToLong(arguments[2]) == 2 ? true : false);
625         bool notify = (Convert::ToLong(arguments[3]) > 0 ? true : false);
626         bool persistent = (Convert::ToLong(arguments[4]) > 0 ? true : false);
627         double timestamp = Convert::ToDouble(arguments[5]);
628
629         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
630
631         if (!service)
632                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot acknowledge service problem with expire time for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
633
634         if (service->GetState() == ServiceOK)
635                 BOOST_THROW_EXCEPTION(std::invalid_argument("The service '" + arguments[1] + "' is OK."));
636
637         if (timestamp != 0 && timestamp <= Utility::GetTime())
638                 BOOST_THROW_EXCEPTION(std::invalid_argument("Acknowledgement expire time must be in the future for service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
639
640         Log(LogNotice, "ExternalCommandProcessor")
641                 << "Setting timed acknowledgement for service '" << service->GetName() << "'" << (notify ? "" : ". Disabled notification");
642
643         Comment::AddComment(service, CommentAcknowledgement, arguments[6], arguments[7], persistent, timestamp);
644         service->AcknowledgeProblem(arguments[6], arguments[7], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, persistent, timestamp);
645 }
646
647 void ExternalCommandProcessor::RemoveSvcAcknowledgement(double, const std::vector<String>& arguments)
648 {
649         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
650
651         if (!service)
652                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot remove service acknowledgement for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
653
654         Log(LogNotice, "ExternalCommandProcessor")
655                 << "Removing acknowledgement for service '" << service->GetName() << "'";
656
657         {
658                 ObjectLock olock(service);
659                 service->ClearAcknowledgement();
660         }
661
662         service->RemoveCommentsByType(CommentAcknowledgement);
663 }
664
665 void ExternalCommandProcessor::AcknowledgeHostProblem(double, const std::vector<String>& arguments)
666 {
667         bool sticky = (Convert::ToLong(arguments[1]) == 2 ? true : false);
668         bool notify = (Convert::ToLong(arguments[2]) > 0 ? true : false);
669         bool persistent = (Convert::ToLong(arguments[3]) > 0 ? true : false);
670
671         Host::Ptr host = Host::GetByName(arguments[0]);
672
673         if (!host)
674                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot acknowledge host problem for non-existent host '" + arguments[0] + "'"));
675
676         Log(LogNotice, "ExternalCommandProcessor")
677                 << "Setting acknowledgement for host '" << host->GetName() << "'" << (notify ? "" : ". Disabled notification");
678
679         if (host->GetState() == HostUp)
680                 BOOST_THROW_EXCEPTION(std::invalid_argument("The host '" + arguments[0] + "' is OK."));
681
682         Comment::AddComment(host, CommentAcknowledgement, arguments[4], arguments[5], persistent, 0);
683         host->AcknowledgeProblem(arguments[4], arguments[5], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, persistent);
684 }
685
686 void ExternalCommandProcessor::AcknowledgeHostProblemExpire(double, const std::vector<String>& arguments)
687 {
688         bool sticky = (Convert::ToLong(arguments[1]) == 2 ? true : false);
689         bool notify = (Convert::ToLong(arguments[2]) > 0 ? true : false);
690         bool persistent = (Convert::ToLong(arguments[3]) > 0 ? true : false);
691         double timestamp = Convert::ToDouble(arguments[4]);
692
693         Host::Ptr host = Host::GetByName(arguments[0]);
694
695         if (!host)
696                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot acknowledge host problem with expire time for non-existent host '" + arguments[0] + "'"));
697
698         Log(LogNotice, "ExternalCommandProcessor")
699                 << "Setting timed acknowledgement for host '" << host->GetName() << "'" << (notify ? "" : ". Disabled notification");
700
701         if (host->GetState() == HostUp)
702                 BOOST_THROW_EXCEPTION(std::invalid_argument("The host '" + arguments[0] + "' is OK."));
703
704         if (timestamp != 0 && timestamp <= Utility::GetTime())
705                 BOOST_THROW_EXCEPTION(std::invalid_argument("Acknowledgement expire time must be in the future for host '" + arguments[0] + "'"));
706
707         Comment::AddComment(host, CommentAcknowledgement, arguments[5], arguments[6], persistent, timestamp);
708         host->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, persistent, timestamp);
709 }
710
711 void ExternalCommandProcessor::RemoveHostAcknowledgement(double, const std::vector<String>& arguments)
712 {
713         Host::Ptr host = Host::GetByName(arguments[0]);
714
715         if (!host)
716                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot remove acknowledgement for non-existent host '" + arguments[0] + "'"));
717
718         Log(LogNotice, "ExternalCommandProcessor")
719                 << "Removing acknowledgement for host '" << host->GetName() << "'";
720
721         {
722                 ObjectLock olock(host);
723                 host->ClearAcknowledgement();
724         }
725         host->RemoveCommentsByType(CommentAcknowledgement);
726 }
727
728 void ExternalCommandProcessor::EnableHostgroupSvcChecks(double, const std::vector<String>& arguments)
729 {
730         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
731
732         if (!hg)
733                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable hostgroup service checks for non-existent hostgroup '" + arguments[0] + "'"));
734
735         for (const Host::Ptr& host : hg->GetMembers()) {
736                 for (const Service::Ptr& service : host->GetServices()) {
737                         Log(LogNotice, "ExternalCommandProcessor")
738                                 << "Enabling active checks for service '" << service->GetName() << "'";
739
740                         service->ModifyAttribute("enable_active_checks", true);
741                 }
742         }
743 }
744
745 void ExternalCommandProcessor::DisableHostgroupSvcChecks(double, const std::vector<String>& arguments)
746 {
747         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
748
749         if (!hg)
750                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable hostgroup service checks for non-existent hostgroup '" + arguments[0] + "'"));
751
752         for (const Host::Ptr& host : hg->GetMembers()) {
753                 for (const Service::Ptr& service : host->GetServices()) {
754                         Log(LogNotice, "ExternalCommandProcessor")
755                                 << "Disabling active checks for service '" << service->GetName() << "'";
756
757                         service->ModifyAttribute("enable_active_checks", false);
758                 }
759         }
760 }
761
762 void ExternalCommandProcessor::EnableServicegroupSvcChecks(double, const std::vector<String>& arguments)
763 {
764         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
765
766         if (!sg)
767                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable servicegroup service checks for non-existent servicegroup '" + arguments[0] + "'"));
768
769         for (const Service::Ptr& service : sg->GetMembers()) {
770                 Log(LogNotice, "ExternalCommandProcessor")
771                         << "Enabling active checks for service '" << service->GetName() << "'";
772
773                 service->ModifyAttribute("enable_active_checks", true);
774         }
775 }
776
777 void ExternalCommandProcessor::DisableServicegroupSvcChecks(double, const std::vector<String>& arguments)
778 {
779         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
780
781         if (!sg)
782                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable servicegroup service checks for non-existent servicegroup '" + arguments[0] + "'"));
783
784         for (const Service::Ptr& service : sg->GetMembers()) {
785                 Log(LogNotice, "ExternalCommandProcessor")
786                         << "Disabling active checks for service '" << service->GetName() << "'";
787
788                 service->ModifyAttribute("enable_active_checks", false);
789         }
790 }
791
792 void ExternalCommandProcessor::EnablePassiveHostChecks(double, const std::vector<String>& arguments)
793 {
794         Host::Ptr host = Host::GetByName(arguments[0]);
795
796         if (!host)
797                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable passive host checks for non-existent host '" + arguments[0] + "'"));
798
799         Log(LogNotice, "ExternalCommandProcessor")
800                 << "Enabling passive checks for host '" << arguments[0] << "'";
801
802         host->ModifyAttribute("enable_passive_checks", true);
803 }
804
805 void ExternalCommandProcessor::DisablePassiveHostChecks(double, const std::vector<String>& arguments)
806 {
807         Host::Ptr host = Host::GetByName(arguments[0]);
808
809         if (!host)
810                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable passive host checks for non-existent host '" + arguments[0] + "'"));
811
812         Log(LogNotice, "ExternalCommandProcessor")
813                 << "Disabling passive checks for host '" << arguments[0] << "'";
814
815         host->ModifyAttribute("enable_passive_checks", false);
816 }
817
818 void ExternalCommandProcessor::EnablePassiveSvcChecks(double, const std::vector<String>& arguments)
819 {
820         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
821
822         if (!service)
823                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable service checks for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
824
825         Log(LogNotice, "ExternalCommandProcessor")
826                 << "Enabling passive checks for service '" << arguments[1] << "'";
827
828         service->ModifyAttribute("enable_passive_checks", true);
829 }
830
831 void ExternalCommandProcessor::DisablePassiveSvcChecks(double, const std::vector<String>& arguments)
832 {
833         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
834
835         if (!service)
836                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable service checks for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
837
838         Log(LogNotice, "ExternalCommandProcessor")
839                 << "Disabling passive checks for service '" << arguments[1] << "'";
840
841         service->ModifyAttribute("enable_passive_checks", false);
842 }
843
844 void ExternalCommandProcessor::EnableServicegroupPassiveSvcChecks(double, const std::vector<String>& arguments)
845 {
846         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
847
848         if (!sg)
849                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable servicegroup passive service checks for non-existent servicegroup '" + arguments[0] + "'"));
850
851         for (const Service::Ptr& service : sg->GetMembers()) {
852                 Log(LogNotice, "ExternalCommandProcessor")
853                         << "Enabling passive checks for service '" << service->GetName() << "'";
854
855                 service->ModifyAttribute("enable_passive_checks", true);
856         }
857 }
858
859 void ExternalCommandProcessor::DisableServicegroupPassiveSvcChecks(double, const std::vector<String>& arguments)
860 {
861         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
862
863         if (!sg)
864                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable servicegroup passive service checks for non-existent servicegroup '" + arguments[0] + "'"));
865
866         for (const Service::Ptr& service : sg->GetMembers()) {
867                 Log(LogNotice, "ExternalCommandProcessor")
868                         << "Disabling passive checks for service '" << service->GetName() << "'";
869
870                 service->ModifyAttribute("enable_passive_checks", false);
871         }
872 }
873
874 void ExternalCommandProcessor::EnableHostgroupPassiveSvcChecks(double, const std::vector<String>& arguments)
875 {
876         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
877
878         if (!hg)
879                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable hostgroup passive service checks for non-existent hostgroup '" + arguments[0] + "'"));
880
881         for (const Host::Ptr& host : hg->GetMembers()) {
882                 for (const Service::Ptr& service : host->GetServices()) {
883                         Log(LogNotice, "ExternalCommandProcessor")
884                                 << "Enabling passive checks for service '" << service->GetName() << "'";
885
886                         service->ModifyAttribute("enable_passive_checks", true);
887                 }
888         }
889 }
890
891 void ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks(double, const std::vector<String>& arguments)
892 {
893         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
894
895         if (!hg)
896                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable hostgroup passive service checks for non-existent hostgroup '" + arguments[0] + "'"));
897
898         for (const Host::Ptr& host : hg->GetMembers()) {
899                 for (const Service::Ptr& service : host->GetServices()) {
900                         Log(LogNotice, "ExternalCommandProcessor")
901                                 << "Disabling passive checks for service '" << service->GetName() << "'";
902
903                         service->ModifyAttribute("enable_passive_checks", false);
904                 }
905         }
906 }
907
908 void ExternalCommandProcessor::ProcessFile(double, const std::vector<String>& arguments)
909 {
910         std::deque< std::vector<String> > file_queue;
911         file_queue.push_back(arguments);
912
913         while (!file_queue.empty()) {
914                 std::vector<String> argument = file_queue.front();
915                 file_queue.pop_front();
916
917                 String file = argument[0];
918                 int to_delete = Convert::ToLong(argument[1]);
919
920                 std::ifstream ifp;
921                 ifp.exceptions(std::ifstream::badbit);
922
923                 ifp.open(file.CStr(), std::ifstream::in);
924
925                 while (ifp.good()) {
926                         std::string line;
927                         std::getline(ifp, line);
928
929                         try {
930                                 Log(LogNotice, "compat")
931                                         << "Executing external command: " << line;
932
933                                 ExecuteFromFile(line, file_queue);
934                         } catch (const std::exception& ex) {
935                                 Log(LogWarning, "ExternalCommandProcessor")
936                                         << "External command failed: " << DiagnosticInformation(ex);
937                         }
938                 }
939
940                 ifp.close();
941
942                 if (to_delete > 0)
943                         (void) unlink(file.CStr());
944         }
945 }
946
947 void ExternalCommandProcessor::ScheduleSvcDowntime(double, const std::vector<String>& arguments)
948 {
949         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
950
951         if (!service)
952                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule service downtime for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
953
954         String triggeredBy;
955         int triggeredByLegacy = Convert::ToLong(arguments[5]);
956         int is_fixed = Convert::ToLong(arguments[4]);
957         if (triggeredByLegacy != 0)
958                 triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
959
960         Log(LogNotice, "ExternalCommandProcessor")
961                 << "Creating downtime for service " << service->GetName();
962         (void) Downtime::AddDowntime(service, arguments[7], arguments[8],
963                 Convert::ToDouble(arguments[2]), Convert::ToDouble(arguments[3]),
964                 Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[6]));
965 }
966
967 void ExternalCommandProcessor::DelSvcDowntime(double, const std::vector<String>& arguments)
968 {
969         int id = Convert::ToLong(arguments[0]);
970         Log(LogNotice, "ExternalCommandProcessor")
971                 << "Removing downtime ID " << arguments[0];
972         String rid = Downtime::GetDowntimeIDFromLegacyID(id);
973         Downtime::RemoveDowntime(rid, true);
974 }
975
976 void ExternalCommandProcessor::ScheduleHostDowntime(double, const std::vector<String>& arguments)
977 {
978         Host::Ptr host = Host::GetByName(arguments[0]);
979
980         if (!host)
981                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule host downtime for non-existent host '" + arguments[0] + "'"));
982
983         String triggeredBy;
984         int triggeredByLegacy = Convert::ToLong(arguments[4]);
985         int is_fixed = Convert::ToLong(arguments[3]);
986         if (triggeredByLegacy != 0)
987                 triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
988
989         Log(LogNotice, "ExternalCommandProcessor")
990                 << "Creating downtime for host " << host->GetName();
991
992         (void) Downtime::AddDowntime(host, arguments[6], arguments[7],
993                 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
994                 Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
995 }
996
997 void ExternalCommandProcessor::ScheduleAndPropagateHostDowntime(double, const std::vector<String>& arguments)
998 {
999         Host::Ptr host = Host::GetByName(arguments[0]);
1000
1001         if (!host)
1002                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule and propagate host downtime for non-existent host '" + arguments[0] + "'"));
1003
1004         String triggeredBy;
1005         int triggeredByLegacy = Convert::ToLong(arguments[4]);
1006         int is_fixed = Convert::ToLong(arguments[3]);
1007         if (triggeredByLegacy != 0)
1008                 triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
1009
1010         Log(LogNotice, "ExternalCommandProcessor")
1011                 << "Creating downtime for host " << host->GetName();
1012
1013         (void) Downtime::AddDowntime(host, arguments[6], arguments[7],
1014                 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1015                 Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
1016
1017         /* Schedule downtime for all child hosts */
1018         for (const Checkable::Ptr& child : host->GetAllChildren()) {
1019                 Host::Ptr host;
1020                 Service::Ptr service;
1021                 tie(host, service) = GetHostService(child);
1022
1023                 /* ignore all service children */
1024                 if (service)
1025                         continue;
1026
1027                 (void) Downtime::AddDowntime(child, arguments[6], arguments[7],
1028                         Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1029                         Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
1030         }
1031 }
1032
1033 void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double, const std::vector<String>& arguments)
1034 {
1035         Host::Ptr host = Host::GetByName(arguments[0]);
1036
1037         if (!host)
1038                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule and propagate triggered host downtime for non-existent host '" + arguments[0] + "'"));
1039
1040         String triggeredBy;
1041         int triggeredByLegacy = Convert::ToLong(arguments[4]);
1042         int is_fixed = Convert::ToLong(arguments[3]);
1043         if (triggeredByLegacy != 0)
1044                 triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
1045
1046         Log(LogNotice, "ExternalCommandProcessor")
1047                 << "Creating downtime for host " << host->GetName();
1048
1049         String parentDowntime = Downtime::AddDowntime(host, arguments[6], arguments[7],
1050                 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1051                 Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
1052
1053         /* Schedule downtime for all child hosts and explicitely trigger them through the parent host's downtime */
1054         for (const Checkable::Ptr& child : host->GetAllChildren()) {
1055                 Host::Ptr host;
1056                 Service::Ptr service;
1057                 tie(host, service) = GetHostService(child);
1058
1059                 /* ignore all service children */
1060                 if (service)
1061                         continue;
1062
1063                 (void) Downtime::AddDowntime(child, arguments[6], arguments[7],
1064                         Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1065                         Convert::ToBool(is_fixed), parentDowntime, Convert::ToDouble(arguments[5]));
1066         }
1067 }
1068
1069 void ExternalCommandProcessor::DelHostDowntime(double, const std::vector<String>& arguments)
1070 {
1071         int id = Convert::ToLong(arguments[0]);
1072         Log(LogNotice, "ExternalCommandProcessor")
1073                 << "Removing downtime ID " << arguments[0];
1074         String rid = Downtime::GetDowntimeIDFromLegacyID(id);
1075         Downtime::RemoveDowntime(rid, true);
1076 }
1077
1078 void ExternalCommandProcessor::DelDowntimeByHostName(double, const std::vector<String>& arguments)
1079 {
1080         Host::Ptr host = Host::GetByName(arguments[0]);
1081
1082         if (!host)
1083                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule host services downtime for non-existent host '" + arguments[0] + "'"));
1084
1085         String serviceName;
1086         if (arguments.size() >= 2)
1087                 serviceName = arguments[1];
1088
1089         String startTime;
1090         if (arguments.size() >= 3)
1091                 startTime = arguments[2];
1092
1093         String commentString;
1094         if (arguments.size() >= 4)
1095                 commentString = arguments[3];
1096
1097         if (arguments.size() > 5)
1098                 Log(LogWarning, "ExternalCommandProcessor")
1099                         << ("Ignoring additional parameters for host '" + arguments[0] + "' downtime deletion.");
1100
1101         for (const Downtime::Ptr& downtime : host->GetDowntimes()) {
1102                 Log(LogNotice, "ExternalCommandProcessor")
1103                         << "Removing downtime '" << downtime->GetName() << "'.";
1104
1105                 Downtime::RemoveDowntime(downtime->GetName(), true);
1106         }
1107
1108         for (const Service::Ptr& service : host->GetServices()) {
1109                 if (!serviceName.IsEmpty() && serviceName != service->GetName())
1110                         continue;
1111
1112                 for (const Downtime::Ptr& downtime : service->GetDowntimes()) {
1113                         if (!startTime.IsEmpty() && downtime->GetStartTime() != Convert::ToDouble(startTime))
1114                                 continue;
1115
1116                         if (!commentString.IsEmpty() && downtime->GetComment() != commentString)
1117                                 continue;
1118
1119                         Log(LogNotice, "ExternalCommandProcessor")
1120                                 << "Removing downtime '" << downtime->GetName() << "'.";
1121
1122                         Downtime::RemoveDowntime(downtime->GetName(), true);
1123                 }
1124         }
1125 }
1126
1127 void ExternalCommandProcessor::ScheduleHostSvcDowntime(double, const std::vector<String>& arguments)
1128 {
1129         Host::Ptr host = Host::GetByName(arguments[0]);
1130
1131         if (!host)
1132                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule host services downtime for non-existent host '" + arguments[0] + "'"));
1133
1134         String triggeredBy;
1135         int triggeredByLegacy = Convert::ToLong(arguments[4]);
1136         int is_fixed = Convert::ToLong(arguments[3]);
1137         if (triggeredByLegacy != 0)
1138                 triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
1139
1140         Log(LogNotice, "ExternalCommandProcessor")
1141                 << "Creating downtime for host " << host->GetName();
1142
1143         (void) Downtime::AddDowntime(host, arguments[6], arguments[7],
1144                 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1145                 Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
1146
1147         for (const Service::Ptr& service : host->GetServices()) {
1148                 Log(LogNotice, "ExternalCommandProcessor")
1149                         << "Creating downtime for service " << service->GetName();
1150                 (void) Downtime::AddDowntime(service, arguments[6], arguments[7],
1151                         Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1152                         Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
1153         }
1154 }
1155
1156 void ExternalCommandProcessor::ScheduleHostgroupHostDowntime(double, const std::vector<String>& arguments)
1157 {
1158         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
1159
1160         if (!hg)
1161                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule hostgroup host downtime for non-existent hostgroup '" + arguments[0] + "'"));
1162
1163         String triggeredBy;
1164         int triggeredByLegacy = Convert::ToLong(arguments[4]);
1165         int is_fixed = Convert::ToLong(arguments[3]);
1166         if (triggeredByLegacy != 0)
1167                 triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
1168
1169         for (const Host::Ptr& host : hg->GetMembers()) {
1170                 Log(LogNotice, "ExternalCommandProcessor")
1171                         <<  "Creating downtime for host " << host->GetName();
1172
1173                 (void) Downtime::AddDowntime(host, arguments[6], arguments[7],
1174                         Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1175                         Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
1176         }
1177 }
1178
1179 void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const std::vector<String>& arguments)
1180 {
1181         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
1182
1183         if (!hg)
1184                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule hostgroup service downtime for non-existent hostgroup '" + arguments[0] + "'"));
1185
1186         String triggeredBy;
1187         int triggeredByLegacy = Convert::ToLong(arguments[4]);
1188         int is_fixed = Convert::ToLong(arguments[3]);
1189         if (triggeredByLegacy != 0)
1190                 triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
1191
1192         /* Note: we can't just directly create downtimes for all the services by iterating
1193          * over all hosts in the host group - otherwise we might end up creating multiple
1194          * downtimes for some services. */
1195
1196         std::set<Service::Ptr> services;
1197
1198         for (const Host::Ptr& host : hg->GetMembers()) {
1199                 for (const Service::Ptr& service : host->GetServices()) {
1200                         services.insert(service);
1201                 }
1202         }
1203
1204         for (const Service::Ptr& service : services) {
1205                 Log(LogNotice, "ExternalCommandProcessor")
1206                         << "Creating downtime for service " << service->GetName();
1207                 (void) Downtime::AddDowntime(service, arguments[6], arguments[7],
1208                         Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1209                         Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
1210         }
1211 }
1212
1213 void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const std::vector<String>& arguments)
1214 {
1215         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1216
1217         if (!sg)
1218                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule servicegroup host downtime for non-existent servicegroup '" + arguments[0] + "'"));
1219
1220         String triggeredBy;
1221         int triggeredByLegacy = Convert::ToLong(arguments[4]);
1222         int is_fixed = Convert::ToLong(arguments[3]);
1223         if (triggeredByLegacy != 0)
1224                 triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
1225
1226         /* Note: we can't just directly create downtimes for all the hosts by iterating
1227          * over all services in the service group - otherwise we might end up creating multiple
1228          * downtimes for some hosts. */
1229
1230         std::set<Host::Ptr> hosts;
1231
1232         for (const Service::Ptr& service : sg->GetMembers()) {
1233                 Host::Ptr host = service->GetHost();
1234                 hosts.insert(host);
1235         }
1236
1237         for (const Host::Ptr& host : hosts) {
1238                 Log(LogNotice, "ExternalCommandProcessor")
1239                         << "Creating downtime for host " << host->GetName();
1240                 (void) Downtime::AddDowntime(host, arguments[6], arguments[7],
1241                         Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1242                         Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
1243         }
1244 }
1245
1246 void ExternalCommandProcessor::ScheduleServicegroupSvcDowntime(double, const std::vector<String>& arguments)
1247 {
1248         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1249
1250         if (!sg)
1251                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule servicegroup service downtime for non-existent servicegroup '" + arguments[0] + "'"));
1252
1253         String triggeredBy;
1254         int triggeredByLegacy = Convert::ToLong(arguments[4]);
1255         int is_fixed = Convert::ToLong(arguments[3]);
1256         if (triggeredByLegacy != 0)
1257                 triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
1258
1259         for (const Service::Ptr& service : sg->GetMembers()) {
1260                 Log(LogNotice, "ExternalCommandProcessor")
1261                         << "Creating downtime for service " << service->GetName();
1262                 (void) Downtime::AddDowntime(service, arguments[6], arguments[7],
1263                         Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1264                         Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
1265         }
1266 }
1267
1268 void ExternalCommandProcessor::AddHostComment(double, const std::vector<String>& arguments)
1269 {
1270         Host::Ptr host = Host::GetByName(arguments[0]);
1271
1272         if (!host)
1273                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot add host comment for non-existent host '" + arguments[0] + "'"));
1274
1275         if (arguments[2].IsEmpty() || arguments[3].IsEmpty())
1276                 BOOST_THROW_EXCEPTION(std::invalid_argument("Author and comment must not be empty"));
1277
1278         Log(LogNotice, "ExternalCommandProcessor")
1279                 << "Creating comment for host " << host->GetName();
1280         (void) Comment::AddComment(host, CommentUser, arguments[2], arguments[3], false, 0);
1281 }
1282
1283 void ExternalCommandProcessor::DelHostComment(double, const std::vector<String>& arguments)
1284 {
1285         int id = Convert::ToLong(arguments[0]);
1286         Log(LogNotice, "ExternalCommandProcessor")
1287                 << "Removing comment ID " << arguments[0];
1288         String rid = Comment::GetCommentIDFromLegacyID(id);
1289         Comment::RemoveComment(rid);
1290 }
1291
1292 void ExternalCommandProcessor::AddSvcComment(double, const std::vector<String>& arguments)
1293 {
1294         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1295
1296         if (!service)
1297                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot add service comment for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1298
1299         if (arguments[3].IsEmpty() || arguments[4].IsEmpty())
1300                 BOOST_THROW_EXCEPTION(std::invalid_argument("Author and comment must not be empty"));
1301
1302         Log(LogNotice, "ExternalCommandProcessor")
1303                 << "Creating comment for service " << service->GetName();
1304         (void) Comment::AddComment(service, CommentUser, arguments[3], arguments[4], false, 0);
1305 }
1306
1307 void ExternalCommandProcessor::DelSvcComment(double, const std::vector<String>& arguments)
1308 {
1309         int id = Convert::ToLong(arguments[0]);
1310         Log(LogNotice, "ExternalCommandProcessor")
1311                 << "Removing comment ID " << arguments[0];
1312
1313         String rid = Comment::GetCommentIDFromLegacyID(id);
1314         Comment::RemoveComment(rid);
1315 }
1316
1317 void ExternalCommandProcessor::DelAllHostComments(double, const std::vector<String>& arguments)
1318 {
1319         Host::Ptr host = Host::GetByName(arguments[0]);
1320
1321         if (!host)
1322                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot delete all host comments for non-existent host '" + arguments[0] + "'"));
1323
1324         Log(LogNotice, "ExternalCommandProcessor")
1325                 << "Removing all comments for host " << host->GetName();
1326         host->RemoveAllComments();
1327 }
1328
1329 void ExternalCommandProcessor::DelAllSvcComments(double, const std::vector<String>& arguments)
1330 {
1331         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1332
1333         if (!service)
1334                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot delete all service comments for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1335
1336         Log(LogNotice, "ExternalCommandProcessor")
1337                 << "Removing all comments for service " << service->GetName();
1338         service->RemoveAllComments();
1339 }
1340
1341 void ExternalCommandProcessor::SendCustomHostNotification(double, const std::vector<String>& arguments)
1342 {
1343         Host::Ptr host = Host::GetByName(arguments[0]);
1344
1345         if (!host)
1346                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot send custom host notification for non-existent host '" + arguments[0] + "'"));
1347
1348         int options = Convert::ToLong(arguments[1]);
1349
1350         Log(LogNotice, "ExternalCommandProcessor")
1351                 << "Sending custom notification for host " << host->GetName();
1352         if (options & 2) {
1353                 host->SetForceNextNotification(true);
1354         }
1355
1356         Checkable::OnNotificationsRequested(host, NotificationCustom,
1357                 host->GetLastCheckResult(), arguments[2], arguments[3], nullptr);
1358 }
1359
1360 void ExternalCommandProcessor::SendCustomSvcNotification(double, const std::vector<String>& arguments)
1361 {
1362         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1363
1364         if (!service)
1365                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot send custom service notification for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1366
1367         int options = Convert::ToLong(arguments[2]);
1368
1369         Log(LogNotice, "ExternalCommandProcessor")
1370                 << "Sending custom notification for service " << service->GetName();
1371
1372         if (options & 2) {
1373                 service->SetForceNextNotification(true);
1374         }
1375
1376         Service::OnNotificationsRequested(service, NotificationCustom,
1377                 service->GetLastCheckResult(), arguments[3], arguments[4], nullptr);
1378 }
1379
1380 void ExternalCommandProcessor::DelayHostNotification(double, const std::vector<String>& arguments)
1381 {
1382         Host::Ptr host = Host::GetByName(arguments[0]);
1383
1384         if (!host)
1385                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot delay host notification for non-existent host '" + arguments[0] + "'"));
1386
1387         Log(LogNotice, "ExternalCommandProcessor")
1388                 << "Delaying notifications for host '" << host->GetName() << "'";
1389
1390         for (const Notification::Ptr& notification : host->GetNotifications()) {
1391                 notification->SetNextNotification(Convert::ToDouble(arguments[1]));
1392         }
1393 }
1394
1395 void ExternalCommandProcessor::DelaySvcNotification(double, const std::vector<String>& arguments)
1396 {
1397         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1398
1399         if (!service)
1400                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot delay service notification for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1401
1402         Log(LogNotice, "ExternalCommandProcessor")
1403                 << "Delaying notifications for service " << service->GetName();
1404
1405         for (const Notification::Ptr& notification : service->GetNotifications()) {
1406                 notification->SetNextNotification(Convert::ToDouble(arguments[2]));
1407         }
1408 }
1409
1410 void ExternalCommandProcessor::EnableHostNotifications(double, const std::vector<String>& arguments)
1411 {
1412         Host::Ptr host = Host::GetByName(arguments[0]);
1413
1414         if (!host)
1415                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable host notifications for non-existent host '" + arguments[0] + "'"));
1416
1417         Log(LogNotice, "ExternalCommandProcessor")
1418                 << "Enabling notifications for host '" << arguments[0] << "'";
1419
1420         host->ModifyAttribute("enable_notifications", true);
1421 }
1422
1423 void ExternalCommandProcessor::DisableHostNotifications(double, const std::vector<String>& arguments)
1424 {
1425         Host::Ptr host = Host::GetByName(arguments[0]);
1426
1427         if (!host)
1428                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable host notifications for non-existent host '" + arguments[0] + "'"));
1429
1430         Log(LogNotice, "ExternalCommandProcessor")
1431                 << "Disabling notifications for host '" << arguments[0] << "'";
1432
1433         host->ModifyAttribute("enable_notifications", false);
1434 }
1435
1436 void ExternalCommandProcessor::EnableSvcNotifications(double, const std::vector<String>& arguments)
1437 {
1438         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1439
1440         if (!service)
1441                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable service notifications for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1442
1443         Log(LogNotice, "ExternalCommandProcessor")
1444                 << "Enabling notifications for service '" << arguments[1] << "'";
1445
1446         service->ModifyAttribute("enable_notifications", true);
1447 }
1448
1449 void ExternalCommandProcessor::DisableSvcNotifications(double, const std::vector<String>& arguments)
1450 {
1451         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1452
1453         if (!service)
1454                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable service notifications for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1455
1456         Log(LogNotice, "ExternalCommandProcessor")
1457                 << "Disabling notifications for service '" << arguments[1] << "'";
1458
1459         service->ModifyAttribute("enable_notifications", false);
1460 }
1461
1462 void ExternalCommandProcessor::EnableHostSvcNotifications(double, const std::vector<String>& arguments)
1463 {
1464         Host::Ptr host = Host::GetByName(arguments[0]);
1465
1466         if (!host)
1467                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable notifications for all services for non-existent host '" + arguments[0] + "'"));
1468
1469         Log(LogNotice, "ExternalCommandProcessor")
1470                 << "Enabling notifications for all services on host '" << arguments[0] << "'";
1471
1472         for (const Service::Ptr& service : host->GetServices()) {
1473                 Log(LogNotice, "ExternalCommandProcessor")
1474                         << "Enabling notifications for service '" << service->GetName() << "'";
1475
1476                 service->ModifyAttribute("enable_notifications", true);
1477         }
1478 }
1479
1480 void ExternalCommandProcessor::DisableHostSvcNotifications(double, const std::vector<String>& arguments)
1481 {
1482         Host::Ptr host = Host::GetByName(arguments[0]);
1483
1484         if (!host)
1485                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable notifications for all services  for non-existent host '" + arguments[0] + "'"));
1486
1487         Log(LogNotice, "ExternalCommandProcessor")
1488                 << "Disabling notifications for all services on host '" << arguments[0] << "'";
1489
1490         for (const Service::Ptr& service : host->GetServices()) {
1491                 Log(LogNotice, "ExternalCommandProcessor")
1492                         << "Disabling notifications for service '" << service->GetName() << "'";
1493
1494                 service->ModifyAttribute("enable_notifications", false);
1495         }
1496 }
1497
1498 void ExternalCommandProcessor::DisableHostgroupHostChecks(double, const std::vector<String>& arguments)
1499 {
1500         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
1501
1502         if (!hg)
1503                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable hostgroup host checks for non-existent hostgroup '" + arguments[0] + "'"));
1504
1505         for (const Host::Ptr& host : hg->GetMembers()) {
1506                 Log(LogNotice, "ExternalCommandProcessor")
1507                         << "Disabling active checks for host '" << host->GetName() << "'";
1508
1509                 host->ModifyAttribute("enable_active_checks", false);
1510         }
1511 }
1512
1513 void ExternalCommandProcessor::DisableHostgroupPassiveHostChecks(double, const std::vector<String>& arguments)
1514 {
1515         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
1516
1517         if (!hg)
1518                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable hostgroup passive host checks for non-existent hostgroup '" + arguments[0] + "'"));
1519
1520         for (const Host::Ptr& host : hg->GetMembers()) {
1521                 Log(LogNotice, "ExternalCommandProcessor")
1522                         << "Disabling passive checks for host '" << host->GetName() << "'";
1523
1524                 host->ModifyAttribute("enable_passive_checks", false);
1525         }
1526 }
1527
1528 void ExternalCommandProcessor::DisableServicegroupHostChecks(double, const std::vector<String>& arguments)
1529 {
1530         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1531
1532         if (!sg)
1533                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable servicegroup host checks for non-existent servicegroup '" + arguments[0] + "'"));
1534
1535         for (const Service::Ptr& service : sg->GetMembers()) {
1536                 Host::Ptr host = service->GetHost();
1537
1538                 Log(LogNotice, "ExternalCommandProcessor")
1539                         << "Disabling active checks for host '" << host->GetName() << "'";
1540
1541                 host->ModifyAttribute("enable_active_checks", false);
1542         }
1543 }
1544
1545 void ExternalCommandProcessor::DisableServicegroupPassiveHostChecks(double, const std::vector<String>& arguments)
1546 {
1547         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1548
1549         if (!sg)
1550                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable servicegroup passive host checks for non-existent servicegroup '" + arguments[0] + "'"));
1551
1552         for (const Service::Ptr& service : sg->GetMembers()) {
1553                 Host::Ptr host = service->GetHost();
1554
1555                 Log(LogNotice, "ExternalCommandProcessor")
1556                         << "Disabling passive checks for host '" << host->GetName() << "'";
1557
1558                 host->ModifyAttribute("enable_passive_checks", false);
1559         }
1560 }
1561
1562 void ExternalCommandProcessor::EnableHostgroupHostChecks(double, const std::vector<String>& arguments)
1563 {
1564         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
1565
1566         if (!hg)
1567                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable hostgroup host checks for non-existent hostgroup '" + arguments[0] + "'"));
1568
1569         for (const Host::Ptr& host : hg->GetMembers()) {
1570                 Log(LogNotice, "ExternalCommandProcessor")
1571                         << "Enabling active checks for host '" << host->GetName() << "'";
1572
1573                 host->ModifyAttribute("enable_active_checks", true);
1574         }
1575 }
1576
1577 void ExternalCommandProcessor::EnableHostgroupPassiveHostChecks(double, const std::vector<String>& arguments)
1578 {
1579         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
1580
1581         if (!hg)
1582                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable hostgroup passive host checks for non-existent hostgroup '" + arguments[0] + "'"));
1583
1584         for (const Host::Ptr& host : hg->GetMembers()) {
1585                 Log(LogNotice, "ExternalCommandProcessor")
1586                         << "Enabling passive checks for host '" << host->GetName() << "'";
1587
1588                 host->ModifyAttribute("enable_passive_checks", true);
1589         }
1590 }
1591
1592 void ExternalCommandProcessor::EnableServicegroupHostChecks(double, const std::vector<String>& arguments)
1593 {
1594         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1595
1596         if (!sg)
1597                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable servicegroup host checks for non-existent servicegroup '" + arguments[0] + "'"));
1598
1599         for (const Service::Ptr& service : sg->GetMembers()) {
1600                 Host::Ptr host = service->GetHost();
1601
1602                 Log(LogNotice, "ExternalCommandProcessor")
1603                         << "Enabling active checks for host '" << host->GetName() << "'";
1604
1605                 host->ModifyAttribute("enable_active_checks", true);
1606         }
1607 }
1608
1609 void ExternalCommandProcessor::EnableServicegroupPassiveHostChecks(double, const std::vector<String>& arguments)
1610 {
1611         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1612
1613         if (!sg)
1614                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable servicegroup passive host checks for non-existent servicegroup '" + arguments[0] + "'"));
1615
1616         for (const Service::Ptr& service : sg->GetMembers()) {
1617                 Host::Ptr host = service->GetHost();
1618
1619                 Log(LogNotice, "ExternalCommandProcessor")
1620                         << "Enabling passive checks for host '" << host->GetName() << "'";
1621
1622                 host->ModifyAttribute("enable_passive_checks", true);
1623         }
1624 }
1625
1626 void ExternalCommandProcessor::EnableHostFlapping(double, const std::vector<String>& arguments)
1627 {
1628         Host::Ptr host = Host::GetByName(arguments[0]);
1629
1630         if (!host)
1631                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable host flapping for non-existent host '" + arguments[0] + "'"));
1632
1633         Log(LogNotice, "ExternalCommandProcessor")
1634                 << "Enabling flapping detection for host '" << arguments[0] << "'";
1635
1636         host->ModifyAttribute("enable_flapping", true);
1637 }
1638
1639 void ExternalCommandProcessor::DisableHostFlapping(double, const std::vector<String>& arguments)
1640 {
1641         Host::Ptr host = Host::GetByName(arguments[0]);
1642
1643         if (!host)
1644                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable host flapping for non-existent host '" + arguments[0] + "'"));
1645
1646         Log(LogNotice, "ExternalCommandProcessor")
1647                 << "Disabling flapping detection for host '" << arguments[0] << "'";
1648
1649         host->ModifyAttribute("enable_flapping", false);
1650 }
1651
1652 void ExternalCommandProcessor::EnableSvcFlapping(double, const std::vector<String>& arguments)
1653 {
1654         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1655
1656         if (!service)
1657                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable service flapping for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1658
1659         Log(LogNotice, "ExternalCommandProcessor")
1660                 << "Enabling flapping detection for service '" << arguments[1] << "'";
1661
1662         service->ModifyAttribute("enable_flapping", true);
1663 }
1664
1665 void ExternalCommandProcessor::DisableSvcFlapping(double, const std::vector<String>& arguments)
1666 {
1667         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1668
1669         if (!service)
1670                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable service flapping for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1671
1672         Log(LogNotice, "ExternalCommandProcessor")
1673                 << "Disabling flapping detection for service '" << arguments[1] << "'";
1674
1675         service->ModifyAttribute("enable_flapping", false);
1676 }
1677
1678 void ExternalCommandProcessor::EnableNotifications(double, const std::vector<String>&)
1679 {
1680         Log(LogNotice, "ExternalCommandProcessor", "Globally enabling notifications.");
1681
1682         IcingaApplication::GetInstance()->ModifyAttribute("enable_notifications", true);
1683 }
1684
1685 void ExternalCommandProcessor::DisableNotifications(double, const std::vector<String>&)
1686 {
1687         Log(LogNotice, "ExternalCommandProcessor", "Globally disabling notifications.");
1688
1689         IcingaApplication::GetInstance()->ModifyAttribute("enable_notifications", false);
1690 }
1691
1692 void ExternalCommandProcessor::EnableFlapDetection(double, const std::vector<String>&)
1693 {
1694         Log(LogNotice, "ExternalCommandProcessor", "Globally enabling flap detection.");
1695
1696         IcingaApplication::GetInstance()->ModifyAttribute("enable_flapping", true);
1697 }
1698
1699 void ExternalCommandProcessor::DisableFlapDetection(double, const std::vector<String>&)
1700 {
1701         Log(LogNotice, "ExternalCommandProcessor", "Globally disabling flap detection.");
1702
1703         IcingaApplication::GetInstance()->ModifyAttribute("enable_flapping", false);
1704 }
1705
1706 void ExternalCommandProcessor::EnableEventHandlers(double, const std::vector<String>&)
1707 {
1708         Log(LogNotice, "ExternalCommandProcessor", "Globally enabling event handlers.");
1709
1710         IcingaApplication::GetInstance()->ModifyAttribute("enable_event_handlers", true);
1711 }
1712
1713 void ExternalCommandProcessor::DisableEventHandlers(double, const std::vector<String>&)
1714 {
1715         Log(LogNotice, "ExternalCommandProcessor", "Globally disabling event handlers.");
1716
1717         IcingaApplication::GetInstance()->ModifyAttribute("enable_event_handlers", false);
1718 }
1719
1720 void ExternalCommandProcessor::EnablePerformanceData(double, const std::vector<String>&)
1721 {
1722         Log(LogNotice, "ExternalCommandProcessor", "Globally enabling performance data processing.");
1723
1724         IcingaApplication::GetInstance()->ModifyAttribute("enable_perfdata", true);
1725 }
1726
1727 void ExternalCommandProcessor::DisablePerformanceData(double, const std::vector<String>&)
1728 {
1729         Log(LogNotice, "ExternalCommandProcessor", "Globally disabling performance data processing.");
1730
1731         IcingaApplication::GetInstance()->ModifyAttribute("enable_perfdata", false);
1732 }
1733
1734 void ExternalCommandProcessor::StartExecutingSvcChecks(double, const std::vector<String>&)
1735 {
1736         Log(LogNotice, "ExternalCommandProcessor", "Globally enabling service checks.");
1737
1738         IcingaApplication::GetInstance()->ModifyAttribute("enable_service_checks", true);
1739 }
1740
1741 void ExternalCommandProcessor::StopExecutingSvcChecks(double, const std::vector<String>&)
1742 {
1743         Log(LogNotice, "ExternalCommandProcessor", "Globally disabling service checks.");
1744
1745         IcingaApplication::GetInstance()->ModifyAttribute("enable_service_checks", false);
1746 }
1747
1748 void ExternalCommandProcessor::StartExecutingHostChecks(double, const std::vector<String>&)
1749 {
1750         Log(LogNotice, "ExternalCommandProcessor", "Globally enabling host checks.");
1751
1752         IcingaApplication::GetInstance()->ModifyAttribute("enable_host_checks", true);
1753 }
1754
1755 void ExternalCommandProcessor::StopExecutingHostChecks(double, const std::vector<String>&)
1756 {
1757         Log(LogNotice, "ExternalCommandProcessor", "Globally disabling host checks.");
1758
1759         IcingaApplication::GetInstance()->ModifyAttribute("enable_host_checks", false);
1760 }
1761
1762 void ExternalCommandProcessor::ChangeNormalSvcCheckInterval(double, const std::vector<String>& arguments)
1763 {
1764         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1765
1766         if (!service)
1767                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot update check interval for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1768
1769         double interval = Convert::ToDouble(arguments[2]);
1770
1771         Log(LogNotice, "ExternalCommandProcessor")
1772                 << "Updating check interval for service '" << arguments[1] << "'";
1773
1774         service->ModifyAttribute("check_interval", interval * 60);
1775 }
1776
1777 void ExternalCommandProcessor::ChangeNormalHostCheckInterval(double, const std::vector<String>& arguments)
1778 {
1779         Host::Ptr host = Host::GetByName(arguments[0]);
1780
1781         if (!host)
1782                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot update check interval for non-existent host '" + arguments[0] + "'"));
1783
1784         Log(LogNotice, "ExternalCommandProcessor")
1785                 << "Updating check interval for host '" << arguments[0] << "'";
1786
1787         double interval = Convert::ToDouble(arguments[1]);
1788
1789         host->ModifyAttribute("check_interval", interval * 60);
1790 }
1791
1792 void ExternalCommandProcessor::ChangeRetrySvcCheckInterval(double, const std::vector<String>& arguments)
1793 {
1794         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1795
1796         if (!service)
1797                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot update retry interval for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1798
1799         double interval = Convert::ToDouble(arguments[2]);
1800
1801         Log(LogNotice, "ExternalCommandProcessor")
1802                 << "Updating retry interval for service '" << arguments[1] << "'";
1803
1804         service->ModifyAttribute("retry_interval", interval * 60);
1805 }
1806
1807 void ExternalCommandProcessor::ChangeRetryHostCheckInterval(double, const std::vector<String>& arguments)
1808 {
1809         Host::Ptr host = Host::GetByName(arguments[0]);
1810
1811         if (!host)
1812                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot update retry interval for non-existent host '" + arguments[0] + "'"));
1813
1814         Log(LogNotice, "ExternalCommandProcessor")
1815                 << "Updating retry interval for host '" << arguments[0] << "'";
1816
1817         double interval = Convert::ToDouble(arguments[1]);
1818
1819         host->ModifyAttribute("retry_interval", interval * 60);
1820 }
1821
1822 void ExternalCommandProcessor::EnableHostEventHandler(double, const std::vector<String>& arguments)
1823 {
1824         Host::Ptr host = Host::GetByName(arguments[0]);
1825
1826         if (!host)
1827                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable event handler for non-existent host '" + arguments[0] + "'"));
1828
1829         Log(LogNotice, "ExternalCommandProcessor")
1830                 << "Enabling event handler for host '" << arguments[0] << "'";
1831
1832         host->ModifyAttribute("enable_event_handler", true);
1833 }
1834
1835 void ExternalCommandProcessor::DisableHostEventHandler(double, const std::vector<String>& arguments)
1836 {
1837         Host::Ptr host = Host::GetByName(arguments[0]);
1838
1839         if (!host)
1840                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable event handler for non-existent host '" + arguments[0] + "'"));
1841
1842         Log(LogNotice, "ExternalCommandProcessor")
1843                 << "Disabling event handler for host '" << arguments[0] << "'";
1844
1845         host->ModifyAttribute("enable_event_handler", false);
1846 }
1847
1848 void ExternalCommandProcessor::EnableSvcEventHandler(double, const std::vector<String>& arguments)
1849 {
1850         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1851
1852         if (!service)
1853                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable event handler for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1854
1855         Log(LogNotice, "ExternalCommandProcessor")
1856                 << "Enabling event handler for service '" << arguments[1] << "'";
1857
1858         service->ModifyAttribute("enable_event_handler", true);
1859 }
1860
1861 void ExternalCommandProcessor::DisableSvcEventHandler(double, const std::vector<String>& arguments)
1862 {
1863         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1864
1865         if (!service)
1866                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable event handler for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1867
1868         Log(LogNotice, "ExternalCommandProcessor")
1869                 << "Disabling event handler for service '" << arguments[1] + "'";
1870
1871         service->ModifyAttribute("enable_event_handler", false);
1872 }
1873
1874 void ExternalCommandProcessor::ChangeHostEventHandler(double, const std::vector<String>& arguments)
1875 {
1876         Host::Ptr host = Host::GetByName(arguments[0]);
1877
1878         if (!host)
1879                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change event handler for non-existent host '" + arguments[0] + "'"));
1880
1881         if (arguments[1].IsEmpty()) {
1882                 Log(LogNotice, "ExternalCommandProcessor")
1883                         << "Unsetting event handler for host '" << arguments[0] << "'";
1884
1885                 host->ModifyAttribute("event_command", "");
1886         } else {
1887                 EventCommand::Ptr command = EventCommand::GetByName(arguments[1]);
1888
1889                 if (!command)
1890                         BOOST_THROW_EXCEPTION(std::invalid_argument("Event command '" + arguments[1] + "' does not exist."));
1891
1892                 Log(LogNotice, "ExternalCommandProcessor")
1893                         << "Changing event handler for host '" << arguments[0] << "' to '" << arguments[1] << "'";
1894
1895                 host->ModifyAttribute("event_command", command->GetName());
1896         }
1897 }
1898
1899 void ExternalCommandProcessor::ChangeSvcEventHandler(double, const std::vector<String>& arguments)
1900 {
1901         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1902
1903         if (!service)
1904                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change event handler for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1905
1906         if (arguments[2].IsEmpty()) {
1907                 Log(LogNotice, "ExternalCommandProcessor")
1908                         << "Unsetting event handler for service '" << arguments[1] << "'";
1909
1910                 service->ModifyAttribute("event_command", "");
1911         } else {
1912                 EventCommand::Ptr command = EventCommand::GetByName(arguments[2]);
1913
1914                 if (!command)
1915                         BOOST_THROW_EXCEPTION(std::invalid_argument("Event command '" + arguments[2] + "' does not exist."));
1916
1917                 Log(LogNotice, "ExternalCommandProcessor")
1918                         << "Changing event handler for service '" << arguments[1] << "' to '" << arguments[2] << "'";
1919
1920                 service->ModifyAttribute("event_command", command->GetName());
1921         }
1922 }
1923
1924 void ExternalCommandProcessor::ChangeHostCheckCommand(double, const std::vector<String>& arguments)
1925 {
1926         Host::Ptr host = Host::GetByName(arguments[0]);
1927
1928         if (!host)
1929                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change check command for non-existent host '" + arguments[0] + "'"));
1930
1931         CheckCommand::Ptr command = CheckCommand::GetByName(arguments[1]);
1932
1933         if (!command)
1934                 BOOST_THROW_EXCEPTION(std::invalid_argument("Check command '" + arguments[1] + "' does not exist."));
1935
1936         Log(LogNotice, "ExternalCommandProcessor")
1937                 << "Changing check command for host '" << arguments[0] << "' to '" << arguments[1] << "'";
1938
1939         host->ModifyAttribute("check_command", command->GetName());
1940 }
1941
1942 void ExternalCommandProcessor::ChangeSvcCheckCommand(double, const std::vector<String>& arguments)
1943 {
1944         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1945
1946         if (!service)
1947                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change check command for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1948
1949         CheckCommand::Ptr command = CheckCommand::GetByName(arguments[2]);
1950
1951         if (!command)
1952                 BOOST_THROW_EXCEPTION(std::invalid_argument("Check command '" + arguments[2] + "' does not exist."));
1953
1954         Log(LogNotice, "ExternalCommandProcessor")
1955                 << "Changing check command for service '" << arguments[1] << "' to '" << arguments[2] << "'";
1956
1957         service->ModifyAttribute("check_command", command->GetName());
1958 }
1959
1960 void ExternalCommandProcessor::ChangeMaxHostCheckAttempts(double, const std::vector<String>& arguments)
1961 {
1962         Host::Ptr host = Host::GetByName(arguments[0]);
1963
1964         if (!host)
1965                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change max check attempts for non-existent host '" + arguments[0] + "'"));
1966
1967         int attempts = Convert::ToLong(arguments[1]);
1968
1969         Log(LogNotice, "ExternalCommandProcessor")
1970                 << "Changing max check attempts for host '" << arguments[0] << "' to '" << arguments[1] << "'";
1971
1972         host->ModifyAttribute("max_check_attempts", attempts);
1973 }
1974
1975 void ExternalCommandProcessor::ChangeMaxSvcCheckAttempts(double, const std::vector<String>& arguments)
1976 {
1977         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1978
1979         if (!service)
1980                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change max check attempts for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
1981
1982         int attempts = Convert::ToLong(arguments[2]);
1983
1984         Log(LogNotice, "ExternalCommandProcessor")
1985                 << "Changing max check attempts for service '" << arguments[1] << "' to '" << arguments[2] << "'";
1986
1987         service->ModifyAttribute("max_check_attempts", attempts);
1988 }
1989
1990 void ExternalCommandProcessor::ChangeHostCheckTimeperiod(double, const std::vector<String>& arguments)
1991 {
1992         Host::Ptr host = Host::GetByName(arguments[0]);
1993
1994         if (!host)
1995                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change check period for non-existent host '" + arguments[0] + "'"));
1996
1997         TimePeriod::Ptr tp = TimePeriod::GetByName(arguments[1]);
1998
1999         if (!tp)
2000                 BOOST_THROW_EXCEPTION(std::invalid_argument("Time period '" + arguments[1] + "' does not exist."));
2001
2002         Log(LogNotice, "ExternalCommandProcessor")
2003                 << "Changing check period for host '" << arguments[0] << "' to '" << arguments[1] << "'";
2004
2005         host->ModifyAttribute("check_period", tp->GetName());
2006 }
2007
2008 void ExternalCommandProcessor::ChangeSvcCheckTimeperiod(double, const std::vector<String>& arguments)
2009 {
2010         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
2011
2012         if (!service)
2013                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change check period for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
2014
2015         TimePeriod::Ptr tp = TimePeriod::GetByName(arguments[2]);
2016
2017         if (!tp)
2018                 BOOST_THROW_EXCEPTION(std::invalid_argument("Time period '" + arguments[2] + "' does not exist."));
2019
2020         Log(LogNotice, "ExternalCommandProcessor")
2021                 << "Changing check period for service '" << arguments[1] << "' to '" << arguments[2] << "'";
2022
2023         service->ModifyAttribute("check_period", tp->GetName());
2024 }
2025
2026 void ExternalCommandProcessor::ChangeCustomHostVar(double, const std::vector<String>& arguments)
2027 {
2028         Host::Ptr host = Host::GetByName(arguments[0]);
2029
2030         if (!host)
2031                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change custom var for non-existent host '" + arguments[0] + "'"));
2032
2033         Log(LogNotice, "ExternalCommandProcessor")
2034                 << "Changing custom var '" << arguments[1] << "' for host '" << arguments[0] << "' to value '" << arguments[2] << "'";
2035
2036         host->ModifyAttribute("vars." + arguments[1], arguments[2]);
2037 }
2038
2039 void ExternalCommandProcessor::ChangeCustomSvcVar(double, const std::vector<String>& arguments)
2040 {
2041         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
2042
2043         if (!service)
2044                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change custom var for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));
2045
2046         Log(LogNotice, "ExternalCommandProcessor")
2047                 << "Changing custom var '" << arguments[2] << "' for service '" << arguments[1] << "' on host '"
2048                 << arguments[0] << "' to value '" << arguments[3] << "'";
2049
2050         service->ModifyAttribute("vars." + arguments[2], arguments[3]);
2051 }
2052
2053 void ExternalCommandProcessor::ChangeCustomUserVar(double, const std::vector<String>& arguments)
2054 {
2055         User::Ptr user = User::GetByName(arguments[0]);
2056
2057         if (!user)
2058                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change custom var for non-existent user '" + arguments[0] + "'"));
2059
2060         Log(LogNotice, "ExternalCommandProcessor")
2061                 << "Changing custom var '" << arguments[1] << "' for user '" << arguments[0] << "' to value '" << arguments[2] << "'";
2062
2063         user->ModifyAttribute("vars." + arguments[1], arguments[2]);
2064 }
2065
2066 void ExternalCommandProcessor::ChangeCustomCheckcommandVar(double, const std::vector<String>& arguments)
2067 {
2068         CheckCommand::Ptr command = CheckCommand::GetByName(arguments[0]);
2069
2070         if (!command)
2071                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change custom var for non-existent command '" + arguments[0] + "'"));
2072
2073         ChangeCustomCommandVarInternal(command, arguments[1], arguments[2]);
2074 }
2075
2076 void ExternalCommandProcessor::ChangeCustomEventcommandVar(double, const std::vector<String>& arguments)
2077 {
2078         EventCommand::Ptr command = EventCommand::GetByName(arguments[0]);
2079
2080         if (!command)
2081                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change custom var for non-existent command '" + arguments[0] + "'"));
2082
2083         ChangeCustomCommandVarInternal(command, arguments[1], arguments[2]);
2084 }
2085
2086 void ExternalCommandProcessor::ChangeCustomNotificationcommandVar(double, const std::vector<String>& arguments)
2087 {
2088         NotificationCommand::Ptr command = NotificationCommand::GetByName(arguments[0]);
2089
2090         if (!command)
2091                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change custom var for non-existent command '" + arguments[0] + "'"));
2092
2093         ChangeCustomCommandVarInternal(command, arguments[1], arguments[2]);
2094 }
2095
2096 void ExternalCommandProcessor::ChangeCustomCommandVarInternal(const Command::Ptr& command, const String& name, const Value& value)
2097 {
2098         Log(LogNotice, "ExternalCommandProcessor")
2099                 << "Changing custom var '" << name << "' for command '" << command->GetName() << "' to value '" << value << "'";
2100
2101         command->ModifyAttribute("vars." + name, value);
2102 }
2103
2104 void ExternalCommandProcessor::EnableHostgroupHostNotifications(double, const std::vector<String>& arguments)
2105 {
2106         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
2107
2108         if (!hg)
2109                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable host notifications for non-existent hostgroup '" + arguments[0] + "'"));
2110
2111         for (const Host::Ptr& host : hg->GetMembers()) {
2112                 Log(LogNotice, "ExternalCommandProcessor")
2113                         << "Enabling notifications for host '" << host->GetName() << "'";
2114
2115                 host->ModifyAttribute("enable_notifications", true);
2116         }
2117 }
2118
2119 void ExternalCommandProcessor::EnableHostgroupSvcNotifications(double, const std::vector<String>& arguments)
2120 {
2121         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
2122
2123         if (!hg)
2124                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable service notifications for non-existent hostgroup '" + arguments[0] + "'"));
2125
2126         for (const Host::Ptr& host : hg->GetMembers()) {
2127                 for (const Service::Ptr& service : host->GetServices()) {
2128                         Log(LogNotice, "ExternalCommandProcessor")
2129                                 << "Enabling notifications for service '" << service->GetName() << "'";
2130
2131                         service->ModifyAttribute("enable_notifications", true);
2132                 }
2133         }
2134 }
2135
2136 void ExternalCommandProcessor::DisableHostgroupHostNotifications(double, const std::vector<String>& arguments)
2137 {
2138         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
2139
2140         if (!hg)
2141                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable host notifications for non-existent hostgroup '" + arguments[0] + "'"));
2142
2143         for (const Host::Ptr& host : hg->GetMembers()) {
2144                 Log(LogNotice, "ExternalCommandProcessor")
2145                         << "Disabling notifications for host '" << host->GetName() << "'";
2146
2147                 host->ModifyAttribute("enable_notifications", false);
2148         }
2149 }
2150
2151 void ExternalCommandProcessor::DisableHostgroupSvcNotifications(double, const std::vector<String>& arguments)
2152 {
2153         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
2154
2155         if (!hg)
2156                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable service notifications for non-existent hostgroup '" + arguments[0] + "'"));
2157
2158         for (const Host::Ptr& host : hg->GetMembers()) {
2159                 for (const Service::Ptr& service : host->GetServices()) {
2160                         Log(LogNotice, "ExternalCommandProcessor")
2161                                 << "Disabling notifications for service '" << service->GetName() << "'";
2162
2163                         service->ModifyAttribute("enable_notifications", false);
2164                 }
2165         }
2166 }
2167
2168 void ExternalCommandProcessor::EnableServicegroupHostNotifications(double, const std::vector<String>& arguments)
2169 {
2170         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
2171
2172         if (!sg)
2173                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable host notifications for non-existent servicegroup '" + arguments[0] + "'"));
2174
2175         for (const Service::Ptr& service : sg->GetMembers()) {
2176                 Host::Ptr host = service->GetHost();
2177
2178                 Log(LogNotice, "ExternalCommandProcessor")
2179                         << "Enabling notifications for host '" << host->GetName() << "'";
2180
2181                 host->ModifyAttribute("enable_notifications", true);
2182         }
2183 }
2184
2185 void ExternalCommandProcessor::EnableServicegroupSvcNotifications(double, const std::vector<String>& arguments)
2186 {
2187         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
2188
2189         if (!sg)
2190                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable service notifications for non-existent servicegroup '" + arguments[0] + "'"));
2191
2192         for (const Service::Ptr& service : sg->GetMembers()) {
2193                 Log(LogNotice, "ExternalCommandProcessor")
2194                         << "Enabling notifications for service '" << service->GetName() << "'";
2195
2196                 service->ModifyAttribute("enable_notifications", true);
2197         }
2198 }
2199
2200 void ExternalCommandProcessor::DisableServicegroupHostNotifications(double, const std::vector<String>& arguments)
2201 {
2202         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
2203
2204         if (!sg)
2205                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable host notifications for non-existent servicegroup '" + arguments[0] + "'"));
2206
2207         for (const Service::Ptr& service : sg->GetMembers()) {
2208                 Host::Ptr host = service->GetHost();
2209
2210                 Log(LogNotice, "ExternalCommandProcessor")
2211                         << "Disabling notifications for host '" << host->GetName() << "'";
2212
2213                 host->ModifyAttribute("enable_notifications", false);
2214         }
2215 }
2216
2217 void ExternalCommandProcessor::DisableServicegroupSvcNotifications(double, const std::vector<String>& arguments)
2218 {
2219         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
2220
2221         if (!sg)
2222                 BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable service notifications for non-existent servicegroup '" + arguments[0] + "'"));
2223
2224         for (const Service::Ptr& service : sg->GetMembers()) {
2225                 Log(LogNotice, "ExternalCommandProcessor")
2226                         << "Disabling notifications for service '" << service->GetName() << "'";
2227
2228                 service->ModifyAttribute("enable_notifications", false);
2229         }
2230 }
2231
2232 boost::mutex& ExternalCommandProcessor::GetMutex()
2233 {
2234         static boost::mutex mtx;
2235         return mtx;
2236 }
2237
2238 std::map<String, ExternalCommandInfo>& ExternalCommandProcessor::GetCommands()
2239 {
2240         static std::map<String, ExternalCommandInfo> commands;
2241         return commands;
2242 }
2243