1 /******************************************************************************
3 * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
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. *
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. *
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 ******************************************************************************/
20 #include "i2-icinga.h"
22 using namespace icinga;
24 boost::once_flag ExternalCommandProcessor::m_InitializeOnce = BOOST_ONCE_INIT;
25 boost::mutex ExternalCommandProcessor::m_Mutex;
26 map<String, ExternalCommandProcessor::Callback> ExternalCommandProcessor::m_Commands;
29 * @threadsafety Always.
31 void ExternalCommandProcessor::Execute(const String& line)
37 BOOST_THROW_EXCEPTION(invalid_argument("Missing timestamp in command: " + line));
39 size_t pos = line.FindFirstOf("]");
41 if (pos == String::NPos)
42 BOOST_THROW_EXCEPTION(invalid_argument("Missing timestamp in command: " + line));
44 String timestamp = line.SubStr(1, pos - 1);
45 String args = line.SubStr(pos + 2, String::NPos);
47 double ts = Convert::ToDouble(timestamp);
50 BOOST_THROW_EXCEPTION(invalid_argument("Invalid timestamp in command: " + line));
52 vector<String> argv = args.Split(is_any_of(";"));
55 BOOST_THROW_EXCEPTION(invalid_argument("Missing arguments in command: " + line));
57 vector<String> argvExtra(argv.begin() + 1, argv.end());
58 Execute(ts, argv[0], argvExtra);
62 * @threadsafety Always.
64 void ExternalCommandProcessor::Execute(double time, const String& command, const vector<String>& arguments)
66 boost::call_once(m_InitializeOnce, &ExternalCommandProcessor::Initialize);
71 boost::mutex::scoped_lock lock(m_Mutex);
73 map<String, ExternalCommandProcessor::Callback>::iterator it;
74 it = m_Commands.find(command);
76 if (it == m_Commands.end())
77 BOOST_THROW_EXCEPTION(invalid_argument("The external command '" + command + "' does not exist."));
79 callback = it->second;
82 callback(time, arguments);
86 * @threadsafety Always.
88 void ExternalCommandProcessor::Initialize(void)
90 RegisterCommand("PROCESS_HOST_CHECK_RESULT", &ExternalCommandProcessor::ProcessServiceCheckResult);
91 RegisterCommand("PROCESS_SERVICE_CHECK_RESULT", &ExternalCommandProcessor::ProcessServiceCheckResult);
92 RegisterCommand("SCHEDULE_HOST_CHECK", &ExternalCommandProcessor::ScheduleHostCheck);
93 RegisterCommand("SCHEDULE_FORCED_HOST_CHECK", &ExternalCommandProcessor::ScheduleForcedHostCheck);
94 RegisterCommand("SCHEDULE_SVC_CHECK", &ExternalCommandProcessor::ScheduleSvcCheck);
95 RegisterCommand("SCHEDULE_FORCED_SVC_CHECK", &ExternalCommandProcessor::ScheduleForcedSvcCheck);
96 RegisterCommand("ENABLE_HOST_CHECK", &ExternalCommandProcessor::EnableHostCheck);
97 RegisterCommand("DISABLE_HOST_CHECK", &ExternalCommandProcessor::DisableHostCheck);
98 RegisterCommand("ENABLE_SVC_CHECK", &ExternalCommandProcessor::EnableSvcCheck);
99 RegisterCommand("DISABLE_SVC_CHECK", &ExternalCommandProcessor::DisableSvcCheck);
100 RegisterCommand("SHUTDOWN_PROCESS", &ExternalCommandProcessor::ShutdownProcess);
101 RegisterCommand("SCHEDULE_FORCED_HOST_SVC_CHECKS", &ExternalCommandProcessor::ScheduleForcedHostSvcChecks);
102 RegisterCommand("SCHEDULE_HOST_SVC_CHECKS", &ExternalCommandProcessor::ScheduleHostSvcChecks);
103 RegisterCommand("ENABLE_HOST_SVC_CHECKS", &ExternalCommandProcessor::EnableHostSvcChecks);
104 RegisterCommand("DISABLE_HOST_SVC_CHECKS", &ExternalCommandProcessor::DisableHostSvcChecks);
105 RegisterCommand("ACKNOWLEDGE_SVC_PROBLEM", &ExternalCommandProcessor::AcknowledgeSvcProblem);
106 RegisterCommand("ACKNOWLEDGE_SVC_PROBLEM_EXPIRE", &ExternalCommandProcessor::AcknowledgeSvcProblemExpire);
107 RegisterCommand("REMOVE_SVC_ACKNOWLEDGEMENT", &ExternalCommandProcessor::RemoveHostAcknowledgement);
108 RegisterCommand("ACKNOWLEDGE_HOST_PROBLEM", &ExternalCommandProcessor::AcknowledgeHostProblem);
109 RegisterCommand("ACKNOWLEDGE_HOST_PROBLEM_EXPIRE", &ExternalCommandProcessor::AcknowledgeHostProblemExpire);
110 RegisterCommand("REMOVE_HOST_ACKNOWLEDGEMENT", &ExternalCommandProcessor::RemoveHostAcknowledgement);
111 RegisterCommand("ENABLE_HOSTGROUP_SVC_CHECKS", &ExternalCommandProcessor::EnableHostgroupSvcChecks);
112 RegisterCommand("DISABLE_HOSTGROUP_SVC_CHECKS", &ExternalCommandProcessor::DisableHostgroupSvcChecks);
113 RegisterCommand("ENABLE_SERVICEGROUP_SVC_CHECKS", &ExternalCommandProcessor::EnableServicegroupSvcChecks);
114 RegisterCommand("DISABLE_SERVICEGROUP_SVC_CHECKS", &ExternalCommandProcessor::DisableServicegroupSvcChecks);
115 RegisterCommand("ENABLE_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::EnablePassiveHostChecks);
116 RegisterCommand("DISABLE_PASSIVE_HOST_CHECKS", &ExternalCommandProcessor::DisablePassiveHostChecks);
117 RegisterCommand("ENABLE_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnablePassiveSvcChecks);
118 RegisterCommand("DISABLE_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisablePassiveSvcChecks);
119 RegisterCommand("ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnableServicegroupPassiveSvcChecks);
120 RegisterCommand("DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisableServicegroupPassiveSvcChecks);
121 RegisterCommand("ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::EnableHostgroupPassiveSvcChecks);
122 RegisterCommand("DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks);
123 RegisterCommand("PROCESS_FILE", &ExternalCommandProcessor::ProcessFile);
124 RegisterCommand("SCHEDULE_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleSvcDowntime);
125 RegisterCommand("DEL_SVC_DOWNTIME", &ExternalCommandProcessor::DelSvcDowntime);
126 RegisterCommand("SCHEDULE_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleHostDowntime);
127 RegisterCommand("DEL_HOST_DOWNTIME", &ExternalCommandProcessor::DelHostDowntime);
128 RegisterCommand("SCHEDULE_HOST_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleHostSvcDowntime);
129 RegisterCommand("SCHEDULE_HOSTGROUP_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleHostgroupHostDowntime);
130 RegisterCommand("SCHEDULE_HOSTGROUP_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleHostgroupSvcDowntime);
131 RegisterCommand("SCHEDULE_SERVICEGROUP_HOST_DOWNTIME", &ExternalCommandProcessor::ScheduleServicegroupHostDowntime);
132 RegisterCommand("SCHEDULE_SERVICEGROUP_SVC_DOWNTIME", &ExternalCommandProcessor::ScheduleServicegroupSvcDowntime);
133 RegisterCommand("ADD_HOST_COMMENT", &ExternalCommandProcessor::AddHostComment);
134 RegisterCommand("DEL_HOST_COMMENT", &ExternalCommandProcessor::DelHostComment);
135 RegisterCommand("ADD_SVC_COMMENT", &ExternalCommandProcessor::AddSvcComment);
136 RegisterCommand("DEL_SVC_COMMENT", &ExternalCommandProcessor::DelSvcComment);
137 RegisterCommand("DEL_ALL_HOST_COMMENTS", &ExternalCommandProcessor::DelAllHostComments);
138 RegisterCommand("DEL_ALL_SVC_COMMENTS", &ExternalCommandProcessor::DelAllSvcComments);
139 RegisterCommand("SEND_CUSTOM_HOST_NOTIFICATION", &ExternalCommandProcessor::SendCustomHostNotification);
140 RegisterCommand("SEND_CUSTOM_SVC_NOTIFICATION", &ExternalCommandProcessor::SendCustomSvcNotification);
141 RegisterCommand("DELAY_HOST_NOTIFICATION", &ExternalCommandProcessor::DelayHostNotification);
142 RegisterCommand("DELAY_SVC_NOTIFICATION", &ExternalCommandProcessor::DelaySvcNotification);
143 RegisterCommand("ENABLE_HOST_NOTIFICATIONS", &ExternalCommandProcessor::EnableHostNotifications);
144 RegisterCommand("DISABLE_HOST_NOTIFICATIONS", &ExternalCommandProcessor::DisableHostNotifications);
145 RegisterCommand("ENABLE_SVC_NOTIFICATIONS", &ExternalCommandProcessor::EnableSvcNotifications);
146 RegisterCommand("DISABLE_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableSvcNotifications);
150 * @threadsafety Always.
152 void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandProcessor::Callback& callback)
154 boost::mutex::scoped_lock lock(m_Mutex);
155 m_Commands[command] = callback;
158 void ExternalCommandProcessor::ProcessHostCheckResult(double time, const vector<String>& arguments)
160 if (arguments.size() < 3)
161 BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
163 Host::Ptr host = Host::GetByName(arguments[0]);
165 Service::Ptr hc = host->GetHostCheckService();
167 if (!hc->GetEnablePassiveChecks())
168 BOOST_THROW_EXCEPTION(invalid_argument("Got passive check result for host '" + arguments[0] + "' which has passive checks disabled."));
170 int exitStatus = Convert::ToDouble(arguments[2]);
171 Dictionary::Ptr result = PluginCheckTask::ParseCheckOutput(arguments[3]);
172 result->Set("state", PluginCheckTask::ExitStatusToState(exitStatus));
174 result->Set("schedule_start", time);
175 result->Set("schedule_end", time);
176 result->Set("execution_start", time);
177 result->Set("execution_end", time);
178 result->Set("active", 0);
180 Logger::Write(LogInformation, "icinga", "Processing passive check result for host '" + arguments[0] + "'");
181 hc->ProcessCheckResult(result);
183 /* Reschedule the next check. The side effect of this is that for as long
184 * as we receive passive results for a service we won't execute any
186 hc->SetNextCheck(Utility::GetTime() + hc->GetCheckInterval());
189 void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const vector<String>& arguments)
191 if (arguments.size() < 4)
192 BOOST_THROW_EXCEPTION(invalid_argument("Expected 4 arguments."));
194 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
196 if (!service->GetEnablePassiveChecks())
197 BOOST_THROW_EXCEPTION(invalid_argument("Got passive check result for service '" + arguments[1] + "' which has passive checks disabled."));
199 int exitStatus = Convert::ToDouble(arguments[2]);
200 Dictionary::Ptr result = PluginCheckTask::ParseCheckOutput(arguments[3]);
201 result->Set("state", PluginCheckTask::ExitStatusToState(exitStatus));
203 result->Set("schedule_start", time);
204 result->Set("schedule_end", time);
205 result->Set("execution_start", time);
206 result->Set("execution_end", time);
207 result->Set("active", 0);
209 Logger::Write(LogInformation, "icinga", "Processing passive check result for service '" + arguments[1] + "'");
210 service->ProcessCheckResult(result);
212 /* Reschedule the next check. The side effect of this is that for as long
213 * as we receive passive results for a service we won't execute any
215 service->SetNextCheck(Utility::GetTime() + service->GetCheckInterval());
218 void ExternalCommandProcessor::ScheduleHostCheck(double, const vector<String>& arguments)
220 if (arguments.size() < 2)
221 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
223 Host::Ptr host = Host::GetByName(arguments[0]);
225 Service::Ptr hc = host->GetHostCheckService();
227 double planned_check = Convert::ToDouble(arguments[1]);
229 if (planned_check > hc->GetNextCheck()) {
230 Logger::Write(LogInformation, "icinga", "Ignoring reschedule request for host '" +
231 arguments[0] + "' (next check is already sooner than requested check time)");
235 Logger::Write(LogInformation, "icinga", "Rescheduling next check for host '" + arguments[0] + "'");
236 hc->SetNextCheck(planned_check);
239 void ExternalCommandProcessor::ScheduleForcedHostCheck(double, const vector<String>& arguments)
241 if (arguments.size() < 2)
242 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
244 Host::Ptr host = Host::GetByName(arguments[0]);
246 Service::Ptr hc = host->GetHostCheckService();
248 Logger::Write(LogInformation, "icinga", "Rescheduling next check for host '" + arguments[0] + "'");
249 hc->SetForceNextCheck(true);
250 hc->SetNextCheck(Convert::ToDouble(arguments[1]));
253 void ExternalCommandProcessor::ScheduleSvcCheck(double, const vector<String>& arguments)
255 if (arguments.size() < 3)
256 BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
258 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
260 double planned_check = Convert::ToDouble(arguments[2]);
262 if (planned_check > service->GetNextCheck()) {
263 Logger::Write(LogInformation, "icinga", "Ignoring reschedule request for service '" +
264 arguments[1] + "' (next check is already sooner than requested check time)");
268 Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + arguments[1] + "'");
269 service->SetNextCheck(planned_check);
272 void ExternalCommandProcessor::ScheduleForcedSvcCheck(double, const vector<String>& arguments)
274 if (arguments.size() < 3)
275 BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
277 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
279 Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + arguments[1] + "'");
280 service->SetForceNextCheck(true);
281 service->SetNextCheck(Convert::ToDouble(arguments[2]));
284 void ExternalCommandProcessor::EnableHostCheck(double, const vector<String>& arguments)
286 if (arguments.size() < 1)
287 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
289 Host::Ptr host = Host::GetByName(arguments[0]);
291 Logger::Write(LogInformation, "icinga", "Enabling active checks for host '" + arguments[0] + "'");
292 Service::Ptr hc = host->GetHostCheckService();
295 hc->SetEnableActiveChecks(true);
298 void ExternalCommandProcessor::DisableHostCheck(double, const vector<String>& arguments)
300 if (arguments.size() < 1)
301 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
303 Host::Ptr host = Host::GetByName(arguments[0]);
305 Logger::Write(LogInformation, "icinga", "Disabling active checks for host '" + arguments[0] + "'");
306 Service::Ptr hc = host->GetHostCheckService();
309 hc->SetEnableActiveChecks(false);
312 void ExternalCommandProcessor::EnableSvcCheck(double, const vector<String>& arguments)
314 if (arguments.size() < 2)
315 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
317 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
319 Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + arguments[1] + "'");
320 service->SetEnableActiveChecks(true);
323 void ExternalCommandProcessor::DisableSvcCheck(double, const vector<String>& arguments)
325 if (arguments.size() < 2)
326 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
328 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
330 Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + arguments[1] + "'");
331 service->SetEnableActiveChecks(false);
334 void ExternalCommandProcessor::ShutdownProcess(double, const vector<String>&)
336 Logger::Write(LogInformation, "icinga", "Shutting down Icinga via external command.");
337 Application::RequestShutdown();
340 void ExternalCommandProcessor::ScheduleForcedHostSvcChecks(double, const vector<String>& arguments)
342 if (arguments.size() < 2)
343 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
345 double planned_check = Convert::ToDouble(arguments[1]);
347 Host::Ptr host = Host::GetByName(arguments[0]);
349 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
350 Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + service->GetName() + "'");
351 service->SetNextCheck(planned_check);
352 service->SetForceNextCheck(true);
356 void ExternalCommandProcessor::ScheduleHostSvcChecks(double, const vector<String>& arguments)
358 if (arguments.size() < 2)
359 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
361 double planned_check = Convert::ToDouble(arguments[1]);
363 Host::Ptr host = Host::GetByName(arguments[0]);
365 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
366 if (planned_check > service->GetNextCheck()) {
367 Logger::Write(LogInformation, "icinga", "Ignoring reschedule request for service '" +
368 service->GetName() + "' (next check is already sooner than requested check time)");
372 Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + service->GetName() + "'");
373 service->SetNextCheck(planned_check);
377 void ExternalCommandProcessor::EnableHostSvcChecks(double, const vector<String>& arguments)
379 if (arguments.size() < 1)
380 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
382 Host::Ptr host = Host::GetByName(arguments[0]);
384 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
385 Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
386 service->SetEnableActiveChecks(true);
390 void ExternalCommandProcessor::DisableHostSvcChecks(double, const vector<String>& arguments)
392 if (arguments.size() < 1)
393 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 arguments."));
395 Host::Ptr host = Host::GetByName(arguments[0]);
397 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
398 Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
399 service->SetEnableActiveChecks(false);
403 void ExternalCommandProcessor::AcknowledgeSvcProblem(double, const vector<String>& arguments)
405 if (arguments.size() < 7)
406 BOOST_THROW_EXCEPTION(invalid_argument("Expected 7 arguments."));
408 bool sticky = Convert::ToBool(arguments[2]);
410 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
412 if (service->GetState() == StateOK)
413 BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK."));
415 Logger::Write(LogInformation, "icinga", "Setting acknowledgement for service '" + service->GetName() + "'");
416 service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal);
419 void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const vector<String>& arguments)
421 if (arguments.size() < 8)
422 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
424 bool sticky = Convert::ToBool(arguments[2]);
425 double timestamp = Convert::ToDouble(arguments[5]);
427 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
429 if (service->GetState() == StateOK)
430 BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK."));
432 Logger::Write(LogInformation, "icinga", "Setting timed acknowledgement for service '" + service->GetName() + "'");
433 service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal, timestamp);
436 void ExternalCommandProcessor::RemoveSvcAcknowledgement(double, const vector<String>& arguments)
438 if (arguments.size() < 2)
439 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
441 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
443 Logger::Write(LogInformation, "icinga", "Removing acknowledgement for service '" + service->GetName() + "'");
444 service->ClearAcknowledgement();
447 void ExternalCommandProcessor::AcknowledgeHostProblem(double, const vector<String>& arguments)
449 if (arguments.size() < 6)
450 BOOST_THROW_EXCEPTION(invalid_argument("Expected 6 arguments."));
452 bool sticky = Convert::ToBool(arguments[1]);
454 Host::Ptr host = Host::GetByName(arguments[0]);
456 Logger::Write(LogInformation, "icinga", "Setting acknowledgement for host '" + host->GetName() + "'");
457 Service::Ptr service = host->GetHostCheckService();
459 if (service->GetState() == StateOK)
460 BOOST_THROW_EXCEPTION(invalid_argument("The host '" + arguments[0] + "' is OK."));
462 service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal);
466 void ExternalCommandProcessor::AcknowledgeHostProblemExpire(double, const vector<String>& arguments)
468 if (arguments.size() < 7)
469 BOOST_THROW_EXCEPTION(invalid_argument("Expected 7 arguments."));
471 bool sticky = Convert::ToBool(arguments[1]);
472 double timestamp = Convert::ToDouble(arguments[4]);
474 Host::Ptr host = Host::GetByName(arguments[0]);
476 Logger::Write(LogInformation, "icinga", "Setting timed acknowledgement for host '" + host->GetName() + "'");
477 Service::Ptr service = host->GetHostCheckService();
479 if (service->GetState() == StateOK)
480 BOOST_THROW_EXCEPTION(invalid_argument("The host '" + arguments[0] + "' is OK."));
482 service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal, timestamp);
486 void ExternalCommandProcessor::RemoveHostAcknowledgement(double, const vector<String>& arguments)
488 if (arguments.size() < 1)
489 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
491 Host::Ptr host = Host::GetByName(arguments[0]);
493 Logger::Write(LogInformation, "icinga", "Removing acknowledgement for host '" + host->GetName() + "'");
494 Service::Ptr service = host->GetHostCheckService();
496 service->ClearAcknowledgement();
500 void ExternalCommandProcessor::EnableHostgroupSvcChecks(double, const vector<String>& arguments)
502 if (arguments.size() < 1)
503 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
505 HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
507 BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
508 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
509 Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
510 service->SetEnableActiveChecks(true);
515 void ExternalCommandProcessor::DisableHostgroupSvcChecks(double, const vector<String>& arguments)
517 if (arguments.size() < 1)
518 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
520 HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
522 BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
523 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
524 Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
525 service->SetEnableActiveChecks(false);
530 void ExternalCommandProcessor::EnableServicegroupSvcChecks(double, const vector<String>& arguments)
532 if (arguments.size() < 1)
533 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
535 ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
537 BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
538 Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
539 service->SetEnableActiveChecks(true);
543 void ExternalCommandProcessor::DisableServicegroupSvcChecks(double, const vector<String>& arguments)
545 if (arguments.size() < 1)
546 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
548 ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
550 BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
551 Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
552 service->SetEnableActiveChecks(false);
556 void ExternalCommandProcessor::EnablePassiveHostChecks(double, const vector<String>& arguments)
558 if (arguments.size() < 1)
559 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
561 Host::Ptr host = Host::GetByName(arguments[0]);
563 Logger::Write(LogInformation, "icinga", "Enabling passive checks for host '" + arguments[0] + "'");
564 Service::Ptr hc = host->GetHostCheckService();
567 hc->SetEnablePassiveChecks(true);
570 void ExternalCommandProcessor::DisablePassiveHostChecks(double, const vector<String>& arguments)
572 if (arguments.size() < 1)
573 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 arguments."));
575 Host::Ptr host = Host::GetByName(arguments[0]);
577 Logger::Write(LogInformation, "icinga", "Disabling passive checks for host '" + arguments[0] + "'");
578 Service::Ptr hc = host->GetHostCheckService();
581 hc->SetEnablePassiveChecks(false);
584 void ExternalCommandProcessor::EnablePassiveSvcChecks(double, const vector<String>& arguments)
586 if (arguments.size() < 2)
587 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
589 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
591 Logger::Write(LogInformation, "icinga", "Enabling passive checks for service '" + arguments[1] + "'");
592 service->SetEnablePassiveChecks(true);
595 void ExternalCommandProcessor::DisablePassiveSvcChecks(double, const vector<String>& arguments)
597 if (arguments.size() < 2)
598 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
600 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
602 Logger::Write(LogInformation, "icinga", "Disabling passive checks for service '" + arguments[1] + "'");
603 service->SetEnablePassiveChecks(false);
606 void ExternalCommandProcessor::EnableServicegroupPassiveSvcChecks(double, const vector<String>& arguments)
608 if (arguments.size() < 1)
609 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
611 ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
613 BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
614 Logger::Write(LogInformation, "icinga", "Enabling passive checks for service '" + service->GetName() + "'");
615 service->SetEnablePassiveChecks(true);
619 void ExternalCommandProcessor::DisableServicegroupPassiveSvcChecks(double, const vector<String>& arguments)
621 if (arguments.size() < 1)
622 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
624 ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
626 BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
627 Logger::Write(LogInformation, "icinga", "Disabling passive checks for service '" + service->GetName() + "'");
628 service->SetEnablePassiveChecks(true);
632 void ExternalCommandProcessor::EnableHostgroupPassiveSvcChecks(double, const vector<String>& arguments)
634 if (arguments.size() < 1)
635 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
637 HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
639 BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
640 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
641 Logger::Write(LogInformation, "icinga", "Enabling passive checks for service '" + service->GetName() + "'");
642 service->SetEnablePassiveChecks(true);
647 void ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks(double, const vector<String>& arguments)
649 if (arguments.size() < 1)
650 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
652 HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
654 BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
655 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
656 Logger::Write(LogInformation, "icinga", "Disabling passive checks for service '" + service->GetName() + "'");
657 service->SetEnablePassiveChecks(false);
662 void ExternalCommandProcessor::ProcessFile(double, const vector<String>& arguments)
664 if (arguments.size() < 2)
665 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
667 String file = arguments[0];
668 bool del = Convert::ToBool(arguments[1]);
671 ifp.exceptions(ifstream::badbit);
673 ifp.open(file.CStr(), ifstream::in);
677 std::getline(ifp, line);
680 Logger::Write(LogInformation, "compat", "Executing external command: " + line);
683 } catch (const exception& ex) {
685 msgbuf << "External command failed: " << diagnostic_information(ex);
686 Logger::Write(LogWarning, "icinga", msgbuf.str());
693 (void) unlink(file.CStr());
696 void ExternalCommandProcessor::ScheduleSvcDowntime(double, const vector<String>& arguments)
698 if (arguments.size() < 9)
699 BOOST_THROW_EXCEPTION(invalid_argument("Expected 9 arguments."));
701 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
704 int triggeredByLegacy = Convert::ToLong(arguments[5]);
705 if (triggeredByLegacy != 0)
706 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
708 Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
709 (void) service->AddDowntime(arguments[7], arguments[8],
710 Convert::ToDouble(arguments[2]), Convert::ToDouble(arguments[3]),
711 Convert::ToBool(arguments[4]), triggeredBy, Convert::ToDouble(arguments[6]));
714 void ExternalCommandProcessor::DelSvcDowntime(double, const vector<String>& arguments)
716 if (arguments.size() < 1)
717 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
719 int id = Convert::ToLong(arguments[0]);
720 Logger::Write(LogInformation, "icinga", "Removing downtime ID " + arguments[0]);
721 String rid = Service::GetDowntimeIDFromLegacyID(id);
722 Service::RemoveDowntime(rid);
725 void ExternalCommandProcessor::ScheduleHostDowntime(double, const vector<String>& arguments)
727 if (arguments.size() < 8)
728 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
730 Host::Ptr host = Host::GetByName(arguments[0]);
733 int triggeredByLegacy = Convert::ToLong(arguments[4]);
734 if (triggeredByLegacy != 0)
735 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
737 Logger::Write(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
738 Service::Ptr service = host->GetHostCheckService();
740 (void) service->AddDowntime(arguments[6], arguments[7],
741 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
742 Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
746 void ExternalCommandProcessor::DelHostDowntime(double, const vector<String>& arguments)
748 if (arguments.size() < 1)
749 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
751 int id = Convert::ToLong(arguments[0]);
752 Logger::Write(LogInformation, "icinga", "Removing downtime ID " + arguments[0]);
753 String rid = Service::GetDowntimeIDFromLegacyID(id);
754 Service::RemoveDowntime(rid);
757 void ExternalCommandProcessor::ScheduleHostSvcDowntime(double, const vector<String>& arguments)
759 if (arguments.size() < 8)
760 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 argument."));
762 Host::Ptr host = Host::GetByName(arguments[0]);
765 int triggeredByLegacy = Convert::ToLong(arguments[4]);
766 if (triggeredByLegacy != 0)
767 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
769 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
770 Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
771 (void) service->AddDowntime(arguments[6], arguments[7],
772 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
773 Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
777 void ExternalCommandProcessor::ScheduleHostgroupHostDowntime(double, const vector<String>& arguments)
779 if (arguments.size() < 8)
780 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
782 HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
785 int triggeredByLegacy = Convert::ToLong(arguments[4]);
786 if (triggeredByLegacy != 0)
787 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
789 BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
790 Logger::Write(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
791 Service::Ptr service = host->GetHostCheckService();
793 (void) service->AddDowntime(arguments[6], arguments[7],
794 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
795 Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
800 void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const vector<String>& arguments)
802 if (arguments.size() < 8)
803 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
805 HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
808 int triggeredByLegacy = Convert::ToLong(arguments[4]);
809 if (triggeredByLegacy != 0)
810 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
812 /* Note: we can't just directly create downtimes for all the services by iterating
813 * over all hosts in the host group - otherwise we might end up creating multiple
814 * downtimes for some services. */
816 set<Service::Ptr> services;
818 BOOST_FOREACH(const Host::Ptr& host, HostGroup::GetMembers(hg)) {
819 BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
820 services.insert(service);
824 BOOST_FOREACH(const Service::Ptr& service, services) {
825 Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
826 (void) service->AddDowntime(arguments[6], arguments[7],
827 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
828 Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
832 void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const vector<String>& arguments)
834 if (arguments.size() < 8)
835 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
837 ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
840 int triggeredByLegacy = Convert::ToLong(arguments[4]);
841 if (triggeredByLegacy != 0)
842 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
844 /* Note: we can't just directly create downtimes for all the hosts by iterating
845 * over all services in the service group - otherwise we might end up creating multiple
846 * downtimes for some hosts. */
848 set<Service::Ptr> services;
850 BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
851 Host::Ptr host = service->GetHost();
852 Service::Ptr hcService = host->GetHostCheckService();
854 services.insert(hcService);
857 BOOST_FOREACH(const Service::Ptr& service, services) {
858 Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
859 (void) service->AddDowntime(arguments[6], arguments[7],
860 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
861 Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
865 void ExternalCommandProcessor::ScheduleServicegroupSvcDowntime(double, const vector<String>& arguments)
867 if (arguments.size() < 8)
868 BOOST_THROW_EXCEPTION(invalid_argument("Expected 8 arguments."));
870 ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
873 int triggeredByLegacy = Convert::ToLong(arguments[4]);
874 if (triggeredByLegacy != 0)
875 triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
877 BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
878 Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
879 (void) service->AddDowntime(arguments[6], arguments[7],
880 Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
881 Convert::ToBool(arguments[3]), triggeredBy, Convert::ToDouble(arguments[5]));
885 void ExternalCommandProcessor::AddHostComment(double, const vector<String>& arguments)
887 if (arguments.size() < 4)
888 BOOST_THROW_EXCEPTION(invalid_argument("Expected 4 arguments."));
890 Host::Ptr host = Host::GetByName(arguments[0]);
892 Logger::Write(LogInformation, "icinga", "Creating comment for host " + host->GetName());
893 Service::Ptr service = host->GetHostCheckService();
895 (void) service->AddComment(CommentUser, arguments[2], arguments[3], 0);
898 void ExternalCommandProcessor::DelHostComment(double, const vector<String>& arguments)
900 if (arguments.size() < 1)
901 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
903 int id = Convert::ToLong(arguments[0]);
904 Logger::Write(LogInformation, "icinga", "Removing comment ID " + arguments[0]);
905 String rid = Service::GetCommentIDFromLegacyID(id);
906 Service::RemoveComment(rid);
909 void ExternalCommandProcessor::AddSvcComment(double, const vector<String>& arguments)
911 if (arguments.size() < 5)
912 BOOST_THROW_EXCEPTION(invalid_argument("Expected 5 arguments."));
914 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
916 Logger::Write(LogInformation, "icinga", "Creating comment for service " + service->GetName());
917 (void) service->AddComment(CommentUser, arguments[3], arguments[4], 0);
920 void ExternalCommandProcessor::DelSvcComment(double, const vector<String>& arguments)
922 if (arguments.size() < 1)
923 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
925 int id = Convert::ToLong(arguments[0]);
926 Logger::Write(LogInformation, "icinga", "Removing comment ID " + arguments[0]);
928 String rid = Service::GetCommentIDFromLegacyID(id);
929 Service::RemoveComment(rid);
932 void ExternalCommandProcessor::DelAllHostComments(double, const vector<String>& arguments)
934 if (arguments.size() < 1)
935 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
937 Host::Ptr host = Host::GetByName(arguments[0]);
939 Logger::Write(LogInformation, "icinga", "Removing all comments for host " + host->GetName());
940 Service::Ptr service = host->GetHostCheckService();
942 service->RemoveAllComments();
945 void ExternalCommandProcessor::DelAllSvcComments(double, const vector<String>& arguments)
947 if (arguments.size() < 2)
948 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
950 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
952 Logger::Write(LogInformation, "icinga", "Removing all comments for service " + service->GetName());
953 service->RemoveAllComments();
956 void ExternalCommandProcessor::SendCustomHostNotification(double time, const vector<String>& arguments)
958 if (arguments.size() < 4)
959 BOOST_THROW_EXCEPTION(invalid_argument("Expected 4 arguments."));
961 Host::Ptr host = Host::GetByName(arguments[0]);
963 Logger::Write(LogInformation, "icinga", "Sending custom notification for host " + host->GetName());
964 Service::Ptr service = host->GetHostCheckService();
966 service->RequestNotifications(NotificationCustom);
970 void ExternalCommandProcessor::SendCustomSvcNotification(double time, const vector<String>& arguments)
972 if (arguments.size() < 5)
973 BOOST_THROW_EXCEPTION(invalid_argument("Expected 5 arguments."));
975 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
977 Logger::Write(LogInformation, "icinga", "Sending custom notification for service " + service->GetName());
978 service->RequestNotifications(NotificationCustom);
981 void ExternalCommandProcessor::DelayHostNotification(double time, const vector<String>& arguments)
983 if (arguments.size() < 2)
984 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
986 Host::Ptr host = Host::GetByName(arguments[0]);
988 Logger::Write(LogInformation, "icinga", "Delaying notifications for host " + host->GetName());
989 Service::Ptr service = host->GetHostCheckService();
991 service->SetLastNotification(Convert::ToDouble(arguments[1]));
995 void ExternalCommandProcessor::DelaySvcNotification(double time, const vector<String>& arguments)
997 if (arguments.size() < 3)
998 BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
1000 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1002 Logger::Write(LogInformation, "icinga", "Delaying notifications for service " + service->GetName());
1003 service->SetLastNotification(Convert::ToDouble(arguments[2]));
1006 void ExternalCommandProcessor::EnableHostNotifications(double, const vector<String>& arguments)
1008 if (arguments.size() < 1)
1009 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
1011 Host::Ptr host = Host::GetByName(arguments[0]);
1013 Logger::Write(LogInformation, "icinga", "Enabling notifications for host '" + arguments[0] + "'");
1014 Service::Ptr hc = host->GetHostCheckService();
1017 hc->SetEnableNotifications(true);
1020 void ExternalCommandProcessor::DisableHostNotifications(double, const vector<String>& arguments)
1022 if (arguments.size() < 1)
1023 BOOST_THROW_EXCEPTION(invalid_argument("Expected 1 argument."));
1025 Host::Ptr host = Host::GetByName(arguments[0]);
1027 Logger::Write(LogInformation, "icinga", "Disabling notifications for host '" + arguments[0] + "'");
1028 Service::Ptr hc = host->GetHostCheckService();
1031 hc->SetEnableNotifications(false);
1034 void ExternalCommandProcessor::EnableSvcNotifications(double, const vector<String>& arguments)
1036 if (arguments.size() < 2)
1037 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
1039 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1041 Logger::Write(LogInformation, "icinga", "Enabling notifications for service '" + arguments[1] + "'");
1042 service->SetEnableNotifications(true);
1045 void ExternalCommandProcessor::DisableSvcNotifications(double, const vector<String>& arguments)
1047 if (arguments.size() < 2)
1048 BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
1050 Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
1052 Logger::Write(LogInformation, "icinga", "Disabling notifications for service '" + arguments[1] + "'");
1053 service->SetEnableNotifications(false);