From 905380b4368eb6ce8b1140a733591820f1b5d36b Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 4 Aug 2016 10:12:55 +0200 Subject: [PATCH] Fix duplicate notifications on HA failover fixes #12267 --- lib/icinga/clusterevents.cpp | 12 +++++++++++- lib/icinga/notification.cpp | 8 ++++++-- lib/remote/apilistener.cpp | 11 +++++++++++ lib/remote/apilistener.hpp | 2 ++ lib/remote/zone.cpp | 6 ++++++ lib/remote/zone.hpp | 1 + 6 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lib/icinga/clusterevents.cpp b/lib/icinga/clusterevents.cpp index 7d5a86713..95cb5db7d 100644 --- a/lib/icinga/clusterevents.cpp +++ b/lib/icinga/clusterevents.cpp @@ -240,6 +240,11 @@ Value ClusterEvents::NextCheckChangedAPIHandler(const MessageOrigin::Ptr& origin return Empty; } + double nextCheck = params->Get("next_check"); + + if (nextCheck < Application::GetStartTime() + 60) + return Empty; + checkable->SetNextCheck(params->Get("next_check"), false, origin); return Empty; @@ -288,7 +293,12 @@ Value ClusterEvents::NextNotificationChangedAPIHandler(const MessageOrigin::Ptr& return Empty; } - notification->SetNextNotification(params->Get("next_notification"), false, origin); + double nextNotification = params->Get("next_notification"); + + if (nextNotification < Utility::GetTime()) + return Empty; + + notification->SetNextNotification(nextNotification, false, origin); return Empty; } diff --git a/lib/icinga/notification.cpp b/lib/icinga/notification.cpp index 41a6cf45f..885c6fd45 100644 --- a/lib/icinga/notification.cpp +++ b/lib/icinga/notification.cpp @@ -21,6 +21,7 @@ #include "icinga/notification.tcpp" #include "icinga/notificationcommand.hpp" #include "icinga/service.hpp" +#include "remote/apilistener.hpp" #include "base/objectlock.hpp" #include "base/logger.hpp" #include "base/utility.hpp" @@ -144,12 +145,15 @@ void Notification::OnAllConfigLoaded(void) void Notification::Start(bool runtimeCreated) { - ObjectImpl::Start(runtimeCreated); - Checkable::Ptr obj = GetCheckable(); if (obj) obj->RegisterNotification(this); + + if (ApiListener::IsHACluster() && GetNextNotification() < Utility::GetTime() + 60) + SetNextNotification(Utility::GetTime() + 60, true); + + ObjectImpl::Start(runtimeCreated); } void Notification::Stop(bool runtimeRemoved) diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index 3d967eff0..007cfb9a8 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -1190,3 +1190,14 @@ void ApiListener::ValidateTlsProtocolmin(const String& value, const ValidationUt "Must be one of '" SSL_TXT_TLSV1 "', '" SSL_TXT_TLSV1_1 "' or '" SSL_TXT_TLSV1_2 "'")); } } + +bool ApiListener::IsHACluster(void) +{ + Zone::Ptr zone = Zone::GetLocalZone(); + + if (!zone) + return false; + + return zone->IsSingleInstance(); +} + diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index 4c1771361..49a57e181 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -100,6 +100,8 @@ public: static void UpdateObjectAuthority(void); + static bool IsHACluster(void); + protected: virtual void OnConfigLoaded(void) override; virtual void OnAllConfigLoaded(void) override; diff --git a/lib/remote/zone.cpp b/lib/remote/zone.cpp index ded60f621..31286b859 100644 --- a/lib/remote/zone.cpp +++ b/lib/remote/zone.cpp @@ -112,6 +112,12 @@ bool Zone::IsGlobal(void) const return GetGlobal(); } +bool Zone::IsSingleInstance(void) const +{ + Array::Ptr endpoints = GetEndpointsRaw(); + return !endpoints || endpoints->GetLength() < 2; +} + Zone::Ptr Zone::GetLocalZone(void) { Endpoint::Ptr local = Endpoint::GetLocalEndpoint(); diff --git a/lib/remote/zone.hpp b/lib/remote/zone.hpp index c633d4967..76ed4c0cc 100644 --- a/lib/remote/zone.hpp +++ b/lib/remote/zone.hpp @@ -45,6 +45,7 @@ public: bool CanAccessObject(const ConfigObject::Ptr& object); bool IsChildOf(const Zone::Ptr& zone); bool IsGlobal(void) const; + bool IsSingleInstance(void) const; static Zone::Ptr GetLocalZone(void);