From 9862ab5324defde1e54a24507399513e0a9187af Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 31 Jan 2013 13:57:14 +0100 Subject: [PATCH] Implement triggered downtime for services. Fixes #3583 --- components/compat/compatcomponent.cpp | 9 ++-- lib/icinga/downtimeprocessor.cpp | 60 ++++++++++++++++++++++++--- lib/icinga/downtimeprocessor.h | 3 ++ lib/icinga/service.cpp | 3 ++ 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/components/compat/compatcomponent.cpp b/components/compat/compatcomponent.cpp index 70e1dfb7f..75f93e468 100644 --- a/components/compat/compatcomponent.cpp +++ b/components/compat/compatcomponent.cpp @@ -231,13 +231,10 @@ void CompatComponent::DumpDowntimes(ofstream& fp, const DynamicObject::Ptr& owne fp << "servicedowntime {" << "\n" << "\t" << "service_description=" << service->GetAlias() << "\n"; - String triggeredBy = downtime->Get("triggered_by"); + Dictionary::Ptr triggeredByObj = DowntimeProcessor::GetDowntimeByID(downtime->Get("triggered_by")); int triggeredByLegacy = 0; - if (!triggeredBy.IsEmpty()) { - Dictionary::Ptr triggeredByObj = DowntimeProcessor::GetDowntimeByID(triggeredBy); - if (triggeredByObj->Contains("legacy_id")) - triggeredByLegacy = triggeredByObj->Get("legacy_id"); - } + if (triggeredByObj) + triggeredByLegacy = triggeredByObj->Get("legacy_id"); fp << "\t" << "host_name=" << host->GetName() << "\n" << "\t" << "downtime_id=" << static_cast(downtime->Get("legacy_id")) << "\n" diff --git a/lib/icinga/downtimeprocessor.cpp b/lib/icinga/downtimeprocessor.cpp index 17b293990..d21a44fc7 100644 --- a/lib/icinga/downtimeprocessor.cpp +++ b/lib/icinga/downtimeprocessor.cpp @@ -46,9 +46,19 @@ String DowntimeProcessor::AddDowntime(const DynamicObject::Ptr& owner, downtime->Set("fixed", fixed); downtime->Set("duration", duration); downtime->Set("triggered_by", triggeredBy); + downtime->Set("triggers", boost::make_shared()); downtime->Set("trigger_time", 0); downtime->Set("legacy_id", m_NextDowntimeID++); + if (!triggeredBy.IsEmpty()) { + DynamicObject::Ptr otherOwner = GetOwnerByDowntimeID(triggeredBy); + Dictionary::Ptr otherDowntimes = otherOwner->Get("downtimes"); + Dictionary::Ptr otherDowntime = otherDowntimes->Get(triggeredBy); + Dictionary::Ptr triggers = otherDowntime->Get("triggers"); + triggers->Set(triggeredBy, triggeredBy); + otherOwner->Touch("downtimes"); + } + Dictionary::Ptr downtimes = owner->Get("downtimes"); if (!downtimes) @@ -65,20 +75,60 @@ void DowntimeProcessor::RemoveDowntime(const String& id) { DynamicObject::Ptr owner = GetOwnerByDowntimeID(id); + if (!owner) + return; + Dictionary::Ptr downtimes = owner->Get("downtimes"); - if (downtimes) { - downtimes->Remove(id); - owner->Touch("downtimes"); + if (!downtimes) + return; + + downtimes->Remove(id); + owner->Touch("downtimes"); +} + +void DowntimeProcessor::TriggerDowntimes(const DynamicObject::Ptr& owner) +{ + Dictionary::Ptr downtimes = owner->Get("downtimes"); + + if (!downtimes) + return; + + String id; + BOOST_FOREACH(tie(id, tuples::ignore), downtimes) { + TriggerDowntime(id); } } +void DowntimeProcessor::TriggerDowntime(const String& id) +{ + DynamicObject::Ptr owner = GetOwnerByDowntimeID(id); + Dictionary::Ptr downtime = GetDowntimeByID(id); + + double now = Utility::GetTime(); + + if (now < downtime->Get("start_time") || + now > downtime->Get("end_time")) + return; + + if (downtime->Get("trigger_time") == 0) + downtime->Set("trigger_time", now); + + Dictionary::Ptr triggers = downtime->Get("triggers"); + String tid; + BOOST_FOREACH(tie(tid, tuples::ignore), triggers) { + TriggerDowntime(tid); + } + + owner->Touch("downtimes"); +} + String DowntimeProcessor::GetIDFromLegacyID(int id) { map::iterator it = m_LegacyDowntimeCache.find(id); if (it == m_LegacyDowntimeCache.end()) - throw_exception(invalid_argument("Invalid legacy downtime ID specified.")); + return Empty; return it->second; } @@ -95,7 +145,7 @@ Dictionary::Ptr DowntimeProcessor::GetDowntimeByID(const String& id) DynamicObject::Ptr owner = GetOwnerByDowntimeID(id); if (!owner) - throw_exception(invalid_argument("Downtime ID does not exist.")); + return Dictionary::Ptr(); Dictionary::Ptr downtimes = owner->Get("downtimes"); diff --git a/lib/icinga/downtimeprocessor.h b/lib/icinga/downtimeprocessor.h index db8913d1b..731d3aa5b 100644 --- a/lib/icinga/downtimeprocessor.h +++ b/lib/icinga/downtimeprocessor.h @@ -40,6 +40,9 @@ public: static void RemoveDowntime(const String& id); + static void TriggerDowntimes(const DynamicObject::Ptr& owner); + static void TriggerDowntime(const String& id); + static String GetIDFromLegacyID(int id); static DynamicObject::Ptr GetOwnerByDowntimeID(const String& id); static Dictionary::Ptr GetDowntimeByID(const String& id); diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index b9848bbd0..7d314d931 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -564,6 +564,9 @@ void Service::ApplyCheckResult(const Dictionary::Ptr& cr) } } } + + if (GetState() != StateOK) + DowntimeProcessor::TriggerDowntimes(GetSelf()); } ServiceState Service::StateFromString(const String& state)