]> granicus.if.org Git - icinga2/blob - lib/icinga/externalcommandprocessor.cpp
aa1b9ca62b08cf279b6623ac63e3d7e7ccfd8bcb
[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 "icinga/externalcommandprocessor.h"
21 #include "icinga/host.h"
22 #include "icinga/service.h"
23 #include "icinga/user.h"
24 #include "icinga/hostgroup.h"
25 #include "icinga/servicegroup.h"
26 #include "icinga/pluginchecktask.h"
27 #include "base/convert.h"
28 #include "base/logger_fwd.h"
29 #include "base/objectlock.h"
30 #include "base/application.h"
31 #include "base/utility.h"
32 #include <fstream>
33 #include <boost/algorithm/string/classification.hpp>
34 #include <boost/foreach.hpp>
35 #include <boost/exception/diagnostic_information.hpp>
36 #include <boost/algorithm/string/split.hpp>
37
38 using namespace icinga;
39
40 boost::once_flag ExternalCommandProcessor::m_InitializeOnce = BOOST_ONCE_INIT;
41 boost::mutex ExternalCommandProcessor::m_Mutex;
42 std::map<String, ExternalCommandProcessor::Callback> ExternalCommandProcessor::m_Commands;
43
44 void ExternalCommandProcessor::Execute(const String& line)
45 {
46         if (line.IsEmpty())
47                 return;
48
49         if (line[0] != '[')
50                 BOOST_THROW_EXCEPTION(std::invalid_argument("Missing timestamp in command: " + line));
51
52         size_t pos = line.FindFirstOf("]");
53
54         if (pos == String::NPos)
55                 BOOST_THROW_EXCEPTION(std::invalid_argument("Missing timestamp in command: " + line));
56
57         String timestamp = line.SubStr(1, pos - 1);
58         String args = line.SubStr(pos + 2, String::NPos);
59
60         double ts = Convert::ToDouble(timestamp);
61
62         if (ts == 0)
63                 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid timestamp in command: " + line));
64
65         std::vector<String> argv;
66         boost::algorithm::split(argv, args, boost::is_any_of(";"));
67
68         if (argv.empty())
69                 BOOST_THROW_EXCEPTION(std::invalid_argument("Missing arguments in command: " + line));
70
71         std::vector<String> argvExtra(argv.begin() + 1, argv.end());
72         Execute(ts, argv[0], argvExtra);
73 }
74
75 void ExternalCommandProcessor::Execute(double time, const String& command, const std::vector<String>& arguments)
76 {
77         boost::call_once(m_InitializeOnce, &ExternalCommandProcessor::Initialize);
78
79         Callback callback;
80
81         {
82                 boost::mutex::scoped_lock lock(m_Mutex);
83
84                 std::map<String, ExternalCommandProcessor::Callback>::iterator it;
85                 it = m_Commands.find(command);
86
87                 if (it == m_Commands.end())
88                         BOOST_THROW_EXCEPTION(std::invalid_argument("The external command '" + command + "' does not exist."));
89
90                 callback = it->second;
91         }
92
93         callback(time, arguments);
94 }
95
96 void ExternalCommandProcessor::Initialize(void)
97 {
98         RegisterCommand("PROCESS_HOST_CHECK_RESULT", &ExternalCommandProcessor::ProcessHostCheckResult);
99         RegisterCommand("PROCESS_SERVICE_CHECK_RESULT", &ExternalCommandProcessor::ProcessServiceCheckResult);
100         RegisterCommand("SCHEDULE_HOST_CHECK", &ExternalCommandProcessor::ScheduleHostCheck);
101         RegisterCommand("SCHEDULE_FORCED_HOST_CHECK", &ExternalCommandProcessor::ScheduleForcedHostCheck);
102         RegisterCommand("SCHEDULE_SVC_CHECK", &ExternalCommandProcessor::ScheduleSvcCheck);
103         RegisterCommand("SCHEDULE_FORCED_SVC_CHECK", &ExternalCommandProcessor::ScheduleForcedSvcCheck);
104         RegisterCommand("ENABLE_HOST_CHECK", &ExternalCommandProcessor::EnableHostCheck);
105         RegisterCommand("DISABLE_HOST_CHECK", &ExternalCommandProcessor::DisableHostCheck);
106         RegisterCommand("ENABLE_SVC_CHECK", &ExternalCommandProcessor::EnableSvcCheck);
107         RegisterCommand("DISABLE_SVC_CHECK", &ExternalCommandProcessor::DisableSvcCheck);
108         RegisterCommand("SHUTDOWN_PROCESS", &ExternalCommandProcessor::ShutdownProcess);
109         RegisterCommand("RESTART_PROCESS", &ExternalCommandProcessor::RestartProcess);
110         RegisterCommand("SCHEDULE_FORCED_HOST_SVC_CHECKS", &ExternalCommandProcessor::ScheduleForcedHostSvcChecks);
111         RegisterCommand("SCHEDULE_HOST_SVC_CHECKS", &ExternalCommandProcessor::ScheduleHostSvcChecks);
112         RegisterCommand("ENABLE_HOST_SVC_CHECKS", &ExternalCommandProcessor::EnableHostSvcChecks);
113         RegisterCommand("DISABLE_HOST_SVC_CHECKS", &ExternalCommandProcessor::DisableHostSvcChecks);
114         RegisterCommand("ACKNOWLEDGE_SVC_PROBLEM", &ExternalCommandProcessor::AcknowledgeSvcProblem);
115         RegisterCommand("ACKNOWLEDGE_SVC_PROBLEM_EXPIRE", &ExternalCommandProcessor::AcknowledgeSvcProblemExpire);
116         RegisterCommand("REMOVE_SVC_ACKNOWLEDGEMENT", &ExternalCommandProcessor::RemoveSvcAcknowledgement);
117         RegisterCommand("ACKNOWLEDGE_HOST_PROBLEM", &ExternalCommandProcessor::AcknowledgeHostProblem);
118         RegisterCommand("ACKNOWLEDGE_HOST_PROBLEM_EXPIRE", &ExternalCommandProcessor::AcknowledgeHostProblemExpire);
119         RegisterCommand("REMOVE_HOST_ACKNOWLEDGEMENT", &ExternalCommandProcessor::RemoveHostAcknowledgement);
120         RegisterCommand("DISABLE_HOST_FLAP_DETECTION", &ExternalCommandProcessor::DisableHostFlapping);
121         RegisterCommand("ENABLE_HOST_FLAP_DETECTION", &ExternalCommandProcessor::EnableHostFlapping);
122         RegisterCommand("DISABLE_SVC_FLAP_DETECTION", &ExternalCommandProcessor::DisableSvcFlapping);
123         RegisterCommand("ENABLE_SVC_FLAP_DETECTION", &ExternalCommandProcessor::EnableSvcFlapping);
124         RegisterCommand("ENABLE_HOSTGROUP_SVC_CHECKS", &ExternalCommandProcessor::EnableHostgroupSvcChecks);
125         RegisterCommand("DISABLE_HOSTGROUP_SVC_CHECKS", &ExternalCommandProcessor::DisableHostgroupSvcChecks);
126         RegisterCommand("ENABLE_SERVICEGROUP_SVC_CHECKS", &ExternalCommandProcessor::EnableServicegroupSvcChecks);
127         RegisterCommand("DISABLE_SERVICEGROUP_SVC_CHECKS", &ExternalCommandProcessor::DisableServicegroupSvcChecks);
128         RegisterCommand("ENABLE_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::EnablePassiveHostChecks);
129         RegisterCommand("DISABLE_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::DisablePassiveHostChecks);
130         RegisterCommand("ENABLE_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnablePassiveSvcChecks);
131         RegisterCommand("DISABLE_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisablePassiveSvcChecks);
132         RegisterCommand("ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnableServicegroupPassiveSvcChecks);
133         RegisterCommand("DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisableServicegroupPassiveSvcChecks);
134         RegisterCommand("ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnableHostgroupPassiveSvcChecks);
135         RegisterCommand("DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks);
136         RegisterCommand("PROCESS_FILE", &ExternalCommandProcessor::ProcessFile);
137         RegisterCommand("SCHEDULE_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleSvcDowntime);
138         RegisterCommand("DEL_SVC_DOWNTIME", &ExternalCommandProcessor::DelSvcDowntime);
139         RegisterCommand("SCHEDULE_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleHostDowntime);
140         RegisterCommand("DEL_HOST_DOWNTIME", &ExternalCommandProcessor::DelHostDowntime);
141         RegisterCommand("SCHEDULE_HOST_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleHostSvcDowntime);
142         RegisterCommand("SCHEDULE_HOSTGROUP_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleHostgroupHostDowntime);
143         RegisterCommand("SCHEDULE_HOSTGROUP_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleHostgroupSvcDowntime);
144         RegisterCommand("SCHEDULE_SERVICEGROUP_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleServicegroupHostDowntime);
145         RegisterCommand("SCHEDULE_SERVICEGROUP_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleServicegroupSvcDowntime);
146         RegisterCommand("ADD_HOST_COMMENT", &ExternalCommandProcessor::AddHostComment);
147         RegisterCommand("DEL_HOST_COMMENT", &ExternalCommandProcessor::DelHostComment);
148         RegisterCommand("ADD_SVC_COMMENT", &ExternalCommandProcessor::AddSvcComment);
149         RegisterCommand("DEL_SVC_COMMENT", &ExternalCommandProcessor::DelSvcComment);
150         RegisterCommand("DEL_ALL_HOST_COMMENTS", &ExternalCommandProcessor::DelAllHostComments);
151         RegisterCommand("DEL_ALL_SVC_COMMENTS", &ExternalCommandProcessor::DelAllSvcComments);
152         RegisterCommand("SEND_CUSTOM_HOST_NOTIFICATION", &ExternalCommandProcessor::SendCustomHostNotification);
153         RegisterCommand("SEND_CUSTOM_SVC_NOTIFICATION", &ExternalCommandProcessor::SendCustomSvcNotification);
154         RegisterCommand("DELAY_HOST_NOTIFICATION", &ExternalCommandProcessor::DelayHostNotification);
155         RegisterCommand("DELAY_SVC_NOTIFICATION", &ExternalCommandProcessor::DelaySvcNotification);
156         RegisterCommand("ENABLE_HOST_NOTIFICATIONS", &ExternalCommandProcessor::EnableHostNotifications);
157         RegisterCommand("DISABLE_HOST_NOTIFICATIONS", &ExternalCommandProcessor::DisableHostNotifications);
158         RegisterCommand("ENABLE_SVC_NOTIFICATIONS", &ExternalCommandProcessor::EnableSvcNotifications);
159         RegisterCommand("DISABLE_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableSvcNotifications);
160         RegisterCommand("DISABLE_HOSTGROUP_HOST_CHECKS", &ExternalCommandProcessor::DisableHostgroupHostChecks);
161         RegisterCommand("DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::DisableHostgroupPassiveHostChecks);
162         RegisterCommand("DISABLE_SERVICEGROUP_HOST_CHECKS", &ExternalCommandProcessor::DisableServicegroupHostChecks);
163         RegisterCommand("DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::DisableServicegroupPassiveHostChecks);
164         RegisterCommand("ENABLE_HOSTGROUP_HOST_CHECKS", &ExternalCommandProcessor::EnableHostgroupHostChecks);
165         RegisterCommand("ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::EnableHostgroupPassiveHostChecks);
166         RegisterCommand("ENABLE_SERVICEGROUP_HOST_CHECKS", &ExternalCommandProcessor::EnableServicegroupHostChecks);
167         RegisterCommand("ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::EnableServicegroupPassiveHostChecks);
168 }
169
170 void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandProcessor::Callback& callback)
171 {
172         boost::mutex::scoped_lock lock(m_Mutex);
173         m_Commands[command] = callback;
174 }
175
176 void ExternalCommandProcessor::ProcessHostCheckResult(double time, const std::vector<String>& arguments)
177 {
178         if (arguments.size() < 3)
179                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 3 arguments."));
180
181         Host::Ptr host = Host::GetByName(arguments[0]);
182
183         Service::Ptr hc = host->GetHostCheckService();
184
185         if (!hc->GetEnablePassiveChecks())
186                 BOOST_THROW_EXCEPTION(std::invalid_argument("Got passive check result for host '" + arguments[0] + "' which has passive checks disabled."));
187
188         int exitStatus = Convert::ToDouble(arguments[1]);
189         Dictionary::Ptr result = PluginCheckTask::ParseCheckOutput(arguments[2]);
190         result->Set("state", PluginCheckTask::ExitStatusToState(exitStatus));
191
192         result->Set("schedule_start", time);
193         result->Set("schedule_end", time);
194         result->Set("execution_start", time);
195         result->Set("execution_end", time);
196         result->Set("active", 0);
197
198         Log(LogInformation, "icinga", "Processing passive check result for host '" + arguments[0] + "'");
199         hc->ProcessCheckResult(result);
200
201         {
202                 ObjectLock olock(hc);
203
204                 /* Reschedule the next check. The side effect of this is that for as long
205                  * as we receive passive results for a service we won't execute any
206                  * active checks. */
207                 hc->SetNextCheck(Utility::GetTime() + hc->GetCheckInterval());
208         }
209 }
210
211 void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const std::vector<String>& arguments)
212 {
213         if (arguments.size() < 4)
214                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 4 arguments."));
215
216         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
217
218         if (!service->GetEnablePassiveChecks())
219                 BOOST_THROW_EXCEPTION(std::invalid_argument("Got passive check result for service '" + arguments[1] + "' which has passive checks disabled."));
220
221         int exitStatus = Convert::ToDouble(arguments[2]);
222         Dictionary::Ptr result = PluginCheckTask::ParseCheckOutput(arguments[3]);
223         result->Set("state", PluginCheckTask::ExitStatusToState(exitStatus));
224
225         result->Set("schedule_start", time);
226         result->Set("schedule_end", time);
227         result->Set("execution_start", time);
228         result->Set("execution_end", time);
229         result->Set("active", 0);
230
231         Log(LogInformation, "icinga", "Processing passive check result for service '" + arguments[1] + "'");
232         service->ProcessCheckResult(result);
233
234         {
235                 ObjectLock olock(service);
236
237                 /* Reschedule the next check. The side effect of this is that for as long
238                  * as we receive passive results for a service we won't execute any
239                  * active checks. */
240                 service->SetNextCheck(Utility::GetTime() + service->GetCheckInterval());
241         }
242 }
243
244 void ExternalCommandProcessor::ScheduleHostCheck(double, const std::vector<String>& arguments)
245 {
246         if (arguments.size() < 2)
247                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
248
249         Host::Ptr host = Host::GetByName(arguments[0]);
250
251         Service::Ptr hc = host->GetHostCheckService();
252
253         if (!hc) {
254                 Log(LogInformation, "icinga", "Ignoring request request for host '" +
255                     arguments[0] + "' (does not have a host check)");
256                 return;
257         }
258
259         double planned_check = Convert::ToDouble(arguments[1]);
260
261         if (planned_check > hc->GetNextCheck()) {
262                 Log(LogInformation, "icinga", "Ignoring reschedule request for host '" +
263                     arguments[0] + "' (next check is already sooner than requested check time)");
264                 return;
265         }
266
267         Log(LogInformation, "icinga", "Rescheduling next check for host '" + arguments[0] + "'");
268
269         if (planned_check < Utility::GetTime())
270                 planned_check = Utility::GetTime();
271
272         {
273                 ObjectLock olock(hc);
274
275                 hc->SetNextCheck(planned_check);
276         }
277 }
278
279 void ExternalCommandProcessor::ScheduleForcedHostCheck(double, const std::vector<String>& arguments)
280 {
281         if (arguments.size() < 2)
282                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
283
284         Host::Ptr host = Host::GetByName(arguments[0]);
285
286         Service::Ptr hc = host->GetHostCheckService();
287
288         if (!hc) {
289                 Log(LogInformation, "icinga", "Ignoring request request for host '" +
290                     arguments[0] + "' (does not have a host check)");
291                 return;
292         }
293
294         Log(LogInformation, "icinga", "Rescheduling next check for host '" + arguments[0] + "'");
295
296         {
297                 ObjectLock olock(hc);
298
299                 hc->SetForceNextCheck(true);
300                 hc->SetNextCheck(Convert::ToDouble(arguments[1]));
301         }
302 }
303
304 void ExternalCommandProcessor::ScheduleSvcCheck(double, const std::vector<String>& arguments)
305 {
306         if (arguments.size() < 3)
307                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 3 arguments."));
308
309         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
310
311         double planned_check = Convert::ToDouble(arguments[2]);
312
313         if (planned_check > service->GetNextCheck()) {
314                 Log(LogInformation, "icinga", "Ignoring reschedule request for service '" +
315                     arguments[1] + "' (next check is already sooner than requested check time)");
316                 return;
317         }
318
319         Log(LogInformation, "icinga", "Rescheduling next check for service '" + arguments[1] + "'");
320
321         if (planned_check < Utility::GetTime())
322                 planned_check = Utility::GetTime();
323
324         {
325                 ObjectLock olock(service);
326
327                 service->SetNextCheck(planned_check);
328         }
329 }
330
331 void ExternalCommandProcessor::ScheduleForcedSvcCheck(double, const std::vector<String>& arguments)
332 {
333         if (arguments.size() < 3)
334                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 3 arguments."));
335
336         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
337
338         Log(LogInformation, "icinga", "Rescheduling next check for service '" + arguments[1] + "'");
339
340         {
341                 ObjectLock olock(service);
342
343                 service->SetForceNextCheck(true);
344                 service->SetNextCheck(Convert::ToDouble(arguments[2]));
345         }
346 }
347
348 void ExternalCommandProcessor::EnableHostCheck(double, const std::vector<String>& arguments)
349 {
350         if (arguments.size() < 1)
351                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
352
353         Host::Ptr host = Host::GetByName(arguments[0]);
354
355         Log(LogInformation, "icinga", "Enabling active checks for host '" + arguments[0] + "'");
356         Service::Ptr hc = host->GetHostCheckService();
357
358         if (!hc)
359                 return;
360
361         {
362                 ObjectLock olock(hc);
363
364                 hc->SetEnableActiveChecks(true);
365         }
366 }
367
368 void ExternalCommandProcessor::DisableHostCheck(double, const std::vector<String>& arguments)
369 {
370         if (arguments.size() < 1)
371                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
372
373         Host::Ptr host = Host::GetByName(arguments[0]);
374
375         Log(LogInformation, "icinga", "Disabling active checks for host '" + arguments[0] + "'");
376         Service::Ptr hc = host->GetHostCheckService();
377
378         if (!hc)
379                 return;
380
381         {
382                 ObjectLock olock(hc);
383
384                 hc->SetEnableActiveChecks(false);
385         }
386 }
387
388 void ExternalCommandProcessor::EnableSvcCheck(double, const std::vector<String>& arguments)
389 {
390         if (arguments.size() < 2)
391                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
392
393         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
394
395         Log(LogInformation, "icinga", "Enabling active checks for service '" + arguments[1] + "'");
396
397         {
398                 ObjectLock olock(service);
399
400                 service->SetEnableActiveChecks(true);
401         }
402 }
403
404 void ExternalCommandProcessor::DisableSvcCheck(double, const std::vector<String>& arguments)
405 {
406         if (arguments.size() < 2)
407                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
408
409         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
410
411         Log(LogInformation, "icinga", "Disabling active checks for service '" + arguments[1] + "'");
412
413         {
414                 ObjectLock olock(service);
415
416                 service->SetEnableActiveChecks(false);
417         }
418 }
419
420 void ExternalCommandProcessor::ShutdownProcess(double, const std::vector<String>&)
421 {
422         Log(LogInformation, "icinga", "Shutting down Icinga via external command.");
423         Application::RequestShutdown();
424 }
425
426 void ExternalCommandProcessor::RestartProcess(double, const std::vector<String>&)
427 {
428         Log(LogInformation, "icinga", "Restarting Icinga via external command.");
429         Application::RequestRestart();
430 }
431
432 void ExternalCommandProcessor::ScheduleForcedHostSvcChecks(double, const std::vector<String>& arguments)
433 {
434         if (arguments.size() < 2)
435                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
436
437         double planned_check = Convert::ToDouble(arguments[1]);
438
439         Host::Ptr host = Host::GetByName(arguments[0]);
440
441         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
442                 Log(LogInformation, "icinga", "Rescheduling next check for service '" + service->GetName() + "'");
443
444                 {
445                         ObjectLock olock(service);
446
447                         service->SetNextCheck(planned_check);
448                         service->SetForceNextCheck(true);
449                 }
450         }
451 }
452
453 void ExternalCommandProcessor::ScheduleHostSvcChecks(double, const std::vector<String>& arguments)
454 {
455         if (arguments.size() < 2)
456                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
457
458         double planned_check = Convert::ToDouble(arguments[1]);
459
460         Host::Ptr host = Host::GetByName(arguments[0]);
461
462         if (planned_check < Utility::GetTime())
463                 planned_check = Utility::GetTime();
464
465         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
466                 if (planned_check > service->GetNextCheck()) {
467                         Log(LogInformation, "icinga", "Ignoring reschedule request for service '" +
468                             service->GetName() + "' (next check is already sooner than requested check time)");
469                         continue;
470                 }
471
472                 Log(LogInformation, "icinga", "Rescheduling next check for service '" + service->GetName() + "'");
473
474                 {
475                         ObjectLock olock(service);
476
477                         service->SetNextCheck(planned_check);
478                 }
479         }
480 }
481
482 void ExternalCommandProcessor::EnableHostSvcChecks(double, const std::vector<String>& arguments)
483 {
484         if (arguments.size() < 1)
485                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
486
487         Host::Ptr host = Host::GetByName(arguments[0]);
488
489         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
490                 Log(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
491                 service->SetEnableActiveChecks(true);
492         }
493 }
494
495 void ExternalCommandProcessor::DisableHostSvcChecks(double, const std::vector<String>& arguments)
496 {
497         if (arguments.size() < 1)
498                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
499
500         Host::Ptr host = Host::GetByName(arguments[0]);
501
502         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
503                 Log(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
504
505                 {
506                         ObjectLock olock(service);
507
508                         service->SetEnableActiveChecks(false);
509                 }
510         }
511 }
512
513 void ExternalCommandProcessor::AcknowledgeSvcProblem(double, const std::vector<String>& arguments)
514 {
515         if (arguments.size() < 7)
516                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 7 arguments."));
517
518         bool sticky = Convert::ToBool(arguments[2]);
519
520         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
521
522         if (service->GetState() == StateOK)
523                 BOOST_THROW_EXCEPTION(std::invalid_argument("The service '" + arguments[1] + "' is OK."));
524
525         Log(LogInformation, "icinga", "Setting acknowledgement for service '" + service->GetName() + "'");
526
527         service->AddComment(CommentAcknowledgement, arguments[5], arguments[6], 0);
528         service->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal);
529 }
530
531 void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const std::vector<String>& arguments)
532 {
533         if (arguments.size() < 8)
534                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 8 arguments."));
535
536         bool sticky = Convert::ToBool(arguments[2]);
537         double timestamp = Convert::ToDouble(arguments[5]);
538
539         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
540
541         if (service->GetState() == StateOK)
542                 BOOST_THROW_EXCEPTION(std::invalid_argument("The service '" + arguments[1] + "' is OK."));
543
544         Log(LogInformation, "icinga", "Setting timed acknowledgement for service '" + service->GetName() + "'");
545
546         service->AddComment(CommentAcknowledgement, arguments[6], arguments[7], 0);
547         service->AcknowledgeProblem(arguments[6], arguments[7], sticky ? AcknowledgementSticky : AcknowledgementNormal, timestamp);
548 }
549
550 void ExternalCommandProcessor::RemoveSvcAcknowledgement(double, const std::vector<String>& arguments)
551 {
552         if (arguments.size() < 2)
553                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
554
555         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
556
557         Log(LogInformation, "icinga", "Removing acknowledgement for service '" + service->GetName() + "'");
558
559         service->ClearAcknowledgement();
560 }
561
562 void ExternalCommandProcessor::AcknowledgeHostProblem(double, const std::vector<String>& arguments)
563 {
564         if (arguments.size() < 6)
565                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 6 arguments."));
566
567         bool sticky = Convert::ToBool(arguments[1]);
568
569         Host::Ptr host = Host::GetByName(arguments[0]);
570
571         Log(LogInformation, "icinga", "Setting acknowledgement for host '" + host->GetName() + "'");
572         Service::Ptr service = host->GetHostCheckService();
573         if (service) {
574                 if (service->GetState() == StateOK)
575                         BOOST_THROW_EXCEPTION(std::invalid_argument("The host '" + arguments[0] + "' is OK."));
576
577                 service->AddComment(CommentAcknowledgement, arguments[4], arguments[5], 0);
578                 service->AcknowledgeProblem(arguments[4], arguments[5], sticky ? AcknowledgementSticky : AcknowledgementNormal);
579         }
580 }
581
582 void ExternalCommandProcessor::AcknowledgeHostProblemExpire(double, const std::vector<String>& arguments)
583 {
584         if (arguments.size() < 7)
585                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 7 arguments."));
586
587         bool sticky = Convert::ToBool(arguments[1]);
588         double timestamp = Convert::ToDouble(arguments[4]);
589
590         Host::Ptr host = Host::GetByName(arguments[0]);
591
592         Log(LogInformation, "icinga", "Setting timed acknowledgement for host '" + host->GetName() + "'");
593         Service::Ptr service = host->GetHostCheckService();
594         if (service) {
595                 if (service->GetState() == StateOK)
596                         BOOST_THROW_EXCEPTION(std::invalid_argument("The host '" + arguments[0] + "' is OK."));
597
598                 service->AddComment(CommentAcknowledgement, arguments[5], arguments[6], 0);
599                 service->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, timestamp);
600         }
601 }
602
603 void ExternalCommandProcessor::RemoveHostAcknowledgement(double, const std::vector<String>& arguments)
604 {
605         if (arguments.size() < 1)
606                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
607
608         Host::Ptr host = Host::GetByName(arguments[0]);
609
610         Log(LogInformation, "icinga", "Removing acknowledgement for host '" + host->GetName() + "'");
611         Service::Ptr service = host->GetHostCheckService();
612         if (service)
613                 service->ClearAcknowledgement();
614 }
615
616 void ExternalCommandProcessor::EnableHostgroupSvcChecks(double, const std::vector<String>& arguments)
617 {
618         if (arguments.size() < 1)
619                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
620
621         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
622
623         BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
624                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
625                         Log(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
626
627                         {
628                                 ObjectLock olock(service);
629
630                                 service->SetEnableActiveChecks(true);
631                         }
632                 }
633         }
634 }
635
636 void ExternalCommandProcessor::DisableHostgroupSvcChecks(double, const std::vector<String>& arguments)
637 {
638         if (arguments.size() < 1)
639                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
640
641         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
642
643         BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
644                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
645                         Log(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
646
647                         {
648                                 ObjectLock olock(service);
649
650                                 service->SetEnableActiveChecks(false);
651                         }
652                 }
653         }
654 }
655
656 void ExternalCommandProcessor::EnableServicegroupSvcChecks(double, const std::vector<String>& arguments)
657 {
658         if (arguments.size() < 1)
659                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
660
661         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
662
663         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
664                 Log(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
665
666                 {
667                         ObjectLock olock(service);
668
669                         service->SetEnableActiveChecks(true);
670                 }
671         }
672 }
673
674 void ExternalCommandProcessor::DisableServicegroupSvcChecks(double, const std::vector<String>& arguments)
675 {
676         if (arguments.size() < 1)
677                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
678
679         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
680
681         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
682                 Log(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
683
684                 {
685                         ObjectLock olock(service);
686
687                         service->SetEnableActiveChecks(false);
688                 }
689         }
690 }
691
692 void ExternalCommandProcessor::EnablePassiveHostChecks(double, const std::vector<String>& arguments)
693 {
694         if (arguments.size() < 1)
695                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
696
697         Host::Ptr host = Host::GetByName(arguments[0]);
698
699         Log(LogInformation, "icinga", "Enabling passive checks for host '" + arguments[0] + "'");
700         Service::Ptr hc = host->GetHostCheckService();
701
702         if (!hc)
703                 return;
704
705         {
706                 ObjectLock olock(hc);
707
708                 hc->SetEnablePassiveChecks(true);
709         }
710 }
711
712 void ExternalCommandProcessor::DisablePassiveHostChecks(double, const std::vector<String>& arguments)
713 {
714         if (arguments.size() < 1)
715                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
716
717         Host::Ptr host = Host::GetByName(arguments[0]);
718
719         Log(LogInformation, "icinga", "Disabling passive checks for host '" + arguments[0] + "'");
720         Service::Ptr hc = host->GetHostCheckService();
721
722         if (!hc)
723                 return;
724
725         {
726                 ObjectLock olock(hc);
727
728                 hc->SetEnablePassiveChecks(false);
729         }
730 }
731
732 void ExternalCommandProcessor::EnablePassiveSvcChecks(double, const std::vector<String>& arguments)
733 {
734         if (arguments.size() < 2)
735                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
736
737         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
738
739         Log(LogInformation, "icinga", "Enabling passive checks for service '" + arguments[1] + "'");
740
741         {
742                 ObjectLock olock(service);
743
744                 service->SetEnablePassiveChecks(true);
745         }
746 }
747
748 void ExternalCommandProcessor::DisablePassiveSvcChecks(double, const std::vector<String>& arguments)
749 {
750         if (arguments.size() < 2)
751                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
752
753         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
754
755         Log(LogInformation, "icinga", "Disabling passive checks for service '" + arguments[1] + "'");
756
757         {
758                 ObjectLock olock(service);
759
760                 service->SetEnablePassiveChecks(false);
761         }
762 }
763
764 void ExternalCommandProcessor::EnableServicegroupPassiveSvcChecks(double, const std::vector<String>& arguments)
765 {
766         if (arguments.size() < 1)
767                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
768
769         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
770
771         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
772                 Log(LogInformation, "icinga", "Enabling passive checks for service '" + service->GetName() + "'");
773
774                 {
775                         ObjectLock olock(service);
776
777                         service->SetEnablePassiveChecks(true);
778                 }
779         }
780 }
781
782 void ExternalCommandProcessor::DisableServicegroupPassiveSvcChecks(double, const std::vector<String>& arguments)
783 {
784         if (arguments.size() < 1)
785                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
786
787         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
788
789         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
790                 Log(LogInformation, "icinga", "Disabling passive checks for service '" + service->GetName() + "'");
791
792                 {
793                         ObjectLock olock(service);
794
795                         service->SetEnablePassiveChecks(true);
796                 }
797         }
798 }
799
800 void ExternalCommandProcessor::EnableHostgroupPassiveSvcChecks(double, const std::vector<String>& arguments)
801 {
802         if (arguments.size() < 1)
803                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
804
805         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
806
807         BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
808                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
809                         Log(LogInformation, "icinga", "Enabling passive checks for service '" + service->GetName() + "'");
810
811                         {
812                                 ObjectLock olock(service);
813
814                                 service->SetEnablePassiveChecks(true);
815                         }
816                 }
817         }
818 }
819
820 void ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks(double, const std::vector<String>& arguments)
821 {
822         if (arguments.size() < 1)
823                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
824
825         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
826
827         BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
828                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
829                         Log(LogInformation, "icinga", "Disabling passive checks for service '" + service->GetName() + "'");
830
831                         {
832                                 ObjectLock olock(service);
833
834                                 service->SetEnablePassiveChecks(false);
835                         }
836                 }
837         }
838 }
839
840 void ExternalCommandProcessor::ProcessFile(double, const std::vector<String>& arguments)
841 {
842         if (arguments.size() < 2)
843                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
844
845         String file = arguments[0];
846         bool del = Convert::ToBool(arguments[1]);
847
848         std::ifstream ifp;
849         ifp.exceptions(std::ifstream::badbit);
850
851         ifp.open(file.CStr(), std::ifstream::in);
852
853         while(ifp.good()) {
854                 std::string line;
855                 std::getline(ifp, line);
856
857                 try {
858                         Log(LogInformation, "compat", "Executing external command: " + line);
859
860                         Execute(line);
861                 } catch (const std::exception& ex) {
862                         std::ostringstream msgbuf;
863                         msgbuf << "External command failed: " << boost::diagnostic_information(ex);
864                         Log(LogWarning, "icinga", msgbuf.str());
865                 }
866         }
867
868         ifp.close();
869
870         if (del)
871                 (void) unlink(file.CStr());
872 }
873
874 void ExternalCommandProcessor::ScheduleSvcDowntime(double, const std::vector<String>& arguments)
875 {
876         if (arguments.size() < 9)
877                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 9 arguments."));
878
879         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
880
881         String triggeredBy;
882         int triggeredByLegacy = Convert::ToLong(arguments[5]);
883         if (triggeredByLegacy != 0)
884                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
885
886         Log(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
887         String comment_id = service->AddComment(CommentDowntime, arguments[7], arguments[8], Convert::ToDouble(arguments[3]));
888         (void) service->AddDowntime(comment_id,
889             Convert::ToDouble(arguments[2]), Convert::ToDouble(arguments[3]),
890             Convert::ToBool(arguments[4]), triggeredBy, Convert::ToDouble(arguments[6]));
891 }
892
893 void ExternalCommandProcessor::DelSvcDowntime(double, const std::vector<String>& arguments)
894 {
895         if (arguments.size() < 1)
896                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
897
898         int id = Convert::ToLong(arguments[0]);
899         Log(LogInformation, "icinga", "Removing downtime ID " + arguments[0]);
900         String rid = Service::GetDowntimeIDFromLegacyID(id);
901         Service::RemoveDowntime(rid);
902 }
903
904 void ExternalCommandProcessor::ScheduleHostDowntime(double, const std::vector<String>& arguments)
905 {
906         if (arguments.size() < 8)
907                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 8 arguments."));
908
909         Host::Ptr host = Host::GetByName(arguments[0]);
910
911         String triggeredBy;
912         int triggeredByLegacy = Convert::ToLong(arguments[4]);
913         if (triggeredByLegacy != 0)
914                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
915
916         Log(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
917         Service::Ptr service = host->GetHostCheckService();
918         if (service) {
919                 String comment_id = service->AddComment(CommentDowntime, arguments[6], arguments[7], Convert::ToDouble(arguments[2]));
920                 (void) service->AddDowntime(comment_id,
921                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
922                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
923         }
924 }
925
926 void ExternalCommandProcessor::DelHostDowntime(double, const std::vector<String>& arguments)
927 {
928         if (arguments.size() < 1)
929                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
930
931         int id = Convert::ToLong(arguments[0]);
932         Log(LogInformation, "icinga", "Removing downtime ID " + arguments[0]);
933         String rid = Service::GetDowntimeIDFromLegacyID(id);
934         Service::RemoveDowntime(rid);
935 }
936
937 void ExternalCommandProcessor::ScheduleHostSvcDowntime(double, const std::vector<String>& arguments)
938 {
939         if (arguments.size() < 8)
940                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 8 argument."));
941
942         Host::Ptr host = Host::GetByName(arguments[0]);
943
944         String triggeredBy;
945         int triggeredByLegacy = Convert::ToLong(arguments[4]);
946         if (triggeredByLegacy != 0)
947                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
948
949         BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
950                 Log(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
951                 String comment_id = service->AddComment(CommentDowntime, arguments[6], arguments[7], Convert::ToDouble(arguments[2]));
952                 (void) service->AddDowntime(comment_id,
953                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
954                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
955         }
956 }
957
958 void ExternalCommandProcessor::ScheduleHostgroupHostDowntime(double, const std::vector<String>& arguments)
959 {
960         if (arguments.size() < 8)
961                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 8 arguments."));
962
963         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
964
965         String triggeredBy;
966         int triggeredByLegacy = Convert::ToLong(arguments[4]);
967         if (triggeredByLegacy != 0)
968                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
969
970         BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
971                 Log(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
972                 Service::Ptr service = host->GetHostCheckService();
973                 if (service) {
974                         String comment_id = service->AddComment(CommentDowntime, arguments[6], arguments[7], Convert::ToDouble(arguments[2]));
975                         (void) service->AddDowntime(comment_id,
976                             Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
977                             Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
978                 }
979         }
980 }
981
982 void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const std::vector<String>& arguments)
983 {
984         if (arguments.size() < 8)
985                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 8 arguments."));
986
987         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
988
989         String triggeredBy;
990         int triggeredByLegacy = Convert::ToLong(arguments[4]);
991         if (triggeredByLegacy != 0)
992                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
993
994         /* Note: we can't just directly create downtimes for all the services by iterating
995          * over all hosts in the host group - otherwise we might end up creating multiple
996          * downtimes for some services. */
997
998         std::set<Service::Ptr> services;
999
1000         BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
1001                 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
1002                         services.insert(service);
1003                 }
1004         }
1005
1006         BOOST_FOREACH(const Service::Ptr& service, services) {
1007                 Log(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
1008                 String comment_id = service->AddComment(CommentDowntime, arguments[6], arguments[7], Convert::ToDouble(arguments[2]));
1009                 (void) service->AddDowntime(comment_id,
1010                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1011                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
1012         }
1013 }
1014
1015 void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const std::vector<String>& arguments)
1016 {
1017         if (arguments.size() < 8)
1018                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 8 arguments."));
1019
1020         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1021
1022         String triggeredBy;
1023         int triggeredByLegacy = Convert::ToLong(arguments[4]);
1024         if (triggeredByLegacy != 0)
1025                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
1026
1027         /* Note: we can't just directly create downtimes for all the hosts by iterating
1028          * over all services in the service group - otherwise we might end up creating multiple
1029          * downtimes for some hosts. */
1030
1031         std::set<Service::Ptr> services;
1032
1033         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
1034                 Host::Ptr host = service->GetHost();
1035                 Service::Ptr hcService = host->GetHostCheckService();
1036                 if (hcService)
1037                         services.insert(hcService);
1038         }
1039
1040         BOOST_FOREACH(const Service::Ptr& service, services) {
1041                 Log(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
1042                 String comment_id = service->AddComment(CommentDowntime, arguments[6], arguments[7], Convert::ToDouble(arguments[2]));
1043                 (void) service->AddDowntime(comment_id,
1044                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1045                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
1046         }
1047 }
1048
1049 void ExternalCommandProcessor::ScheduleServicegroupSvcDowntime(double, const std::vector<String>& arguments)
1050 {
1051         if (arguments.size() < 8)
1052                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 8 arguments."));
1053
1054         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1055
1056         String triggeredBy;
1057         int triggeredByLegacy = Convert::ToLong(arguments[4]);
1058         if (triggeredByLegacy != 0)
1059                 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
1060
1061         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
1062                 Log(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
1063                 String comment_id = service->AddComment(CommentDowntime, arguments[6], arguments[7], Convert::ToDouble(arguments[2]));
1064                 (void) service->AddDowntime(comment_id,
1065                     Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
1066                     Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
1067         }
1068 }
1069
1070 void ExternalCommandProcessor::AddHostComment(double, const std::vector<String>& arguments)
1071 {
1072         if (arguments.size() < 4)
1073                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 4 arguments."));
1074
1075         Host::Ptr host = Host::GetByName(arguments[0]);
1076
1077         Log(LogInformation, "icinga", "Creating comment for host " + host->GetName());
1078         Service::Ptr service = host->GetHostCheckService();
1079         if (service)
1080                 (void) service->AddComment(CommentUser, arguments[2], arguments[3], 0);
1081 }
1082
1083 void ExternalCommandProcessor::DelHostComment(double, const std::vector<String>& arguments)
1084 {
1085         if (arguments.size() < 1)
1086                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
1087
1088         int id = Convert::ToLong(arguments[0]);
1089         Log(LogInformation, "icinga", "Removing comment ID " + arguments[0]);
1090         String rid = Service::GetCommentIDFromLegacyID(id);
1091         Service::RemoveComment(rid);
1092 }
1093
1094 void ExternalCommandProcessor::AddSvcComment(double, const std::vector<String>& arguments)
1095 {
1096         if (arguments.size() < 5)
1097                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 5 arguments."));
1098
1099         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1100
1101         Log(LogInformation, "icinga", "Creating comment for service " + service->GetName());
1102         (void) service->AddComment(CommentUser, arguments[3], arguments[4], 0);
1103 }
1104
1105 void ExternalCommandProcessor::DelSvcComment(double, const std::vector<String>& arguments)
1106 {
1107         if (arguments.size() < 1)
1108                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
1109
1110         int id = Convert::ToLong(arguments[0]);
1111         Log(LogInformation, "icinga", "Removing comment ID " + arguments[0]);
1112
1113         String rid = Service::GetCommentIDFromLegacyID(id);
1114         Service::RemoveComment(rid);
1115 }
1116
1117 void ExternalCommandProcessor::DelAllHostComments(double, const std::vector<String>& arguments)
1118 {
1119         if (arguments.size() < 1)
1120                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
1121
1122         Host::Ptr host = Host::GetByName(arguments[0]);
1123
1124         Log(LogInformation, "icinga", "Removing all comments for host " + host->GetName());
1125         Service::Ptr service = host->GetHostCheckService();
1126         if (service)
1127                 service->RemoveAllComments();
1128 }
1129
1130 void ExternalCommandProcessor::DelAllSvcComments(double, const std::vector<String>& arguments)
1131 {
1132         if (arguments.size() < 2)
1133                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
1134
1135         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1136
1137         Log(LogInformation, "icinga", "Removing all comments for service " + service->GetName());
1138         service->RemoveAllComments();
1139 }
1140
1141 void ExternalCommandProcessor::SendCustomHostNotification(double, const std::vector<String>& arguments)
1142 {
1143         if (arguments.size() < 4)
1144                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 4 arguments."));
1145
1146         Host::Ptr host = Host::GetByName(arguments[0]);
1147         int options = Convert::ToLong(arguments[1]);
1148
1149         Log(LogInformation, "icinga", "Sending custom notification for host " + host->GetName());
1150         Service::Ptr service = host->GetHostCheckService();
1151         if (service) {
1152                 if (options & 2) {
1153                         ObjectLock olock(service);
1154                         service->SetForceNextNotification(true);
1155                 }
1156
1157                 Service::OnNotificationsRequested(service, NotificationCustom, service->GetLastCheckResult(), arguments[2], arguments[3]);
1158         }
1159 }
1160
1161 void ExternalCommandProcessor::SendCustomSvcNotification(double, const std::vector<String>& arguments)
1162 {
1163         if (arguments.size() < 5)
1164                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 5 arguments."));
1165
1166         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1167         int options = Convert::ToLong(arguments[2]);
1168
1169         Log(LogInformation, "icinga", "Sending custom notification for service " + service->GetName());
1170
1171         if (options & 2) {
1172                 ObjectLock olock(service);
1173                 service->SetForceNextNotification(true);
1174         }
1175
1176         Service::OnNotificationsRequested(service, NotificationCustom, service->GetLastCheckResult(), arguments[3], arguments[4]);
1177 }
1178
1179 void ExternalCommandProcessor::DelayHostNotification(double, const std::vector<String>& arguments)
1180 {
1181         if (arguments.size() < 2)
1182                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
1183
1184         Host::Ptr host = Host::GetByName(arguments[0]);
1185
1186         Log(LogInformation, "icinga", "Delaying notifications for host " + host->GetName());
1187         Service::Ptr hc = host->GetHostCheckService();
1188         if (!hc)
1189                 return;
1190
1191         BOOST_FOREACH(const Notification::Ptr& notification, hc->GetNotifications()) {
1192                 ObjectLock olock(notification);
1193
1194                 notification->SetNextNotification(Convert::ToDouble(arguments[1]));
1195         }
1196 }
1197
1198 void ExternalCommandProcessor::DelaySvcNotification(double, const std::vector<String>& arguments)
1199 {
1200         if (arguments.size() < 3)
1201                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 3 arguments."));
1202
1203         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1204
1205         Log(LogInformation, "icinga", "Delaying notifications for service " + service->GetName());
1206
1207         BOOST_FOREACH(const Notification::Ptr& notification, service->GetNotifications()) {
1208                 ObjectLock olock(notification);
1209
1210                 notification->SetNextNotification(Convert::ToDouble(arguments[2]));
1211         }
1212 }
1213
1214 void ExternalCommandProcessor::EnableHostNotifications(double, const std::vector<String>& arguments)
1215 {
1216         if (arguments.size() < 1)
1217                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
1218
1219         Host::Ptr host = Host::GetByName(arguments[0]);
1220
1221         Log(LogInformation, "icinga", "Enabling notifications for host '" + arguments[0] + "'");
1222         Service::Ptr hc = host->GetHostCheckService();
1223
1224         if (!hc)
1225                 return;
1226
1227         {
1228                 ObjectLock olock(hc);
1229
1230                 hc->SetEnableNotifications(true);
1231         }
1232 }
1233
1234 void ExternalCommandProcessor::DisableHostNotifications(double, const std::vector<String>& arguments)
1235 {
1236         if (arguments.size() < 1)
1237                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
1238
1239         Host::Ptr host = Host::GetByName(arguments[0]);
1240
1241         Log(LogInformation, "icinga", "Disabling notifications for host '" + arguments[0] + "'");
1242         Service::Ptr hc = host->GetHostCheckService();
1243
1244         if (!hc)
1245                 return;
1246
1247         {
1248                 ObjectLock olock(hc);
1249
1250                 hc->SetEnableNotifications(false);
1251         }
1252 }
1253
1254 void ExternalCommandProcessor::EnableSvcNotifications(double, const std::vector<String>& arguments)
1255 {
1256         if (arguments.size() < 2)
1257                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
1258
1259         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1260
1261         Log(LogInformation, "icinga", "Enabling notifications for service '" + arguments[1] + "'");
1262
1263         {
1264                 ObjectLock olock(service);
1265
1266                 service->SetEnableNotifications(true);
1267         }
1268 }
1269
1270 void ExternalCommandProcessor::DisableSvcNotifications(double, const std::vector<String>& arguments)
1271 {
1272         if (arguments.size() < 2)
1273                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
1274
1275         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1276
1277         Log(LogInformation, "icinga", "Disabling notifications for service '" + arguments[1] + "'");
1278
1279         {
1280                 ObjectLock olock(service);
1281
1282                 service->SetEnableNotifications(false);
1283         }
1284 }
1285
1286 void ExternalCommandProcessor::DisableHostgroupHostChecks(double, const std::vector<String>& arguments)
1287 {
1288         if (arguments.size() < 1)
1289                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
1290
1291         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
1292
1293         BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
1294                 Service::Ptr hc = host->GetHostCheckService();
1295
1296                 if (!hc)
1297                         continue;
1298
1299                 Log(LogInformation, "icinga", "Disabling active checks for host '" + host->GetName() + "'");
1300
1301                 {
1302                         ObjectLock olock(hc);
1303
1304                         hc->SetEnableActiveChecks(false);
1305                 }
1306         }
1307 }
1308
1309 void ExternalCommandProcessor::DisableHostgroupPassiveHostChecks(double, const std::vector<String>& arguments)
1310 {
1311         if (arguments.size() < 1)
1312                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
1313
1314         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
1315
1316         BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
1317                 Service::Ptr hc = host->GetHostCheckService();
1318
1319                 if (!hc)
1320                         continue;
1321
1322                 Log(LogInformation, "icinga", "Disabling active checks for host '" + host->GetName() + "'");
1323
1324                 {
1325                         ObjectLock olock(hc);
1326
1327                         hc->SetEnablePassiveChecks(false);
1328                 }
1329         }
1330 }
1331
1332 void ExternalCommandProcessor::DisableServicegroupHostChecks(double, const std::vector<String>& arguments)
1333 {
1334         if (arguments.size() < 1)
1335                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
1336
1337         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1338
1339         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
1340                 Host::Ptr host = service->GetHost();
1341
1342                 if (!host)
1343                         continue;
1344
1345                 Service::Ptr hc = host->GetHostCheckService();
1346
1347                 if (!hc)
1348                         continue;
1349
1350                 Log(LogInformation, "icinga", "Disabling active checks for host '" + host->GetName() + "'");
1351
1352                 {
1353                         ObjectLock olock(hc);
1354
1355                         hc->SetEnableActiveChecks(false);
1356                 }
1357         }
1358 }
1359
1360 void ExternalCommandProcessor::DisableServicegroupPassiveHostChecks(double, const std::vector<String>& arguments)
1361 {
1362         if (arguments.size() < 1)
1363                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
1364
1365         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1366
1367         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
1368                 Host::Ptr host = service->GetHost();
1369
1370                 if (!host)
1371                         continue;
1372
1373                 Service::Ptr hc = host->GetHostCheckService();
1374
1375                 if (!hc)
1376                         continue;
1377
1378                 Log(LogInformation, "icinga", "Disabling active checks for host '" + host->GetName() + "'");
1379
1380                 {
1381                         ObjectLock olock(hc);
1382
1383                         hc->SetEnablePassiveChecks(false);
1384                 }
1385         }
1386 }
1387
1388 void ExternalCommandProcessor::EnableHostgroupHostChecks(double, const std::vector<String>& arguments)
1389 {
1390         if (arguments.size() < 1)
1391                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
1392
1393         HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
1394
1395         BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
1396                 Service::Ptr hc = host->GetHostCheckService();
1397
1398                 if (!hc)
1399                         continue;
1400
1401                 Log(LogInformation, "icinga", "Enabling active checks for host '" + host->GetName() + "'");
1402
1403                 {
1404                         ObjectLock olock(hc);
1405
1406                         hc->SetEnableActiveChecks(true);
1407                 }
1408         }
1409 }
1410
1411 void ExternalCommandProcessor::EnableHostgroupPassiveHostChecks(double, const std::vector<String>& arguments)
1412 {
1413         if (arguments.size() < 1)
1414                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
1415
1416 }
1417
1418 void ExternalCommandProcessor::EnableServicegroupHostChecks(double, const std::vector<String>& arguments)
1419 {
1420         if (arguments.size() < 1)
1421                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
1422
1423         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1424
1425         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
1426                 Host::Ptr host = service->GetHost();
1427
1428                 if (!host)
1429                         continue;
1430
1431                 Service::Ptr hc = host->GetHostCheckService();
1432
1433                 if (!hc)
1434                         continue;
1435
1436                 Log(LogInformation, "icinga", "Enabling active checks for host '" + host->GetName() + "'");
1437
1438                 {
1439                         ObjectLock olock(hc);
1440
1441                         hc->SetEnableActiveChecks(true);
1442                 }
1443         }
1444 }
1445
1446 void ExternalCommandProcessor::EnableServicegroupPassiveHostChecks(double, const std::vector<String>& arguments)
1447 {
1448         if (arguments.size() < 1)
1449                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 arguments."));
1450
1451         ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
1452
1453         BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
1454                 Host::Ptr host = service->GetHost();
1455
1456                 if (!host)
1457                         continue;
1458
1459                 Service::Ptr hc = host->GetHostCheckService();
1460
1461                 if (!hc)
1462                         continue;
1463
1464                 Log(LogInformation, "icinga", "Enabling active checks for host '" + host->GetName() + "'");
1465
1466                 {
1467                         ObjectLock olock(hc);
1468
1469                         hc->SetEnablePassiveChecks(false);
1470                 }
1471         }
1472 }
1473
1474 void ExternalCommandProcessor::EnableHostFlapping(double, const std::vector<String>& arguments)
1475 {
1476         if (arguments.size() < 1)
1477                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
1478
1479         Host::Ptr host = Host::GetByName(arguments[0]);
1480
1481         Log(LogInformation, "icinga", "Enabling flapping detection for host '" + arguments[0] + "'");
1482         Service::Ptr hc = host->GetHostCheckService();
1483
1484         if (!hc)
1485                 return;
1486
1487         {
1488                 ObjectLock olock(hc);
1489
1490                 hc->SetEnableFlapping(true);
1491         }
1492 }
1493
1494 void ExternalCommandProcessor::DisableHostFlapping(double, const std::vector<String>& arguments)
1495 {
1496         if (arguments.size() < 1)
1497                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument."));
1498
1499         Host::Ptr host = Host::GetByName(arguments[0]);
1500
1501         Log(LogInformation, "icinga", "Disabling flapping detection for host '" + arguments[0] + "'");
1502         Service::Ptr hc = host->GetHostCheckService();
1503
1504         if (!hc)
1505                 return;
1506
1507         {
1508                 ObjectLock olock(hc);
1509
1510                 hc->SetEnableFlapping(false);
1511         }
1512 }
1513
1514 void ExternalCommandProcessor::EnableSvcFlapping(double, const std::vector<String>& arguments)
1515 {
1516         if (arguments.size() < 2)
1517                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
1518
1519         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1520
1521         Log(LogInformation, "icinga", "Enabling flapping detection for service '" + arguments[1] + "'");
1522
1523         {
1524                 ObjectLock olock(service);
1525
1526                 service->SetEnableFlapping(true);
1527         }
1528 }
1529
1530 void ExternalCommandProcessor::DisableSvcFlapping(double, const std::vector<String>& arguments)
1531 {
1532         if (arguments.size() < 2)
1533                 BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments."));
1534
1535         Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1536
1537         Log(LogInformation, "icinga", "Disabling flapping detection for service '" + arguments[1] + "'");
1538
1539         {
1540                 ObjectLock olock(service);
1541
1542                 service->SetEnableFlapping(false);
1543         }
1544 }