diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index 7a2b4834b..41532ac83 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -1104,11 +1104,19 @@ void ExternalCommandProcessor::SendCustomHostNotification(double, const std::vec BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 4 arguments.")); Host::Ptr host = Host::GetByName(arguments[0]); + int options = Convert::ToLong(arguments[1]); Log(LogInformation, "icinga", "Sending custom notification for host " + host->GetName()); Service::Ptr service = host->GetHostCheckService(); - if (service) + if (service) { + if (options & 2) { + ObjectLock olock(service); + service->SetForceNextNotification(true); + service->Flush(); + } + service->RequestNotifications(NotificationCustom, service->GetLastCheckResult()); + } } void ExternalCommandProcessor::SendCustomSvcNotification(double, const std::vector& arguments) @@ -1117,8 +1125,16 @@ void ExternalCommandProcessor::SendCustomSvcNotification(double, const std::vect BOOST_THROW_EXCEPTION(std::invalid_argument("Expected 5 arguments.")); Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); + int options = Convert::ToLong(arguments[2]); Log(LogInformation, "icinga", "Sending custom notification for service " + service->GetName()); + + if (options & 2) { + ObjectLock olock(service); + service->SetForceNextNotification(true); + service->Flush(); + } + service->RequestNotifications(NotificationCustom, service->GetLastCheckResult()); } diff --git a/lib/icinga/service-notification.cpp b/lib/icinga/service-notification.cpp index 8c169def2..2da027df4 100644 --- a/lib/icinga/service-notification.cpp +++ b/lib/icinga/service-notification.cpp @@ -61,8 +61,12 @@ void Service::RequestNotifications(NotificationType type, const Dictionary::Ptr& void Service::SendNotifications(NotificationType type, const Dictionary::Ptr& cr) { if (!GetEnableNotifications()) { - Log(LogInformation, "icinga", "Notifications are disabled for service '" + GetName() + "'."); - return; + if (!GetForceNextNotification()) { + Log(LogInformation, "icinga", "Notifications are disabled for service '" + GetName() + "'."); + return; + } + + SetForceNextNotification(false); } Log(LogInformation, "icinga", "Sending notifications for service '" + GetName() + "'"); @@ -309,3 +313,23 @@ void Service::SetEnableNotifications(bool enabled) m_EnableNotifications = enabled; Touch("enable_notifications"); } + +/** + * @threadsafety Always. + */ +bool Service::GetForceNextNotification(void) const +{ + if (m_ForceNextNotification.IsEmpty()) + return false; + + return static_cast(m_ForceNextNotification); +} + +/** + * @threadsafety Always. + */ +void Service::SetForceNextNotification(bool forced) +{ + m_ForceNextNotification = forced ? 1 : 0; + Touch("force_next_notification"); +} diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index c1cf433d5..d32a26883 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -75,6 +75,7 @@ Service::Service(const Dictionary::Ptr& serializedObject) RegisterAttribute("downtimes", Attribute_Replicated, &m_Downtimes); RegisterAttribute("enable_notifications", Attribute_Replicated, &m_EnableNotifications); + RegisterAttribute("force_next_notification", Attribute_Replicated, &m_ForceNextNotification); SetSchedulingOffset(rand()); } diff --git a/lib/icinga/service.h b/lib/icinga/service.h index 028d58cb5..d71cc84d1 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -233,6 +233,9 @@ public: std::set GetNotifications(void) const; + void SetForceNextNotification(bool force); + bool GetForceNextNotification(void) const; + static void InvalidateNotificationsCache(void); void UpdateSlaveNotifications(void); @@ -305,6 +308,7 @@ private: /* Notifications */ Attribute m_EnableNotifications; + Attribute m_ForceNextNotification; static void RefreshNotificationsCache(void); };