From 04061adc01d397aecd1ccec66f63594a9f3601ce Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 26 Nov 2013 11:18:05 +0100 Subject: [PATCH 1/8] Implement override_enable_notifications. Refs #4746 --- lib/icinga/icinga-type.conf | 1 + lib/icinga/service-notification.cpp | 7 +++++-- lib/icinga/service.cpp | 6 ++++++ lib/icinga/service.ti | 7 ++++--- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/icinga/icinga-type.conf b/lib/icinga/icinga-type.conf index 473f4b938..706b2d7cf 100644 --- a/lib/icinga/icinga-type.conf +++ b/lib/icinga/icinga-type.conf @@ -76,6 +76,7 @@ type Service { %attribute number "check_interval", %attribute number "retry_interval", + %attribute number "enable_notifications", %attribute number "enable_active_checks", %attribute number "enable_passive_checks", %attribute number "enable_event_handler", diff --git a/lib/icinga/service-notification.cpp b/lib/icinga/service-notification.cpp index 0f32995d1..0d69ab7bd 100644 --- a/lib/icinga/service-notification.cpp +++ b/lib/icinga/service-notification.cpp @@ -163,12 +163,15 @@ void Service::UpdateSlaveNotifications(void) bool Service::GetEnableNotifications(void) const { - return GetEnableNotificationsRaw(); + if (!GetOverrideEnableNotifications().IsEmpty()) + return GetOverrideEnableNotifications(); + else + return GetEnableNotifications(); } void Service::SetEnableNotifications(bool enabled, const String& authority) { - SetEnableNotificationsRaw(enabled); + SetOverrideEnableActiveChecks(enabled); OnEnableNotificationsChanged(GetSelf(), enabled, authority); } diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index 3a45529c2..e985c2a18 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -264,6 +264,9 @@ int Service::GetModifiedAttributes(void) const { int attrs = 0; + if (!GetOverrideEnableNotifications().IsEmpty()) + attrs |= ModAttrNotificationsEnabled; + if (!GetOverrideEnableActiveChecks().IsEmpty()) attrs |= ModAttrActiveChecksEnabled; @@ -286,6 +289,9 @@ int Service::GetModifiedAttributes(void) const void Service::SetModifiedAttributes(int flags) { + if ((flags & ModAttrNotificationsEnabled) == 0) + SetOverrideEnableNotifications(Empty); + if ((flags & ModAttrActiveChecksEnabled) == 0) SetOverrideEnableActiveChecks(Empty); diff --git a/lib/icinga/service.ti b/lib/icinga/service.ti index 134a41c61..09c5d3f13 100644 --- a/lib/icinga/service.ti +++ b/lib/icinga/service.ti @@ -68,6 +68,9 @@ class Service : DynamicObject [config] bool enable_event_handler (EnableEventHandlerRaw) { default {{{ return true; }}} }; + [config] bool enable_notifications (EnableNotificationsRaw) { + default {{{ return true; }}} + }; [state] double next_check (NextCheckRaw); [state] int check_attempt { @@ -115,9 +118,6 @@ class Service : DynamicObject [state] Dictionary::Ptr downtimes { default {{{ return make_shared(); }}} }; - [state] bool enable_notifications (EnableNotificationsRaw) { - default {{{ return true; }}} - }; [state] bool force_next_notification (ForceNextNotificationRaw); [state] int flapping_positive; [state] int flapping_negative; @@ -128,6 +128,7 @@ class Service : DynamicObject [state] bool enable_perfdata { default {{{ return true; }}} }; + [state] Value override_enable_notifications; [state] Value override_enable_active_checks; [state] Value override_enable_passive_checks; [state] Value override_check_interval; From d8c9d6a88a7a607330bacf15103e0f8aee30a526 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 26 Nov 2013 11:34:33 +0100 Subject: [PATCH 2/8] Implement override_enable_flapping. Refs #4746 --- lib/icinga/service-flapping.cpp | 7 +++++-- lib/icinga/service-notification.cpp | 2 +- lib/icinga/service.cpp | 6 ++++++ lib/icinga/service.ti | 7 ++++--- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/icinga/service-flapping.cpp b/lib/icinga/service-flapping.cpp index 144b165a5..67b7af938 100644 --- a/lib/icinga/service-flapping.cpp +++ b/lib/icinga/service-flapping.cpp @@ -42,12 +42,15 @@ double Service::GetFlappingCurrent(void) const bool Service::GetEnableFlapping(void) const { - return GetEnableFlappingRaw(); + if (!GetOverrideEnableFlapping().IsEmpty()) + return GetOverrideEnableFlapping(); + else + return GetEnableFlappingRaw(); } void Service::SetEnableFlapping(bool enabled, const String& authority) { - SetEnableFlappingRaw(enabled); + SetOverrideEnableFlapping(enabled); OnFlappingChanged(GetSelf(), enabled ? FlappingEnabled : FlappingDisabled); OnEnableFlappingChanged(GetSelf(), enabled, authority); diff --git a/lib/icinga/service-notification.cpp b/lib/icinga/service-notification.cpp index 0d69ab7bd..6128301c9 100644 --- a/lib/icinga/service-notification.cpp +++ b/lib/icinga/service-notification.cpp @@ -166,7 +166,7 @@ bool Service::GetEnableNotifications(void) const if (!GetOverrideEnableNotifications().IsEmpty()) return GetOverrideEnableNotifications(); else - return GetEnableNotifications(); + return GetEnableNotificationsRaw(); } void Service::SetEnableNotifications(bool enabled, const String& authority) diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index e985c2a18..b1d05fbd5 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -273,6 +273,9 @@ int Service::GetModifiedAttributes(void) const if (!GetOverrideEnablePassiveChecks().IsEmpty()) attrs |= ModAttrPassiveChecksEnabled; + if (!GetOverrideEnableFlapping().IsEmpty()) + attrs |= ModAttrFlapDetectionEnabled; + if (!GetOverrideEnableEventHandler().IsEmpty()) attrs |= ModAttrEventHandlerEnabled; @@ -298,6 +301,9 @@ void Service::SetModifiedAttributes(int flags) if ((flags & ModAttrPassiveChecksEnabled) == 0) SetOverrideEnablePassiveChecks(Empty); + if ((flags & ModAttrFlapDetectionEnabled) == 0) + SetOverrideEnableFlapping(Empty); + if ((flags & ModAttrEventHandlerEnabled) == 0) SetOverrideEnableEventHandler(Empty); diff --git a/lib/icinga/service.ti b/lib/icinga/service.ti index 09c5d3f13..9fadc756b 100644 --- a/lib/icinga/service.ti +++ b/lib/icinga/service.ti @@ -71,6 +71,9 @@ class Service : DynamicObject [config] bool enable_notifications (EnableNotificationsRaw) { default {{{ return true; }}} }; + [config] bool enable_flapping (EnableFlappingRaw) { + default {{{ return true; }}} + }; [state] double next_check (NextCheckRaw); [state] int check_attempt { @@ -122,15 +125,13 @@ class Service : DynamicObject [state] int flapping_positive; [state] int flapping_negative; [state] double flapping_last_change; - [state] bool enable_flapping (EnableFlappingRaw) { - default {{{ return true; }}} - }; [state] bool enable_perfdata { default {{{ return true; }}} }; [state] Value override_enable_notifications; [state] Value override_enable_active_checks; [state] Value override_enable_passive_checks; + [state] Value override_enable_flapping; [state] Value override_check_interval; [state] Value override_retry_interval; [state] Value override_enable_event_handler; From ae3eaee1f4d0122e920a581e236498e11a344611 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 26 Nov 2013 11:51:06 +0100 Subject: [PATCH 3/8] Implement override_enable_perfdata. Refs #4746 --- lib/icinga/service.cpp | 19 +++++++++++++++++++ lib/icinga/service.h | 4 ++++ lib/icinga/service.ti | 7 ++++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index b1d05fbd5..1d3311fa8 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -260,6 +260,19 @@ std::set Service::GetParentServices(void) const return parents; } +bool Service::GetEnablePerfdata(void) const +{ + if (!GetOverrideEnablePerfdata().IsEmpty()) + return GetOverrideEnablePerfdata(); + else + return GetEnablePerfdataRaw(); +} + +void Service::SetEnablePerfdata(bool enabled, const String& authority) +{ + SetOverrideEnablePerfdata(enabled); +} + int Service::GetModifiedAttributes(void) const { int attrs = 0; @@ -279,6 +292,9 @@ int Service::GetModifiedAttributes(void) const if (!GetOverrideEnableEventHandler().IsEmpty()) attrs |= ModAttrEventHandlerEnabled; + if (!GetOverrideEnablePerfdata().IsEmpty()) + attrs |= ModAttrPerformanceDataEnabled; + if (!GetOverrideCheckInterval().IsEmpty()) attrs |= ModAttrNormalCheckInterval; @@ -307,6 +323,9 @@ void Service::SetModifiedAttributes(int flags) if ((flags & ModAttrEventHandlerEnabled) == 0) SetOverrideEnableEventHandler(Empty); + if ((flags & ModAttrPerformanceDataEnabled) == 0) + SetOverrideEnablePerfdata(Empty); + if ((flags & ModAttrNormalCheckInterval) == 0) SetOverrideCheckInterval(Empty); diff --git a/lib/icinga/service.h b/lib/icinga/service.h index c11e0ea85..458410b83 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -249,6 +249,10 @@ public: bool IsFlapping(void) const; void UpdateFlappingStatus(bool stateChange); + /* Performance data */ + bool GetEnablePerfdata(void) const; + void SetEnablePerfdata(bool enabled, const String& authority = String()); + protected: virtual void Start(void); diff --git a/lib/icinga/service.ti b/lib/icinga/service.ti index 9fadc756b..f3f9c3672 100644 --- a/lib/icinga/service.ti +++ b/lib/icinga/service.ti @@ -74,6 +74,9 @@ class Service : DynamicObject [config] bool enable_flapping (EnableFlappingRaw) { default {{{ return true; }}} }; + [config] bool enable_perfdata (EnablePerfdataRaw) { + default {{{ return true; }}} + }; [state] double next_check (NextCheckRaw); [state] int check_attempt { @@ -125,13 +128,11 @@ class Service : DynamicObject [state] int flapping_positive; [state] int flapping_negative; [state] double flapping_last_change; - [state] bool enable_perfdata { - default {{{ return true; }}} - }; [state] Value override_enable_notifications; [state] Value override_enable_active_checks; [state] Value override_enable_passive_checks; [state] Value override_enable_flapping; + [state] Value override_enable_perfdata; [state] Value override_check_interval; [state] Value override_retry_interval; [state] Value override_enable_event_handler; From b9f9cd03d20baa2fc8394680de3cef9cbb64c2fe Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 26 Nov 2013 12:31:17 +0100 Subject: [PATCH 4/8] Implement override_event_command. Refs #4746 --- lib/icinga/externalcommandprocessor.cpp | 57 ++++++++++++++++++++++++- lib/icinga/externalcommandprocessor.h | 2 + lib/icinga/service-event.cpp | 14 +++++- lib/icinga/service.cpp | 6 +++ lib/icinga/service.h | 2 + lib/icinga/service.ti | 1 + 6 files changed, 79 insertions(+), 3 deletions(-) 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; }; } From 1c8fb7a198e7d37c770e19956ccfd8bdee7c7865 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 26 Nov 2013 12:56:42 +0100 Subject: [PATCH 5/8] Implement override_check_command. Refs #4746 --- lib/icinga/externalcommandprocessor.cpp | 54 ++++++++++++++++++++++++- lib/icinga/externalcommandprocessor.h | 2 + lib/icinga/service-check.cpp | 14 ++++++- lib/icinga/service.cpp | 6 +++ lib/icinga/service.h | 2 + lib/icinga/service.ti | 1 + 6 files changed, 77 insertions(+), 2 deletions(-) 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; }; } From 245dd66babbf2c697ae65c2bb4e39ef16e760e04 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 26 Nov 2013 13:27:41 +0100 Subject: [PATCH 6/8] Implement override_max_check_attempts. Refs #4746 --- lib/icinga/externalcommandprocessor.cpp | 46 +++++++++++++++++++++++++ lib/icinga/externalcommandprocessor.h | 2 ++ lib/icinga/service-check.cpp | 13 +++++++ lib/icinga/service.cpp | 6 ++++ lib/icinga/service.h | 3 ++ lib/icinga/service.ti | 3 +- 6 files changed, 72 insertions(+), 1 deletion(-) diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index 77d5d5b83..197c4553d 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -195,6 +195,8 @@ void ExternalCommandProcessor::Initialize(void) RegisterCommand("CHANGE_SVC_EVENT_HANDLER", &ExternalCommandProcessor::ChangeSvcEventHandler); RegisterCommand("CHANGE_HOST_CHECK_COMMAND", &ExternalCommandProcessor::ChangeHostCheckCommand); RegisterCommand("CHANGE_SVC_CHECK_COMMAND", &ExternalCommandProcessor::ChangeSvcCheckCommand); + RegisterCommand("CHANGE_MAX_HOST_CHECK_ATTEMPTS", &ExternalCommandProcessor::ChangeMaxHostCheckAttempts); + RegisterCommand("CHANGE_MAX_SVC_CHECK_ATTEMPTS", &ExternalCommandProcessor::ChangeMaxSvcCheckAttempts); } void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandProcessor::Callback& callback) @@ -2121,3 +2123,47 @@ void ExternalCommandProcessor::ChangeSvcCheckCommand(double time, const std::vec service->SetCheckCommand(command); } } + +void ExternalCommandProcessor::ChangeMaxHostCheckAttempts(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 max check attempts for non-existent host '" + arguments[0] + "'")); + + Service::Ptr hc = host->GetCheckService(); + + int attempts = Convert::ToLong(arguments[2]); + + Log(LogInformation, "icinga", "Changing max check attempts for host '" + arguments[0] + "' to '" + arguments[1] + "'"); + + { + ObjectLock olock(hc); + + hc->SetMaxCheckAttempts(attempts); + } +} + +void ExternalCommandProcessor::ChangeMaxSvcCheckAttempts(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 max check attempts for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); + + int attempts = Convert::ToLong(arguments[2]); + + Log(LogInformation, "icinga", "Changing max check attempts for service '" + arguments[1] + "' to '" + arguments[2] + "'"); + + { + ObjectLock olock(service); + + service->SetMaxCheckAttempts(attempts); + } +} diff --git a/lib/icinga/externalcommandprocessor.h b/lib/icinga/externalcommandprocessor.h index a8efbf3ef..66bdc6742 100644 --- a/lib/icinga/externalcommandprocessor.h +++ b/lib/icinga/externalcommandprocessor.h @@ -145,6 +145,8 @@ private: 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); + static void ChangeMaxHostCheckAttempts(double time, const std::vector& arguments); + static void ChangeMaxSvcCheckAttempts(double time, const std::vector& arguments); }; } diff --git a/lib/icinga/service-check.cpp b/lib/icinga/service-check.cpp index 2c4e29335..9fce8433a 100644 --- a/lib/icinga/service-check.cpp +++ b/lib/icinga/service-check.cpp @@ -193,6 +193,19 @@ void Service::SetForceNextCheck(bool forced, const String& authority) OnForceNextCheckChanged(GetSelf(), forced, authority); } +int Service::GetMaxCheckAttempts(void) const +{ + if (!GetOverrideMaxCheckAttempts().IsEmpty()) + return GetOverrideMaxCheckAttempts(); + else + return GetMaxCheckAttemptsRaw(); +} + +void Service::SetMaxCheckAttempts(int attempts) +{ + SetOverrideMaxCheckAttempts(attempts); +} + void Service::ProcessCheckResult(const CheckResult::Ptr& cr, const String& authority) { double now = Utility::GetTime(); diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index 82571ada6..a4f5e2909 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -307,6 +307,9 @@ int Service::GetModifiedAttributes(void) const if (!GetOverrideCheckCommand().IsEmpty()) attrs |= ModAttrCheckCommand; + if (!GetOverrideMaxCheckAttempts().IsEmpty()) + attrs |= ModAttrMaxCheckAttempts; + // TODO: finish return attrs; @@ -343,6 +346,9 @@ void Service::SetModifiedAttributes(int flags) if ((flags & ModAttrCheckCommand) == 0) SetOverrideCheckCommand(Empty); + + if ((flags & ModAttrMaxCheckAttempts) == 0) + SetOverrideMaxCheckAttempts(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 4d2374243..36d2f173a 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -119,6 +119,9 @@ public: double GetRetryInterval(void) const; void SetRetryInterval(double interval); + int GetMaxCheckAttempts(void) const; + void SetMaxCheckAttempts(int attempts); + long GetSchedulingOffset(void); void SetSchedulingOffset(long offset); diff --git a/lib/icinga/service.ti b/lib/icinga/service.ti index c59528ac6..4da129a24 100644 --- a/lib/icinga/service.ti +++ b/lib/icinga/service.ti @@ -34,7 +34,7 @@ class Service : DynamicObject [config] Array::Ptr service_dependencies; [config] Array::Ptr groups; [config, protected] String check_command (CheckCommandRaw); - [config] int max_check_attempts { + [config] int max_check_attempts (MaxCheckAttemptsRaw) { default {{{ return 3; }}} }; [config, protected] String check_period (CheckPeriodRaw); @@ -138,6 +138,7 @@ class Service : DynamicObject [state] Value override_enable_event_handler; [state] Value override_event_command; [state] Value override_check_command; + [state] Value override_max_check_attempts; }; } From 6428fc61238a378c9e4acabcd7d4e7e1901f2959 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 26 Nov 2013 13:43:56 +0100 Subject: [PATCH 7/8] Implement override_check_period. Refs #4746 --- lib/icinga/externalcommandprocessor.cpp | 52 +++++++++++++++++++++++++ lib/icinga/externalcommandprocessor.h | 2 + lib/icinga/service-check.cpp | 14 ++++++- lib/icinga/service.cpp | 6 +++ lib/icinga/service.h | 1 + lib/icinga/service.ti | 1 + 6 files changed, 75 insertions(+), 1 deletion(-) diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index 197c4553d..7b3fd46b2 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -197,6 +197,8 @@ void ExternalCommandProcessor::Initialize(void) RegisterCommand("CHANGE_SVC_CHECK_COMMAND", &ExternalCommandProcessor::ChangeSvcCheckCommand); RegisterCommand("CHANGE_MAX_HOST_CHECK_ATTEMPTS", &ExternalCommandProcessor::ChangeMaxHostCheckAttempts); RegisterCommand("CHANGE_MAX_SVC_CHECK_ATTEMPTS", &ExternalCommandProcessor::ChangeMaxSvcCheckAttempts); + RegisterCommand("CHANGE_HOST_CHECK_TIMEPERIOD", &ExternalCommandProcessor::ChangeHostCheckTimeperiod); + RegisterCommand("CHANGE_SVC_CHECK_TIMEPERIOD", &ExternalCommandProcessor::ChangeSvcCheckTimeperiod); } void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandProcessor::Callback& callback) @@ -2167,3 +2169,53 @@ void ExternalCommandProcessor::ChangeMaxSvcCheckAttempts(double time, const std: service->SetMaxCheckAttempts(attempts); } } + +void ExternalCommandProcessor::ChangeHostCheckTimeperiod(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 period for non-existent host '" + arguments[0] + "'")); + + Service::Ptr hc = host->GetCheckService(); + + TimePeriod::Ptr tp = TimePeriod::GetByName(arguments[2]); + + if (!tp) + BOOST_THROW_EXCEPTION(std::invalid_argument("Time period '" + arguments[1] + "' does not exist.")); + + Log(LogInformation, "icinga", "Changing check period for host '" + arguments[0] + "' to '" + arguments[1] + "'"); + + { + ObjectLock olock(hc); + + hc->SetCheckPeriod(tp); + } +} + +void ExternalCommandProcessor::ChangeSvcCheckTimeperiod(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 period for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'")); + + TimePeriod::Ptr tp = TimePeriod::GetByName(arguments[2]); + + if (!tp) + BOOST_THROW_EXCEPTION(std::invalid_argument("Time period '" + arguments[2] + "' does not exist.")); + + Log(LogInformation, "icinga", "Changing check period for service '" + arguments[1] + "' to '" + arguments[2] + "'"); + + { + ObjectLock olock(service); + + service->SetCheckPeriod(tp); + } +} \ No newline at end of file diff --git a/lib/icinga/externalcommandprocessor.h b/lib/icinga/externalcommandprocessor.h index 66bdc6742..371eef800 100644 --- a/lib/icinga/externalcommandprocessor.h +++ b/lib/icinga/externalcommandprocessor.h @@ -147,6 +147,8 @@ private: static void ChangeSvcCheckCommand(double time, const std::vector& arguments); static void ChangeMaxHostCheckAttempts(double time, const std::vector& arguments); static void ChangeMaxSvcCheckAttempts(double time, const std::vector& arguments); + static void ChangeHostCheckTimeperiod(double time, const std::vector& arguments); + static void ChangeSvcCheckTimeperiod(double time, const std::vector& arguments); }; } diff --git a/lib/icinga/service-check.cpp b/lib/icinga/service-check.cpp index 9fce8433a..e2f68b468 100644 --- a/lib/icinga/service-check.cpp +++ b/lib/icinga/service-check.cpp @@ -64,7 +64,19 @@ void Service::SetCheckCommand(const CheckCommand::Ptr& command) TimePeriod::Ptr Service::GetCheckPeriod(void) const { - return TimePeriod::GetByName(GetCheckPeriodRaw()); + String tp; + + if (!GetOverrideCheckPeriod().IsEmpty()) + tp = GetOverrideCheckPeriod(); + else + tp = GetCheckPeriodRaw(); + + return TimePeriod::GetByName(tp); +} + +void Service::SetCheckPeriod(const TimePeriod::Ptr& tp) +{ + SetOverrideCheckPeriod(tp->GetName()); } double Service::GetCheckInterval(void) const diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index a4f5e2909..4c909118b 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -310,6 +310,9 @@ int Service::GetModifiedAttributes(void) const if (!GetOverrideMaxCheckAttempts().IsEmpty()) attrs |= ModAttrMaxCheckAttempts; + if (!GetOverrideCheckPeriod().IsEmpty()) + attrs |= ModAttrCheckTimeperiod; + // TODO: finish return attrs; @@ -349,6 +352,9 @@ void Service::SetModifiedAttributes(int flags) if ((flags & ModAttrMaxCheckAttempts) == 0) SetOverrideMaxCheckAttempts(Empty); + + if ((flags & ModAttrCheckTimeperiod) == 0) + SetOverrideCheckPeriod(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 36d2f173a..1680e2221 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -112,6 +112,7 @@ public: void SetCheckCommand(const shared_ptr& command); TimePeriod::Ptr GetCheckPeriod(void) const; + void SetCheckPeriod(const TimePeriod::Ptr& tp); double GetCheckInterval(void) const; void SetCheckInterval(double interval); diff --git a/lib/icinga/service.ti b/lib/icinga/service.ti index 4da129a24..ee693c706 100644 --- a/lib/icinga/service.ti +++ b/lib/icinga/service.ti @@ -139,6 +139,7 @@ class Service : DynamicObject [state] Value override_event_command; [state] Value override_check_command; [state] Value override_max_check_attempts; + [state] Value override_check_period; }; } From a2d77451ecf708229ff3d3ea80aa2cfed431711a Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 26 Nov 2013 13:55:07 +0100 Subject: [PATCH 8/8] Update documentation. Refs #4746 --- doc/4.3-object-types.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/4.3-object-types.md b/doc/4.3-object-types.md index e980de29a..d2965b92d 100644 --- a/doc/4.3-object-types.md +++ b/doc/4.3-object-types.md @@ -112,9 +112,12 @@ Attributes: check\_period |**Optional.** The name of a time period which determines when this service should be checked. Not set by default. check\_interval |**Optional.** The check interval (in seconds). This interval is used for checks when the service is in a `HARD` state. Defaults to 5 minutes. 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 minute. + enable\_notifications|**Optional.** Whether notifications are enabled. Defaults to true. 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. + enable\_flap\_detection|**Optional.** Whether flap detection is enabled. Defaults to true. + enable\_perfdata|**Optional.** Whether performance data processing is enabled. 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|**Optional.** The flapping threshold in percent when a service is considered to be flapping. volatile |**Optional.** The volatile setting enables always `HARD` state types if `NOT-OK` state changes occur.