diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index f0e9d1f6c..8a793420a 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -25,6 +25,7 @@ #include "icinga/servicegroup.h" #include "icinga/pluginutility.h" #include "icinga/icingaapplication.h" +#include "icinga/eventcommand.h" #include "base/convert.h" #include "base/logger_fwd.h" #include "base/objectlock.h" @@ -190,6 +191,8 @@ void ExternalCommandProcessor::Initialize(void) RegisterCommand("DISABLE_HOST_EVENT_HANDLER", &ExternalCommandProcessor::DisableHostEventHandler); RegisterCommand("ENABLE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::EnableSvcEventHandler); RegisterCommand("DISABLE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::DisableSvcEventHandler); + RegisterCommand("CHANGE_HOST_EVENT_HANDLER", &ExternalCommandProcessor::ChangeHostEventHandler); + RegisterCommand("CHANGE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::ChangeSvcEventHandler); } void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandProcessor::Callback& callback) @@ -1987,7 +1990,7 @@ void ExternalCommandProcessor::EnableSvcEventHandler(double time, const std::vec Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); if (!service) - BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable event handlerfor non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); + BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable event handler for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); Log(LogInformation, "icinga", "Enabling event handler for service '" + arguments[1] + "'"); @@ -2006,7 +2009,7 @@ void ExternalCommandProcessor::DisableSvcEventHandler(double time, const std::ve Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); if (!service) - BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable event handlerfor non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); + BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable event handler for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); Log(LogInformation, "icinga", "Disabling event handler for service '" + arguments[1] + "'"); @@ -2016,3 +2019,53 @@ void ExternalCommandProcessor::DisableSvcEventHandler(double time, const std::ve service->SetEnableEventHandler(false); } } + +void ExternalCommandProcessor::ChangeHostEventHandler(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 event handler for non-existent host '" + arguments[0] + "'")); + + Service::Ptr hc = host->GetCheckService(); + + EventCommand::Ptr command = EventCommand::GetByName(arguments[2]); + + if (!command) + BOOST_THROW_EXCEPTION(std::invalid_argument("Event command '" + arguments[1] + "' does not exist.")); + + Log(LogInformation, "icinga", "Changing event handler for host '" + arguments[0] + "' to '" + arguments[1] + "'"); + + { + ObjectLock olock(hc); + + hc->SetEventCommand(command); + } +} + +void ExternalCommandProcessor::ChangeSvcEventHandler(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 event handler non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); + + EventCommand::Ptr command = EventCommand::GetByName(arguments[2]); + + if (!command) + BOOST_THROW_EXCEPTION(std::invalid_argument("Event command '" + arguments[2] + "' does not exist.")); + + Log(LogInformation, "icinga", "Changing event handler for service '" + arguments[1] + "' to '" + arguments[2] + "'"); + + { + ObjectLock olock(service); + + service->SetEventCommand(command); + } +} diff --git a/lib/icinga/externalcommandprocessor.h b/lib/icinga/externalcommandprocessor.h index 2216728a7..86679de63 100644 --- a/lib/icinga/externalcommandprocessor.h +++ b/lib/icinga/externalcommandprocessor.h @@ -141,6 +141,8 @@ private: static void DisableHostEventHandler(double time, const std::vector& arguments); static void EnableSvcEventHandler(double time, const std::vector& arguments); 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); }; } diff --git a/lib/icinga/service-event.cpp b/lib/icinga/service-event.cpp index d7b8d7806..ff5923400 100644 --- a/lib/icinga/service-event.cpp +++ b/lib/icinga/service-event.cpp @@ -41,7 +41,19 @@ void Service::SetEnableEventHandler(bool enabled) EventCommand::Ptr Service::GetEventCommand(void) const { - return EventCommand::GetByName(GetEventCommandRaw()); + String command; + + if (!GetOverrideEventCommand().IsEmpty()) + command = GetOverrideEventCommand(); + else + command = GetEventCommandRaw(); + + return EventCommand::GetByName(command); +} + +void Service::SetEventCommand(const EventCommand::Ptr& command) +{ + SetOverrideEventCommand(command->GetName()); } void Service::ExecuteEventHandler(void) diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index 1d3311fa8..3bea75cc7 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -301,6 +301,9 @@ int Service::GetModifiedAttributes(void) const if (!GetOverrideRetryInterval().IsEmpty()) attrs |= ModAttrRetryCheckInterval; + if (!GetOverrideEventCommand().IsEmpty()) + attrs |= ModAttrEventHandlerCommand; + // TODO: finish return attrs; @@ -331,6 +334,9 @@ void Service::SetModifiedAttributes(int flags) if ((flags & ModAttrRetryCheckInterval) == 0) SetOverrideRetryInterval(Empty); + + if ((flags & ModAttrEventHandlerCommand) == 0) + SetOverrideEventCommand(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 458410b83..a2cda9a28 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -235,7 +235,9 @@ public: /* Event Handler */ void ExecuteEventHandler(void); + shared_ptr GetEventCommand(void) const; + void SetEventCommand(const shared_ptr& command); bool GetEnableEventHandler(void) const; void SetEnableEventHandler(bool enabled); diff --git a/lib/icinga/service.ti b/lib/icinga/service.ti index f3f9c3672..04bc047c6 100644 --- a/lib/icinga/service.ti +++ b/lib/icinga/service.ti @@ -136,6 +136,7 @@ class Service : DynamicObject [state] Value override_check_interval; [state] Value override_retry_interval; [state] Value override_enable_event_handler; + [state] Value override_event_command; }; }