diff --git a/components/compat/statusdatawriter.cpp b/components/compat/statusdatawriter.cpp index fbb0d4601..4e0b1c8c6 100644 --- a/components/compat/statusdatawriter.cpp +++ b/components/compat/statusdatawriter.cpp @@ -299,19 +299,16 @@ void StatusDataWriter::DumpHostObject(std::ostream& fp, const Host::Ptr& host) << "\t" << "passive_checks_enabled" << "\t" << (hc->GetEnablePassiveChecks() ? 1 : 0) << "\n" << "\t" << "notifications_enabled" << "\t" << (hc->GetEnableNotifications() ? 1 : 0) << "\n" << "\t" << "notification_options" << "\t" << "d,u,r" << "\n" - << "\t" << "notification_interval" << "\t" << 1 << "\n"; + << "\t" << "notification_interval" << "\t" << 1 << "\n" + << "\t" << "event_handler_enabled" << "\t" << (hc->GetEnableEventHandler() ? 1 : 0) << "\n"; CheckCommand::Ptr checkcommand = hc->GetCheckCommand(); if (checkcommand) fp << "\t" << "check_command" << "\t" << "check_" << checkcommand->GetName() << "\n"; EventCommand::Ptr eventcommand = hc->GetEventCommand(); - if (eventcommand) { - fp << "\t" << "event_handler_enabled" << "\t" << 1 << "\n" - << "\t" << "event_handler" << "\t" << "event_" << eventcommand->GetName() << "\n"; - } else { - fp << "\t" << "event_handler_enabled" << "\t" << 0 << "\n"; - } + if (eventcommand) + fp << "\t" << "event_handler" << "\t" << "event_" << eventcommand->GetName() << "\n"; TimePeriod::Ptr check_period = hc->GetCheckPeriod(); if (check_period) @@ -480,19 +477,16 @@ void StatusDataWriter::DumpServiceObject(std::ostream& fp, const Service::Ptr& s << "\t" << "is_volatile" << "\t" << (service->IsVolatile() ? 1 : 0) << "\n" << "\t" << "notifications_enabled" << "\t" << (service->GetEnableNotifications() ? 1 : 0) << "\n" << "\t" << "notification_options" << "\t" << "u,w,c,r" << "\n" - << "\t" << "notification_interval" << "\t" << notification_interval / 60.0 << "\n"; + << "\t" << "notification_interval" << "\t" << notification_interval / 60.0 << "\n" + << "\t" << "event_handler_enabled" << "\t" << (service->GetEnableEventHandler() ? 1 : 0) << "\n"; CheckCommand::Ptr checkcommand = service->GetCheckCommand(); if (checkcommand) fp << "\t" << "check_command" << "\t" << "check_" << checkcommand->GetName() << "\n"; EventCommand::Ptr eventcommand = service->GetEventCommand(); - if (eventcommand) { - fp << "\t" << "event_handler_enabled" << "\t" << 1 << "\n" - << "\t" << "event_handler" << "\t" << "event_" << eventcommand->GetName() << "\n"; - } else { - fp << "\t" << "event_handler_enabled" << "\t" << 0 << "\n"; - } + if (eventcommand) + fp << "\t" << "event_handler" << "\t" << "event_" << eventcommand->GetName() << "\n"; TimePeriod::Ptr check_period = service->GetCheckPeriod(); if (check_period) diff --git a/doc/4.3-object-types.md b/doc/4.3-object-types.md index c0f52f03f..df41c7c58 100644 --- a/doc/4.3-object-types.md +++ b/doc/4.3-object-types.md @@ -114,6 +114,7 @@ Attributes: retry\_interval |**Optional.** The retry interval (in seconds). This interval is used for checks when the service is in a `SOFT` state. Defaults to 1/5th of the check interval if not specified. enable\_active\_checks|**Optional.** Whether active checks are enabled. Defaults to true. enable\_passive\_checks|**Optional.** Whether passive checks are enabled. Defaults to true. + enable\_event\_handler|**Optional.** Enables event handlers for this service. Defaults to true. event\_command |**Optional.** The name of an event command that should be executed every time the service's state changes. flapping\_threshold|TODO volatile |TODO diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index 7c82cf8b4..0dc57071f 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -186,6 +186,10 @@ void ExternalCommandProcessor::Initialize(void) RegisterCommand("CHANGE_NORMAL_HOST_CHECK_INTERVAL", &ExternalCommandProcessor::ChangeNormalHostCheckInterval); RegisterCommand("CHANGE_RETRY_SVC_CHECK_INTERVAL", &ExternalCommandProcessor::ChangeRetrySvcCheckInterval); RegisterCommand("CHANGE_RETRY_HOST_CHECK_INTERVAL", &ExternalCommandProcessor::ChangeRetryHostCheckInterval); + RegisterCommand("ENABLE_HOST_EVENT_HANDLER", &ExternalCommandProcessor::EnableHostEventHandler); + RegisterCommand("DISABLE_HOST_EVENT_HANDLER", &ExternalCommandProcessor::DisableHostEventHandler); + RegisterCommand("ENABLE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::EnableSvcEventHandler); + RegisterCommand("DISABLE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::DisableSvcEventHandler); } void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandProcessor::Callback& callback) @@ -1949,4 +1953,84 @@ void ExternalCommandProcessor::ChangeRetryHostCheckInterval(double time, const s hc->SetRetryInterval(interval * 60); } -} \ No newline at end of file +} + +void ExternalCommandProcessor::EnableHostEventHandler(double time, const std::vector& arguments) +{ + if (arguments.size() < 1) + BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument.")); + + Host::Ptr host = Host::GetByName(arguments[0]); + + if (!host) + BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot enable event handler for non-existent host '" + arguments[0] + "'")); + + Service::Ptr hc = host->GetCheckService(); + + Log(LogInformation, "icinga", "Enabling event handler for host '" + arguments[0] + "'"); + + { + ObjectLock olock(hc); + + hc->SetEnableEventHandler(true); + } +} + +void ExternalCommandProcessor::DisableHostEventHandler(double time, const std::vector& arguments) +{ + if (arguments.size() < 1) + BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 1 argument.")); + + Host::Ptr host = Host::GetByName(arguments[0]); + + if (!host) + BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot disable event handler for non-existent host '" + arguments[0] + "'")); + + Service::Ptr hc = host->GetCheckService(); + + Log(LogInformation, "icinga", "Disabling event handler for host '" + arguments[0] + "'"); + + { + ObjectLock olock(hc); + + hc->SetEnableEventHandler(false); + } +} + +void ExternalCommandProcessor::EnableSvcEventHandler(double time, const std::vector& arguments) +{ + if (arguments.size() < 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments.")); + + 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] + "'")); + + Log(LogInformation, "icinga", "Enabling event handler for service '" + arguments[1] + "'"); + + { + ObjectLock olock(service); + + service->SetEnableEventHandler(true); + } +} + +void ExternalCommandProcessor::DisableSvcEventHandler(double time, const std::vector& arguments) +{ + if (arguments.size() < 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 2 arguments.")); + + 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] + "'")); + + Log(LogInformation, "icinga", "Disabling event handler for service '" + arguments[1] + "'"); + + { + ObjectLock olock(service); + + service->SetEnableEventHandler(false); + } +} diff --git a/lib/icinga/externalcommandprocessor.h b/lib/icinga/externalcommandprocessor.h index a66db9eec..2216728a7 100644 --- a/lib/icinga/externalcommandprocessor.h +++ b/lib/icinga/externalcommandprocessor.h @@ -137,6 +137,10 @@ private: static void ChangeNormalHostCheckInterval(double time, const std::vector& arguments); static void ChangeRetrySvcCheckInterval(double time, const std::vector& arguments); static void ChangeRetryHostCheckInterval(double time, const std::vector& arguments); + static void EnableHostEventHandler(double time, const std::vector& arguments); + 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); }; } diff --git a/lib/icinga/icinga-type.conf b/lib/icinga/icinga-type.conf index 816481293..f6d525369 100644 --- a/lib/icinga/icinga-type.conf +++ b/lib/icinga/icinga-type.conf @@ -78,6 +78,7 @@ type Service { %attribute number "enable_active_checks", %attribute number "enable_passive_checks", + %attribute number "enable_event_handler", %attribute name(EventCommand) "event_command", diff --git a/lib/icinga/service-event.cpp b/lib/icinga/service-event.cpp index 9714c906c..adacd53da 100644 --- a/lib/icinga/service-event.cpp +++ b/lib/icinga/service-event.cpp @@ -25,9 +25,19 @@ using namespace icinga; boost::signals2::signal Service::OnEventCommandExecuted; -bool Service::GetEnableEventHandlers(void) const +bool Service::GetEnableEventHandler(void) const { - return m_EnableEventHandlers; + if (!m_OverrideEnableEventHandler.IsEmpty()) + return m_EnableEventHandler; + else if (!m_EnableEventHandler.IsEmpty()) + return m_EnableEventHandler; + else + return true; +} + +void Service::SetEnableEventHandler(bool enabled) +{ + m_OverrideEnableEventHandler = enabled; } EventCommand::Ptr Service::GetEventCommand(void) const @@ -37,7 +47,7 @@ EventCommand::Ptr Service::GetEventCommand(void) const void Service::ExecuteEventHandler(void) { - if (!IcingaApplication::GetInstance()->GetEnableEventHandlers() || !GetEnableEventHandlers()) + if (!IcingaApplication::GetInstance()->GetEnableEventHandlers() || !GetEnableEventHandler()) return; EventCommand::Ptr ec = GetEventCommand(); diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index bece73696..a3e41d9d1 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -343,6 +343,9 @@ int Service::GetModifiedAttributes(void) const if (!m_OverrideEnablePassiveChecks.IsEmpty()) attrs |= ModAttrPassiveChecksEnabled; + if (!m_OverrideEnableEventHandler.IsEmpty()) + attrs |= ModAttrEventHandlerEnabled; + if (!m_OverrideCheckInterval.IsEmpty()) attrs |= ModAttrNormalCheckInterval; @@ -362,6 +365,9 @@ void Service::SetModifiedAttributes(int flags) if ((flags & ModAttrPassiveChecksEnabled) == 0) m_OverrideEnablePassiveChecks = Empty; + if ((flags & ModAttrEventHandlerEnabled) == 0) + m_OverrideEnableEventHandler = Empty; + if ((flags & ModAttrNormalCheckInterval) == 0) m_OverrideCheckInterval = Empty; @@ -467,6 +473,9 @@ void Service::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) bag->Set("host", m_HostName); bag->Set("flapping_threshold", m_FlappingThreshold); bag->Set("notifications", m_NotificationDescriptions); + bag->Set("enable_active_checks", m_EnableActiveChecks); + bag->Set("enable_passive_checks", m_EnablePassiveChecks); + bag->Set("enable_event_handler", m_EnableEventHandler); } if (attributeTypes & Attribute_State) { @@ -502,11 +511,11 @@ void Service::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) bag->Set("flapping_lastchange", m_FlappingLastChange); bag->Set("enable_flapping", m_EnableFlapping); bag->Set("enable_perfdata", m_EnablePerfdata); - bag->Set("enable_event_handlers", m_EnableEventHandlers); bag->Set("override_enable_active_checks", m_OverrideEnableActiveChecks); bag->Set("override_enable_passive_checks", m_OverrideEnablePassiveChecks); bag->Set("override_check_interval", m_OverrideCheckInterval); bag->Set("override_retry_interval", m_OverrideRetryInterval); + bag->Set("override_enable_event_handler", m_OverrideEnableEventHandler); } } @@ -533,6 +542,7 @@ void Service::InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes m_NotificationDescriptions = bag->Get("notifications"); m_EnableActiveChecks = bag->Get("enable_active_checks"); m_EnablePassiveChecks = bag->Get("enable_passive_checks"); + m_EnableEventHandler = bag->Get("enable_event_handler"); } if (attributeTypes & Attribute_State) { @@ -566,10 +576,10 @@ void Service::InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes m_FlappingLastChange = bag->Get("flapping_lastchange"); m_EnableFlapping = bag->Get("enable_flapping"); m_EnablePerfdata = bag->Get("enable_perfdata"); - m_EnableEventHandlers = bag->Get("enable_event_handlers"); m_OverrideEnableActiveChecks = bag->Get("override_enable_active_checks"); m_OverrideEnablePassiveChecks = bag->Get("override_enable_passive_checks"); m_OverrideCheckInterval = bag->Get("override_check_interval"); m_OverrideRetryInterval = bag->Get("override_retry_interval"); + m_OverrideEnableEventHandler = bag->Get("override_enable_event_handler"); } } diff --git a/lib/icinga/service.h b/lib/icinga/service.h index 4e76ef68a..8ed08d903 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -358,7 +358,9 @@ public: /* Event Handler */ void ExecuteEventHandler(void); shared_ptr GetEventCommand(void) const; - bool GetEnableEventHandlers(void) const; + + bool GetEnableEventHandler(void) const; + void SetEnableEventHandler(bool enabled); /* Flapping Detection */ bool GetEnableFlapping(void) const; @@ -453,7 +455,8 @@ private: std::set m_Notifications; /* Event Handler */ - Value m_EnableEventHandlers; + Value m_EnableEventHandler; + Value m_OverrideEnableEventHandler; String m_EventCommand; /* Flapping */