]> granicus.if.org Git - icinga2/blob - lib/icinga/externalcommandprocessor.cpp
Make the services/notifications caches thread safe.
[icinga2] / lib / icinga / externalcommandprocessor.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
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 "i2-icinga.h"
21
22 using namespace icinga;
23
24 boost::once_flag ExternalCommandProcessor::m_InitializeOnce = BOOST_ONCE_INIT;
25 boost::mutex ExternalCommandProcessor::m_Mutex;
26 map<String, ExternalCommandProcessor::Callback> ExternalCommandProcessor::m_Commands;
27
28 /**
29  * @threadsafety Always.
30  */
31 void ExternalCommandProcessor::Execute(const String& line)
32 {
33         if (line.IsEmpty())
34                 return;
35
36         if (line[0] != '[')
37                 BOOST_THROW_EXCEPTION(invalid_argument("Missing timestamp in command: " + line));
38
39         size_t pos = line.FindFirstOf("]");
40
41         if (pos == String::NPos)
42                 BOOST_THROW_EXCEPTION(invalid_argument("Missing timestamp in command: " + line));
43
44         String timestamp = line.SubStr(1, pos - 1);
45         String args = line.SubStr(pos + 2, String::NPos);
46
47         double ts = Convert::ToDouble(timestamp);
48
49         if (ts == 0)
50                 BOOST_THROW_EXCEPTION(invalid_argument("Invalid timestamp in command: " + line));
51
52         vector<String> argv = args.Split(is_any_of(";"));
53
54         if (argv.size() == 0)
55                 BOOST_THROW_EXCEPTION(invalid_argument("Missing arguments in command: " + line));
56
57         vector<String> argvExtra(argv.begin() + 1, argv.end());
58         Execute(ts, argv[0], argvExtra);
59 }
60
61 /**
62  * @threadsafety Always.
63  */
64 void ExternalCommandProcessor::Execute(double time, const String& command, const vector<String>& arguments)
65 {
66         boost::call_once(m_InitializeOnce, &ExternalCommandProcessor::Initialize);
67
68         Callback callback;
69
70         {
71                 boost::mutex::scoped_lock lock(m_Mutex);
72
73                 map<String, ExternalCommandProcessor::Callback>::iterator it;
74                 it = m_Commands.find(command);
75
76                 if (it == m_Commands.end())
77                         BOOST_THROW_EXCEPTION(invalid_argument("The external command '" + command + "' does not exist."));
78
79                 callback = it->second;
80         }
81
82         callback(time, arguments);
83 }
84
85 /**
86  * @threadsafety Always.
87  */
88 void ExternalCommandProcessor::Initialize(void)
89 {
90         RegisterCommand("PROCESS_HOST_CHECK_RESULT", &ExternalCommandProcessor::ProcessServiceCheckResult);
91         RegisterCommand("PROCESS_SERVICE_CHECK_RESULT", &ExternalCommandProcessor::ProcessServiceCheckResult);
92         RegisterCommand("SCHEDULE_HOST_CHECK", &ExternalCommandProcessor::ScheduleHostCheck);
93         RegisterCommand("SCHEDULE_FORCED_HOST_CHECK", &ExternalCommandProcessor::ScheduleForcedHostCheck);
94         RegisterCommand("SCHEDULE_SVC_CHECK", &ExternalCommandProcessor::ScheduleSvcCheck);
95         RegisterCommand("SCHEDULE_FORCED_SVC_CHECK", &ExternalCommandProcessor::ScheduleForcedSvcCheck);
96         RegisterCommand("ENABLE_HOST_CHECK", &ExternalCommandProcessor::EnableHostCheck);
97         RegisterCommand("DISABLE_HOST_CHECK", &ExternalCommandProcessor::DisableHostCheck);
98         RegisterCommand("ENABLE_SVC_CHECK", &ExternalCommandProcessor::EnableSvcCheck);
99         RegisterCommand("DISABLE_SVC_CHECK", &ExternalCommandProcessor::DisableSvcCheck);
100         RegisterCommand("SHUTDOWN_PROCESS", &ExternalCommandProcessor::ShutdownProcess);
101         RegisterCommand("SCHEDULE_FORCED_HOST_SVC_CHECKS", &ExternalCommandProcessor::ScheduleForcedHostSvcChecks);
102         RegisterCommand("SCHEDULE_HOST_SVC_CHECKS", &ExternalCommandProcessor::ScheduleHostSvcChecks);
103         RegisterCommand("ENABLE_HOST_SVC_CHECKS", &ExternalCommandProcessor::EnableHostSvcChecks);
104         RegisterCommand("DISABLE_HOST_SVC_CHECKS", &ExternalCommandProcessor::DisableHostSvcChecks);
105         RegisterCommand("ACKNOWLEDGE_SVC_PROBLEM", &ExternalCommandProcessor::AcknowledgeSvcProblem);
106         RegisterCommand("ACKNOWLEDGE_SVC_PROBLEM_EXPIRE", &ExternalCommandProcessor::AcknowledgeSvcProblemExpire);
107         RegisterCommand("REMOVE_SVC_ACKNOWLEDGEMENT", &ExternalCommandProcessor::RemoveHostAcknowledgement);
108         RegisterCommand("ACKNOWLEDGE_HOST_PROBLEM", &ExternalCommandProcessor::AcknowledgeHostProblem);
109         RegisterCommand("ACKNOWLEDGE_HOST_PROBLEM_EXPIRE", &ExternalCommandProcessor::AcknowledgeHostProblemExpire);
110         RegisterCommand("REMOVE_HOST_ACKNOWLEDGEMENT", &ExternalCommandProcessor::RemoveHostAcknowledgement);
111         RegisterCommand("ENABLE_HOSTGROUP_SVC_CHECKS", &ExternalCommandProcessor::EnableHostgroupSvcChecks);
112         RegisterCommand("DISABLE_HOSTGROUP_SVC_CHECKS", &ExternalCommandProcessor::DisableHostgroupSvcChecks);
113         RegisterCommand("ENABLE_SERVICEGROUP_SVC_CHECKS", &ExternalCommandProcessor::EnableServicegroupSvcChecks);
114         RegisterCommand("DISABLE_SERVICEGROUP_SVC_CHECKS", &ExternalCommandProcessor::DisableServicegroupSvcChecks);
115         RegisterCommand("ENABLE_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::EnablePassiveHostChecks);
116         RegisterCommand("DISABLE_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::DisablePassiveHostChecks);
117         RegisterCommand("ENABLE_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnablePassiveSvcChecks);
118         RegisterCommand("DISABLE_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisablePassiveSvcChecks);
119         RegisterCommand("ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnableServicegroupPassiveSvcChecks);
120         RegisterCommand("DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisableServicegroupPassiveSvcChecks);
121         RegisterCommand("ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnableHostgroupPassiveSvcChecks);
122         RegisterCommand("DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks);
123         RegisterCommand("PROCESS_FILE", &ExternalCommandProcessor::ProcessFile);
124         RegisterCommand("SCHEDULE_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleSvcDowntime);
125         RegisterCommand("DEL_SVC_DOWNTIME", &ExternalCommandProcessor::DelSvcDowntime);
126         RegisterCommand("SCHEDULE_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleHostDowntime);
127         RegisterCommand("DEL_HOST_DOWNTIME", &ExternalCommandProcessor::DelHostDowntime);
128         RegisterCommand("SCHEDULE_HOST_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleHostSvcDowntime);
129         RegisterCommand("SCHEDULE_HOSTGROUP_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleHostgroupHostDowntime);
130         RegisterCommand("SCHEDULE_HOSTGROUP_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleHostgroupSvcDowntime);
131         RegisterCommand("SCHEDULE_SERVICEGROUP_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleServicegroupHostDowntime);
132         RegisterCommand("SCHEDULE_SERVICEGROUP_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleServicegroupSvcDowntime);
133         RegisterCommand("ADD_HOST_COMMENT", &ExternalCommandProcessor::AddHostComment);
134         RegisterCommand("DEL_HOST_COMMENT", &ExternalCommandProcessor::DelHostComment);
135         RegisterCommand("ADD_SVC_COMMENT", &ExternalCommandProcessor::AddSvcComment);
136         RegisterCommand("DEL_SVC_COMMENT", &ExternalCommandProcessor::DelSvcComment);
137         RegisterCommand("DEL_ALL_HOST_COMMENTS", &ExternalCommandProcessor::DelAllHostComments);
138         RegisterCommand("DEL_ALL_SVC_COMMENTS", &ExternalCommandProcessor::DelAllSvcComments);
139         RegisterCommand("SEND_CUSTOM_HOST_NOTIFICATION", &ExternalCommandProcessor::SendCustomHostNotification);
140         RegisterCommand("SEND_CUSTOM_SVC_NOTIFICATION", &ExternalCommandProcessor::SendCustomSvcNotification);
141         RegisterCommand("DELAY_HOST_NOTIFICATION", &ExternalCommandProcessor::DelayHostNotification);
142         RegisterCommand("DELAY_SVC_NOTIFICATION", &ExternalCommandProcessor::DelaySvcNotification);
143         RegisterCommand("ENABLE_HOST_NOTIFICATIONS", &ExternalCommandProcessor::EnableHostNotifications);
144         RegisterCommand("DISABLE_HOST_NOTIFICATIONS", &ExternalCommandProcessor::DisableHostNotifications);
145         RegisterCommand("ENABLE_SVC_NOTIFICATIONS", &ExternalCommandProcessor::EnableSvcNotifications);
146         RegisterCommand("DISABLE_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableSvcNotifications);
147 }
148
149 /**
150  * @threadsafety Always.
151  */
152 void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandProcessor::Callback& callback)
153 {
154         boost::mutex::scoped_lock lock(m_Mutex);
155         m_Commands[command] = callback;
156 }
157
158 void ExternalCommandProcessor::ProcessHostCheckResult(double time, const vector<String>& arguments)
159 {
160         if (arguments.size() < 3)
161                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
162
163         Host::Ptr host = Host::GetByName(arguments[0]);
164
165         Service::Ptr hc = Host::GetHostCheckService(host);
166
167         if (!hc->GetEnablePassiveChecks())
168                 BOOST_THROW_EXCEPTION(invalid_argument("Got passive check result for host '" + arguments[0] + "' which has passive checks disabled."));
169
170         int exitStatus = Convert::ToDouble(arguments[2]);
171         Dictionary::Ptr result = PluginCheckTask::ParseCheckOutput(arguments[3]);
172         result->Set("state", PluginCheckTask::ExitStatusToState(exitStatus));
173
174         result->Set("schedule_start", time);
175         result->Set("schedule_end", time);
176         result->Set("execution_start", time);
177         result->Set("execution_end", time);
178         result->Set("active", 0);
179
180         Logger::Write(LogInformation, "icinga", "Processing passive check result for host '" + arguments[0] + "'");
181         hc->ProcessCheckResult(result);
182
183         /* Reschedule the next check. The side effect of this is that for as long
184          * as we receive passive results for a service we won't execute any
185          * active checks. */
186         hc->SetNextCheck(Utility::GetTime() + hc->GetCheckInterval());
187 }
188
189 void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const vector<String>& arguments)
190 {
191         if (arguments.size() < 4)
192                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 4 arguments."));
193
194         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
195
196         if (!service->GetEnablePassiveChecks())
197                 BOOST_THROW_EXCEPTION(invalid_argument("Got passive check result for service '" + arguments[1] + "' which has passive checks disabled."));
198
199         int exitStatus = Convert::ToDouble(arguments[2]);
200         Dictionary::Ptr result = PluginCheckTask::ParseCheckOutput(arguments[3]);
201         result->Set("state", PluginCheckTask::ExitStatusToState(exitStatus));
202
203         result->Set("schedule_start", time);
204         result->Set("schedule_end", time);
205         result->Set("execution_start", time);
206         result->Set("execution_end", time);
207         result->Set("active", 0);
208
209         Logger::Write(LogInformation, "icinga", "Processing passive check result for service '" + arguments[1] + "'");
210         service->ProcessCheckResult(result);
211
212         /* Reschedule the next check. The side effect of this is that for as long
213          * as we receive passive results for a service we won't execute any
214          * active checks. */
215         service->SetNextCheck(Utility::GetTime() + service->GetCheckInterval());
216 }
217
218 void ExternalCommandProcessor::ScheduleHostCheck(double, const vector<String>& arguments)
219 {
220         if (arguments.size() < 2)
221                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
222
223         Host::Ptr host = Host::GetByName(arguments[0]);
224
225         Service::Ptr hc = Host::GetHostCheckService(host);
226
227         double planned_check = Convert::ToDouble(arguments[1]);
228
229         if (planned_check > hc->GetNextCheck()) {
230                 Logger::Write(LogInformation, "icinga", "Ignoring reschedule request for host '" +
231                     arguments[0] + "' (next check is already sooner than requested check time)");
232                 return;
233         }
234
235         Logger::Write(LogInformation, "icinga", "Rescheduling next check for host '" + arguments[0] + "'");
236         hc->SetNextCheck(planned_check);
237 }
238
239 void ExternalCommandProcessor::ScheduleForcedHostCheck(double, const vector<String>& arguments)
240 {
241         if (arguments.size() < 2)
242                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
243
244         Host::Ptr host = Host::GetByName(arguments[0]);
245
246         Service::Ptr hc = Host::GetHostCheckService(host);
247
248         Logger::Write(LogInformation, "icinga", "Rescheduling next check for host '" + arguments[0] + "'");
249         hc->SetForceNextCheck(true);
250         hc->SetNextCheck(Convert::ToDouble(arguments[1]));
251 }
252
253 void ExternalCommandProcessor::ScheduleSvcCheck(double, const vector<String>& arguments)
254 {
255         if (arguments.size() < 3)
256                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
257
258         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
259
260         double planned_check = Convert::ToDouble(arguments[2]);
261
262         if (planned_check > service->GetNextCheck()) {
263                 Logger::Write(LogInformation, "icinga", "Ignoring reschedule request for service '" +
264                     arguments[1] + "' (next check is already sooner than requested check time)");
265                 return;
266         }
267
268         Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + arguments[1] + "'");
269         service->SetNextCheck(planned_check);
270 }
271
272 void ExternalCommandProcessor::ScheduleForcedSvcCheck(double, const vector<String>& arguments)
273 {
274         if (arguments.size() < 3)
275                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
276
277         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
278
279         Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + arguments[1] + "'");
280         service->SetForceNextCheck(true);
281         service->SetNextCheck(Convert::ToDouble(arguments[2]));
282 }
283
284 void ExternalCommandProcessor::EnableHostCheck(double, const vector<String>& arguments)
285 {
286         if (arguments.size() < 1)
287                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
288
289         Host::Ptr host = Host::GetByName(arguments[0]);
290
291         Logger::Write(LogInformation, "icinga", "Enabling active checks for host '" + arguments[0] + "'");
292         Service::Ptr hc = Host::GetHostCheckService(host);
293
294         if (hc)
295                 hc->SetEnableActiveChecks(true);
296 }
297
298 void ExternalCommandProcessor::DisableHostCheck(double, const vector<String>& arguments)
299 {
300         if (arguments.size() < 1)
301                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
302
303         Host::Ptr host = Host::GetByName(arguments[0]);
304
305         Logger::Write(LogInformation, "icinga", "Disabling active checks for host '" + arguments[0] + "'");
306         Service::Ptr hc = Host::GetHostCheckService(host);
307
308         if (hc)
309                 hc->SetEnableActiveChecks(false);
310 }
311
312 void ExternalCommandProcessor::EnableSvcCheck(double, const vector<String>& arguments)
313 {
314         if (arguments.size() < 2)
315                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
316
317         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
318
319         Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + arguments[1] + "'");
320         service->SetEnableActiveChecks(true);
321 }
322
323 void ExternalCommandProcessor::DisableSvcCheck(double, const vector<String>& arguments)
324 {
325         if (arguments.size() < 2)
326                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
327
328         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
329
330         Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + arguments[1] + "'");
331         service->SetEnableActiveChecks(false);
332 }
333
334 void ExternalCommandProcessor::ShutdownProcess(double, const vector<String>&)
335 {
336         Logger::Write(LogInformation, "icinga", "Shutting down Icinga via external command.");
337         Application::RequestShutdown();
338 }
339
340 void ExternalCommandProcessor::ScheduleForcedHostSvcChecks(double, const vector<String>& arguments)
341 {
342         if (arguments.size() < 2)
343                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
344
345         double planned_check = Convert::ToDouble(arguments[1]);
346
347         Host::Ptr host = Host::GetByName(arguments[0]);
348
349         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
350                 Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + service->GetName() + "'");
351                 service->SetNextCheck(planned_check);
352                 service->SetForceNextCheck(true);
353         }
354 }
355
356 void ExternalCommandProcessor::ScheduleHostSvcChecks(double, const vector<String>& arguments)
357 {
358         if (arguments.size() < 2)
359                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
360
361         double planned_check = Convert::ToDouble(arguments[1]);
362
363         Host::Ptr host = Host::GetByName(arguments[0]);
364
365         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
366                 if (planned_check > service->GetNextCheck()) {
367                         Logger::Write(LogInformation, "icinga", "Ignoring reschedule request for service '" +
368                             service->GetName() + "' (next check is already sooner than requested check time)");
369                         continue;
370                 }
371
372                 Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + service->GetName() + "'");
373                 service->SetNextCheck(planned_check);
374         }
375 }
376
377 void ExternalCommandProcessor::EnableHostSvcChecks(double, const vector<String>& arguments)
378 {
379         if (arguments.size() < 1)
380                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
381
382         Host::Ptr host = Host::GetByName(arguments[0]);
383
384         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
385                 Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
386                 service->SetEnableActiveChecks(true);
387         }
388 }
389
390 void ExternalCommandProcessor::DisableHostSvcChecks(double, const vector<String>& arguments)
391 {
392         if (arguments.size() < 1)
393                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 arguments."));
394
395         Host::Ptr host = Host::GetByName(arguments[0]);
396
397         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
398                 Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
399                 service->SetEnableActiveChecks(false);
400         }
401 }
402
403 void ExternalCommandProcessor::AcknowledgeSvcProblem(double, const vector<String>& arguments)
404 {
405         if (arguments.size() < 7)
406                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 7 arguments."));
407
408         bool sticky = Convert::ToBool(arguments[2]);
409
410         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
411
412         if (service->GetState() == StateOK)
413                 BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK."));
414
415         Logger::Write(LogInformation, "icinga", "Setting acknowledgement for service '" + service->GetName() + "'");
416         service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal);
417 }
418
419 void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const vector<String>& arguments)
420 {
421         if (arguments.size() < 8)
422                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
423
424         bool sticky = Convert::ToBool(arguments[2]);
425         double timestamp = Convert::ToDouble(arguments[5]);
426
427         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
428
429         if (service->GetState() == StateOK)
430                 BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK."));
431
432         Logger::Write(LogInformation, "icinga", "Setting timed acknowledgement for service '" + service->GetName() + "'");
433         service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal, timestamp);
434 }
435
436 void ExternalCommandProcessor::RemoveSvcAcknowledgement(double, const vector<String>& arguments)
437 {
438         if (arguments.size() < 2)
439                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
440
441         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
442
443         Logger::Write(LogInformation, "icinga", "Removing acknowledgement for service '" + service->GetName() + "'");
444         service->ClearAcknowledgement();
445 }
446
447 void ExternalCommandProcessor::AcknowledgeHostProblem(double, const vector<String>& arguments)
448 {
449         if (arguments.size() < 6)
450                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 6 arguments."));
451
452         bool sticky = Convert::ToBool(arguments[1]);
453
454         Host::Ptr host = Host::GetByName(arguments[0]);
455
456         Logger::Write(LogInformation, "icinga", "Setting acknowledgement for host '" + host->GetName() + "'");
457         Service::Ptr service = Host::GetHostCheckService(host);
458         if (service) {
459                 if (service->GetState() == StateOK)
460                         BOOST_THROW_EXCEPTION(invalid_argument("The host '" + arguments[0] + "' is OK."));
461
462                 service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal);
463         }
464 }
465
466 void ExternalCommandProcessor::AcknowledgeHostProblemExpire(double, const vector<String>& arguments)
467 {
468         if (arguments.size() < 7)
469                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 7 arguments."));
470
471         bool sticky = Convert::ToBool(arguments[1]);
472         double timestamp = Convert::ToDouble(arguments[4]);
473
474         Host::Ptr host = Host::GetByName(arguments[0]);
475
476         Logger::Write(LogInformation, "icinga", "Setting timed acknowledgement for host '" + host->GetName() + "'");
477         Service::Ptr service = Host::GetHostCheckService(host);
478         if (service) {
479                 if (service->GetState() == StateOK)
480                         BOOST_THROW_EXCEPTION(invalid_argument("The host '" + arguments[0] + "' is OK."));
481
482                 service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal, timestamp);
483         }
484 }
485
486 void ExternalCommandProcessor::RemoveHostAcknowledgement(double, const vector<String>& arguments)
487 {
488         if (arguments.size() < 1)
489                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
490
491         Host::Ptr host = Host::GetByName(arguments[0]);
492
493         Logger::Write(LogInformation, "icinga", "Removing acknowledgement for host '" + host->GetName() + "'");
494         Service::Ptr service = Host::GetHostCheckService(host);
495         if (service) {
496                 service->ClearAcknowledgement();
497         }
498 }
499
500 void ExternalCommandProcessor::EnableHostgroupSvcChecks(double, const vector<String>& arguments)
501 {
502         if (arguments.size() < 1)
503                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
504
505         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
506
507         BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
508                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
509                         Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
510                         service->SetEnableActiveChecks(true);
511                 }
512         }
513 }
514
515 void ExternalCommandProcessor::DisableHostgroupSvcChecks(double, const vector<String>& arguments)
516 {
517         if (arguments.size() < 1)
518                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
519
520         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
521
522         BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
523                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
524                         Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
525                         service->SetEnableActiveChecks(false);
526                 }
527         }
528 }
529
530 void ExternalCommandProcessor::EnableServicegroupSvcChecks(double, const vector<String>& arguments)
531 {
532         if (arguments.size() < 1)
533                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
534
535         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
536
537         BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
538                 Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
539                 service->SetEnableActiveChecks(true);
540         }
541 }
542
543 void ExternalCommandProcessor::DisableServicegroupSvcChecks(double, const vector<String>& arguments)
544 {
545         if (arguments.size() < 1)
546                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
547
548         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
549
550         BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
551                 Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
552                 service->SetEnableActiveChecks(false);
553         }
554 }
555
556 void ExternalCommandProcessor::EnablePassiveHostChecks(double, const vector<String>& arguments)
557 {
558         if (arguments.size() < 1)
559                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
560
561         Host::Ptr host = Host::GetByName(arguments[0]);
562
563         Logger::Write(LogInformation, "icinga", "Enabling passive checks for host '" + arguments[0] + "'");
564         Service::Ptr hc = Host::GetHostCheckService(host);
565
566         if (hc)
567                 hc->SetEnablePassiveChecks(true);
568 }
569
570 void ExternalCommandProcessor::DisablePassiveHostChecks(double, const vector<String>& arguments)
571 {
572         if (arguments.size() < 1)
573                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 arguments."));
574
575         Host::Ptr host = Host::GetByName(arguments[0]);
576
577         Logger::Write(LogInformation, "icinga", "Disabling passive checks for host '" + arguments[0] + "'");
578         Service::Ptr hc = Host::GetHostCheckService(host);
579
580         if (hc)
581                 hc->SetEnablePassiveChecks(false);
582 }
583
584 void ExternalCommandProcessor::EnablePassiveSvcChecks(double, const vector<String>& arguments)
585 {
586         if (arguments.size() < 2)
587                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
588
589         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
590
591         Logger::Write(LogInformation, "icinga", "Enabling passive checks for service '" + arguments[1] + "'");
592         service->SetEnablePassiveChecks(true);
593 }
594
595 void ExternalCommandProcessor::DisablePassiveSvcChecks(double, const vector<String>& arguments)
596 {
597         if (arguments.size() < 2)
598                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
599
600         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
601
602         Logger::Write(LogInformation, "icinga", "Disabling passive checks for service '" + arguments[1] + "'");
603         service->SetEnablePassiveChecks(false);
604 }
605
606 void ExternalCommandProcessor::EnableServicegroupPassiveSvcChecks(double, const vector<String>& arguments)
607 {
608         if (arguments.size() < 1)
609                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
610
611         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
612
613         BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
614                 Logger::Write(LogInformation, "icinga", "Enabling passive checks for service '" + service->GetName() + "'");
615                 service->SetEnablePassiveChecks(true);
616         }
617 }
618
619 void ExternalCommandProcessor::DisableServicegroupPassiveSvcChecks(double, const vector<String>& arguments)
620 {
621         if (arguments.size() < 1)
622                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
623
624         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
625
626         BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
627                 Logger::Write(LogInformation, "icinga", "Disabling passive checks for service '" + service->GetName() + "'");
628                 service->SetEnablePassiveChecks(true);
629         }
630 }
631
632 void ExternalCommandProcessor::EnableHostgroupPassiveSvcChecks(double, const vector<String>& arguments)
633 {
634         if (arguments.size() < 1)
635                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
636
637         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
638
639         BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
640                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
641                         Logger::Write(LogInformation, "icinga", "Enabling passive checks for service '" + service->GetName() + "'");
642                         service->SetEnablePassiveChecks(true);
643                 }
644         }
645 }
646
647 void ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks(double, const vector<String>& arguments)
648 {
649         if (arguments.size() < 1)
650                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
651
652         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
653
654         BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
655                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
656                         Logger::Write(LogInformation, "icinga", "Disabling passive checks for service '" + service->GetName() + "'");
657                         service->SetEnablePassiveChecks(false);
658                 }
659         }
660 }
661
662 void ExternalCommandProcessor::ProcessFile(double, const vector<String>& arguments)
663 {
664         if (arguments.size() < 2)
665                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
666
667         String file = arguments[0];
668         bool del = Convert::ToBool(arguments[1]);
669
670         ifstream ifp;
671         ifp.exceptions(ifstream::badbit);
672
673         ifp.open(file.CStr(), ifstream::in);
674
675         while(ifp.good()) {
676                 std::string line;
677                 std::getline(ifp, line);
678
679                 try {
680                         Logger::Write(LogInformation, "compat", "Executing external command: " + line);
681
682                         Execute(line);
683                 } catch (const exception& ex) {
684                         stringstream msgbuf;
685                         msgbuf << "External command failed: " << diagnostic_information(ex);
686                         Logger::Write(LogWarning, "icinga", msgbuf.str());
687                 }
688         }
689
690         ifp.close();
691
692         if (del)
693                 (void) unlink(file.CStr());
694 }
695
696 void ExternalCommandProcessor::ScheduleSvcDowntime(double, const vector<String>& arguments)
697 {
698         if (arguments.size() < 9)
699                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 9 arguments."));
700
701         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
702
703         String triggeredBy;
704         int triggeredByLegacy = Convert::ToLong(arguments[5]);
705         if (triggeredByLegacy != 0)
706                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
707
708         Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
709         (void) service->AddDowntime(arguments[7], arguments[8],
710             Convert::ToDouble(arguments[2]), Convert::ToDouble(arguments[3]),
711             Convert::ToBool(arguments[4]), triggeredBy, Convert::ToDouble(arguments[6]));
712 }
713
714 void ExternalCommandProcessor::DelSvcDowntime(double, const vector<String>& arguments)
715 {
716         if (arguments.size() < 1)
717                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
718
719         int id = Convert::ToLong(arguments[0]);
720         Logger::Write(LogInformation, "icinga", "Removing downtime ID " + arguments[0]);
721         String rid = Service::GetDowntimeIDFromLegacyID(id);
722         Service::RemoveDowntime(rid);
723 }
724
725 void ExternalCommandProcessor::ScheduleHostDowntime(double, const vector<String>& arguments)
726 {
727         if (arguments.size() < 8)
728                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
729
730         Host::Ptr host = Host::GetByName(arguments[0]);
731
732         String triggeredBy;
733         int triggeredByLegacy = Convert::ToLong(arguments[4]);
734         if (triggeredByLegacy != 0)
735                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
736
737         Logger::Write(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
738         Service::Ptr service = Host::GetHostCheckService(host);
739         if (service) {
740                 (void) service->AddDowntime(arguments[6], arguments[7],
741                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
742                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
743         }
744 }
745
746 void ExternalCommandProcessor::DelHostDowntime(double, const vector<String>& arguments)
747 {
748         if (arguments.size() < 1)
749                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
750
751         int id = Convert::ToLong(arguments[0]);
752         Logger::Write(LogInformation, "icinga", "Removing downtime ID " + arguments[0]);
753         String rid = Service::GetDowntimeIDFromLegacyID(id);
754         Service::RemoveDowntime(rid);
755 }
756
757 void ExternalCommandProcessor::ScheduleHostSvcDowntime(double, const vector<String>& arguments)
758 {
759         if (arguments.size() < 8)
760                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 argument."));
761
762         Host::Ptr host = Host::GetByName(arguments[0]);
763
764         String triggeredBy;
765         int triggeredByLegacy = Convert::ToLong(arguments[4]);
766         if (triggeredByLegacy != 0)
767                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
768
769         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
770                 Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
771                 (void) service->AddDowntime(arguments[6], arguments[7],
772                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
773                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
774         }
775 }
776
777 void ExternalCommandProcessor::ScheduleHostgroupHostDowntime(double, const vector<String>& arguments)
778 {
779         if (arguments.size() < 8)
780                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
781
782         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
783
784         String triggeredBy;
785         int triggeredByLegacy = Convert::ToLong(arguments[4]);
786         if (triggeredByLegacy != 0)
787                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
788
789         BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
790                 Logger::Write(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
791                 Service::Ptr service = Host::GetHostCheckService(host);
792                 if (service) {
793                         (void) service->AddDowntime(arguments[6], arguments[7],
794                             Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
795                             Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
796                 }
797         }
798 }
799
800 void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const vector<String>& arguments)
801 {
802         if (arguments.size() < 8)
803                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
804
805         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
806
807         String triggeredBy;
808         int triggeredByLegacy = Convert::ToLong(arguments[4]);
809         if (triggeredByLegacy != 0)
810                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
811
812         /* Note: we can't just directly create downtimes for all the services by iterating
813          * over all hosts in the host group - otherwise we might end up creating multiple
814          * downtimes for some services. */
815
816         set<Service::Ptr> services;
817
818         BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
819                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
820                         services.insert(service);
821                 }
822         }
823
824         BOOST_FOREACH(const Service::Ptr& service, services) {
825                 Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
826                 (void) service->AddDowntime(arguments[6], arguments[7],
827                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
828                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
829         }
830 }
831
832 void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const vector<String>& arguments)
833 {
834         if (arguments.size() < 8)
835                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
836
837         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
838
839         String triggeredBy;
840         int triggeredByLegacy = Convert::ToLong(arguments[4]);
841         if (triggeredByLegacy != 0)
842                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
843
844         /* Note: we can't just directly create downtimes for all the hosts by iterating
845          * over all services in the service group - otherwise we might end up creating multiple
846          * downtimes for some hosts. */
847
848         set<Service::Ptr> services;
849
850         BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
851                 Host::Ptr host = service->GetHost();
852                 Service::Ptr hcService = Host::GetHostCheckService(host);
853                 if (hcService)
854                         services.insert(hcService);
855         }
856
857         BOOST_FOREACH(const Service::Ptr& service, services) {
858                 Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
859                 (void) service->AddDowntime(arguments[6], arguments[7],
860                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
861                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
862         }
863 }
864
865 void ExternalCommandProcessor::ScheduleServicegroupSvcDowntime(double, const vector<String>& arguments)
866 {
867         if (arguments.size() < 8)
868                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
869
870         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
871
872         String triggeredBy;
873         int triggeredByLegacy = Convert::ToLong(arguments[4]);
874         if (triggeredByLegacy != 0)
875                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
876
877         BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
878                 Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
879                 (void) service->AddDowntime(arguments[6], arguments[7],
880                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
881                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
882         }
883 }
884
885 void ExternalCommandProcessor::AddHostComment(double, const vector<String>& arguments)
886 {
887         if (arguments.size() < 4)
888                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 4 arguments."));
889
890         Host::Ptr host = Host::GetByName(arguments[0]);
891
892         Logger::Write(LogInformation, "icinga", "Creating comment for host " + host->GetName());
893         Service::Ptr service = Host::GetHostCheckService(host);
894         if (service)
895                 (void) service->AddComment(CommentUser, arguments[2], arguments[3], 0);
896 }
897
898 void ExternalCommandProcessor::DelHostComment(double, const vector<String>& arguments)
899 {
900         if (arguments.size() < 1)
901                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
902
903         int id = Convert::ToLong(arguments[0]);
904         Logger::Write(LogInformation, "icinga", "Removing comment ID " + arguments[0]);
905         String rid = Service::GetCommentIDFromLegacyID(id);
906         Service::RemoveComment(rid);
907 }
908
909 void ExternalCommandProcessor::AddSvcComment(double, const vector<String>& arguments)
910 {
911         if (arguments.size() < 5)
912                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 5 arguments."));
913
914         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
915
916         Logger::Write(LogInformation, "icinga", "Creating comment for service " + service->GetName());
917         (void) service->AddComment(CommentUser, arguments[3], arguments[4], 0);
918 }
919
920 void ExternalCommandProcessor::DelSvcComment(double, const vector<String>& arguments)
921 {
922         if (arguments.size() < 1)
923                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
924
925         int id = Convert::ToLong(arguments[0]);
926         Logger::Write(LogInformation, "icinga", "Removing comment ID " + arguments[0]);
927
928         String rid = Service::GetCommentIDFromLegacyID(id);
929         Service::RemoveComment(rid);
930 }
931
932 void ExternalCommandProcessor::DelAllHostComments(double, const vector<String>& arguments)
933 {
934         if (arguments.size() < 1)
935                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
936
937         Host::Ptr host = Host::GetByName(arguments[0]);
938
939         Logger::Write(LogInformation, "icinga", "Removing all comments for host " + host->GetName());
940         Service::Ptr service = Host::GetHostCheckService(host);
941         if (service)
942                 service->RemoveAllComments();
943 }
944
945 void ExternalCommandProcessor::DelAllSvcComments(double, const vector<String>& arguments)
946 {
947         if (arguments.size() < 2)
948                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
949
950         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
951
952         Logger::Write(LogInformation, "icinga", "Removing all comments for service " + service->GetName());
953         service->RemoveAllComments();
954 }
955
956 void ExternalCommandProcessor::SendCustomHostNotification(double time, const vector<String>& arguments)
957 {
958         if (arguments.size() < 4)
959                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 4 arguments."));
960
961         Host::Ptr host = Host::GetByName(arguments[0]);
962
963         Logger::Write(LogInformation, "icinga", "Sending custom notification for host " + host->GetName());
964         Service::Ptr service = Host::GetHostCheckService(host);
965         if (service) {
966                 service->RequestNotifications(NotificationCustom);
967         }
968 }
969
970 void ExternalCommandProcessor::SendCustomSvcNotification(double time, const vector<String>& arguments)
971 {
972         if (arguments.size() < 5)
973                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 5 arguments."));
974
975         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
976
977         Logger::Write(LogInformation, "icinga", "Sending custom notification for service " + service->GetName());
978         service->RequestNotifications(NotificationCustom);
979 }
980
981 void ExternalCommandProcessor::DelayHostNotification(double time, const vector<String>& arguments)
982 {
983         if (arguments.size() < 2)
984                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
985
986         Host::Ptr host = Host::GetByName(arguments[0]);
987
988         Logger::Write(LogInformation, "icinga", "Delaying notifications for host " + host->GetName());
989         Service::Ptr service = Host::GetHostCheckService(host);
990         if (service) {
991                 service->SetLastNotification(Convert::ToDouble(arguments[1]));
992         }
993 }
994
995 void ExternalCommandProcessor::DelaySvcNotification(double time, const vector<String>& arguments)
996 {
997         if (arguments.size() < 3)
998                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
999
1000         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1001
1002         Logger::Write(LogInformation, "icinga", "Delaying notifications for service " + service->GetName());
1003         service->SetLastNotification(Convert::ToDouble(arguments[2]));
1004 }
1005
1006 void ExternalCommandProcessor::EnableHostNotifications(double, const vector<String>& arguments)
1007 {
1008         if (arguments.size() < 1)
1009                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
1010
1011         Host::Ptr host = Host::GetByName(arguments[0]);
1012
1013         Logger::Write(LogInformation, "icinga", "Enabling notifications for host '" + arguments[0] + "'");
1014         Service::Ptr hc = Host::GetHostCheckService(host);
1015
1016         if (hc)
1017                 hc->SetEnableNotifications(true);
1018 }
1019
1020 void ExternalCommandProcessor::DisableHostNotifications(double, const vector<String>& arguments)
1021 {
1022         if (arguments.size() < 1)
1023                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
1024
1025         Host::Ptr host = Host::GetByName(arguments[0]);
1026
1027         Logger::Write(LogInformation, "icinga", "Disabling notifications for host '" + arguments[0] + "'");
1028         Service::Ptr hc = Host::GetHostCheckService(host);
1029
1030         if (hc)
1031                 hc->SetEnableNotifications(false);
1032 }
1033
1034 void ExternalCommandProcessor::EnableSvcNotifications(double, const vector<String>& arguments)
1035 {
1036         if (arguments.size() < 2)
1037                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
1038
1039         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1040
1041         Logger::Write(LogInformation, "icinga", "Enabling notifications for service '" + arguments[1] + "'");
1042         service->SetEnableNotifications(true);
1043 }
1044
1045 void ExternalCommandProcessor::DisableSvcNotifications(double, const vector<String>& arguments)
1046 {
1047         if (arguments.size() < 2)
1048                 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
1049
1050         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1051
1052         Logger::Write(LogInformation, "icinga", "Disabling notifications for service '" + arguments[1] + "'");
1053         service->SetEnableNotifications(false);
1054 }