diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index 8a793420a..77d5d5b83 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -193,6 +193,8 @@ void ExternalCommandProcessor::Initialize(void) RegisterCommand("DISABLE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::DisableSvcEventHandler); RegisterCommand("CHANGE_HOST_EVENT_HANDLER", &ExternalCommandProcessor::ChangeHostEventHandler); RegisterCommand("CHANGE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::ChangeSvcEventHandler); + RegisterCommand("CHANGE_HOST_CHECK_COMMAND", &ExternalCommandProcessor::ChangeHostCheckCommand); + RegisterCommand("CHANGE_SVC_CHECK_COMMAND", &ExternalCommandProcessor::ChangeSvcCheckCommand); } void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandProcessor::Callback& callback) @@ -2054,7 +2056,7 @@ void ExternalCommandProcessor::ChangeSvcEventHandler(double time, const std::vec Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); if (!service) - BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change event handler non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); + BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change event handler for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); EventCommand::Ptr command = EventCommand::GetByName(arguments[2]); @@ -2069,3 +2071,53 @@ void ExternalCommandProcessor::ChangeSvcEventHandler(double time, const std::vec service->SetEventCommand(command); } } + +void ExternalCommandProcessor::ChangeHostCheckCommand(double time, const std::vector& arguments) +{ + if (arguments.size() < 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments.")); + + Host::Ptr host = Host::GetByName(arguments[0]); + + if (!host) + BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change check command for non-existent host '" + arguments[0] + "'")); + + Service::Ptr hc = host->GetCheckService(); + + CheckCommand::Ptr command = CheckCommand::GetByName(arguments[2]); + + if (!command) + BOOST_THROW_EXCEPTION(std::invalid_argument("Check command '" + arguments[1] + "' does not exist.")); + + Log(LogInformation, "icinga", "Changing check command for host '" + arguments[0] + "' to '" + arguments[1] + "'"); + + { + ObjectLock olock(hc); + + hc->SetCheckCommand(command); + } +} + +void ExternalCommandProcessor::ChangeSvcCheckCommand(double time, const std::vector& arguments) +{ + if (arguments.size() < 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 3 arguments.")); + + Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); + + if (!service) + BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot change check command for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); + + CheckCommand::Ptr command = CheckCommand::GetByName(arguments[2]); + + if (!command) + BOOST_THROW_EXCEPTION(std::invalid_argument("Check command '" + arguments[2] + "' does not exist.")); + + Log(LogInformation, "icinga", "Changing check command for service '" + arguments[1] + "' to '" + arguments[2] + "'"); + + { + ObjectLock olock(service); + + service->SetCheckCommand(command); + } +} diff --git a/lib/icinga/externalcommandprocessor.h b/lib/icinga/externalcommandprocessor.h index 86679de63..a8efbf3ef 100644 --- a/lib/icinga/externalcommandprocessor.h +++ b/lib/icinga/externalcommandprocessor.h @@ -143,6 +143,8 @@ private: static void DisableSvcEventHandler(double time, const std::vector& arguments); static void ChangeHostEventHandler(double time, const std::vector& arguments); static void ChangeSvcEventHandler(double time, const std::vector& arguments); + static void ChangeHostCheckCommand(double time, const std::vector& arguments); + static void ChangeSvcCheckCommand(double time, const std::vector& arguments); }; } diff --git a/lib/icinga/service-check.cpp b/lib/icinga/service-check.cpp index 219086109..2c4e29335 100644 --- a/lib/icinga/service-check.cpp +++ b/lib/icinga/service-check.cpp @@ -47,7 +47,19 @@ boost::signals2::signal Service::OnFl CheckCommand::Ptr Service::GetCheckCommand(void) const { - return CheckCommand::GetByName(GetCheckCommandRaw()); + String command; + + if (!GetOverrideCheckCommand().IsEmpty()) + command = GetOverrideCheckCommand(); + else + command = GetCheckCommandRaw(); + + return CheckCommand::GetByName(command); +} + +void Service::SetCheckCommand(const CheckCommand::Ptr& command) +{ + SetOverrideCheckCommand(command->GetName()); } TimePeriod::Ptr Service::GetCheckPeriod(void) const diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index 3bea75cc7..82571ada6 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -304,6 +304,9 @@ int Service::GetModifiedAttributes(void) const if (!GetOverrideEventCommand().IsEmpty()) attrs |= ModAttrEventHandlerCommand; + if (!GetOverrideCheckCommand().IsEmpty()) + attrs |= ModAttrCheckCommand; + // TODO: finish return attrs; @@ -337,6 +340,9 @@ void Service::SetModifiedAttributes(int flags) if ((flags & ModAttrEventHandlerCommand) == 0) SetOverrideEventCommand(Empty); + + if ((flags & ModAttrCheckCommand) == 0) + SetOverrideCheckCommand(Empty); } bool Service::ResolveMacro(const String& macro, const CheckResult::Ptr& cr, String *result) const diff --git a/lib/icinga/service.h b/lib/icinga/service.h index a2cda9a28..4d2374243 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -109,6 +109,8 @@ public: /* Checks */ shared_ptr GetCheckCommand(void) const; + void SetCheckCommand(const shared_ptr& command); + TimePeriod::Ptr GetCheckPeriod(void) const; double GetCheckInterval(void) const; diff --git a/lib/icinga/service.ti b/lib/icinga/service.ti index 04bc047c6..c59528ac6 100644 --- a/lib/icinga/service.ti +++ b/lib/icinga/service.ti @@ -137,6 +137,7 @@ class Service : DynamicObject [state] Value override_retry_interval; [state] Value override_enable_event_handler; [state] Value override_event_command; + [state] Value override_check_command; }; }