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