From 33ae12d08499ced08f2990da6420fd4599f19980 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Fri, 28 Mar 2014 22:58:05 +0100 Subject: [PATCH] Implement apply support for scheduled downtimes and notifications. Refs #5880 --- lib/config/applyrule.cpp | 1 + lib/icinga/CMakeLists.txt | 8 +-- lib/icinga/notification-apply.cpp | 80 ++++++++++++++++++++++++++ lib/icinga/notification.h | 4 ++ lib/icinga/scheduleddowntime-apply.cpp | 80 ++++++++++++++++++++++++++ lib/icinga/scheduleddowntime.h | 4 ++ 6 files changed, 173 insertions(+), 4 deletions(-) create mode 100644 lib/icinga/notification-apply.cpp create mode 100644 lib/icinga/scheduleddowntime-apply.cpp diff --git a/lib/config/applyrule.cpp b/lib/config/applyrule.cpp index 8556108c8..fc959107f 100644 --- a/lib/config/applyrule.cpp +++ b/lib/config/applyrule.cpp @@ -69,6 +69,7 @@ bool ApplyRule::EvaluateFilter(const Dictionary::Ptr& scope) const void ApplyRule::EvaluateRules(void) { + // TODO: priority std::pair > kv; BOOST_FOREACH(kv, m_Callbacks) { RuleMap::const_iterator it = m_Rules.find(kv.first); diff --git a/lib/icinga/CMakeLists.txt b/lib/icinga/CMakeLists.txt index ca0607913..5242952b7 100644 --- a/lib/icinga/CMakeLists.txt +++ b/lib/icinga/CMakeLists.txt @@ -47,10 +47,10 @@ add_library(icinga SHARED icingaapplication.cpp icingaapplication.th icingastatuswriter.cpp icingastatuswriter.th legacytimeperiod.cpp macroprocessor.cpp macroresolver.cpp notificationcommand.cpp notificationcommand.th - notification.cpp notification.th perfdatavalue.cpp perfdatavalue.th - pluginutility.cpp scheduleddowntime.cpp scheduleddowntime.th service-apply.cpp service-check.cpp - service-comment.cpp service.cpp service-dependency.cpp service-downtime.cpp service-event.cpp - service-flapping.cpp service.th servicegroup.cpp servicegroup.th + notification.cpp notification.th notification-apply.cpp perfdatavalue.cpp perfdatavalue.th + pluginutility.cpp scheduleddowntime.cpp scheduleddowntime.th scheduleddowntime-apply.cpp + service-apply.cpp service-check.cpp service-comment.cpp service.cpp service-dependency.cpp + service-downtime.cpp service-event.cpp service-flapping.cpp service.th servicegroup.cpp servicegroup.th service-notification.cpp timeperiod.cpp timeperiod.th user.cpp user.th usergroup.cpp usergroup.th icinga-type.cpp ) diff --git a/lib/icinga/notification-apply.cpp b/lib/icinga/notification-apply.cpp new file mode 100644 index 000000000..b5390bebe --- /dev/null +++ b/lib/icinga/notification-apply.cpp @@ -0,0 +1,80 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "icinga/service.h" +#include "config/configitembuilder.h" +#include "base/initialize.h" +#include "base/dynamictype.h" +#include "base/convert.h" +#include "base/logger_fwd.h" +#include "base/context.h" +#include + +using namespace icinga; + +INITIALIZE_ONCE(&Notification::RegisterApplyRuleHandler); + +void Notification::RegisterApplyRuleHandler(void) +{ + ApplyRule::RegisterType("Notification", &Notification::EvaluateApplyRules, 2); +} + +void Notification::EvaluateApplyRules(const std::vector& rules) +{ + BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects()) { + CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'"); + + Dictionary::Ptr locals = make_shared(); + locals->Set("host", service->GetHost()); + locals->Set("service", service); + + BOOST_FOREACH(const ApplyRule& rule, rules) { + DebugInfo di = rule.GetDebugInfo(); + + std::ostringstream msgbuf; + msgbuf << "Evaluating 'apply' rule (" << di << ")"; + CONTEXT(msgbuf.str()); + + if (!rule.EvaluateFilter(locals)) + continue; + + std::ostringstream msgbuf2; + msgbuf2 << "Applying notification '" << rule.GetName() << "' to service '" << service->GetName() << "' for rule " << di; + Log(LogDebug, "icinga", msgbuf2.str()); + + std::ostringstream namebuf; + namebuf << service->GetName() << "!" << rule.GetName(); + String name = namebuf.str(); + + ConfigItemBuilder::Ptr builder = make_shared(di); + builder->SetType("Notification"); + builder->SetName(name); + builder->SetScope(rule.GetScope()); + + builder->AddExpression(make_shared(&AExpression::OpSet, "host", make_shared(&AExpression::OpLiteral, service->GetHost()->GetName(), di), di)); + builder->AddExpression(make_shared(&AExpression::OpSet, "service", make_shared(&AExpression::OpLiteral, service->GetShortName(), di), di)); + builder->AddExpression(rule.GetExpression()); + + ConfigItem::Ptr serviceItem = builder->Compile(); + serviceItem->Register(); + DynamicObject::Ptr dobj = serviceItem->Commit(); + dobj->OnConfigLoaded(); + } + } +} diff --git a/lib/icinga/notification.h b/lib/icinga/notification.h index 6348aa428..559501bdc 100644 --- a/lib/icinga/notification.h +++ b/lib/icinga/notification.h @@ -25,6 +25,7 @@ #include "icinga/user.h" #include "icinga/usergroup.h" #include "icinga/timeperiod.h" +#include "config/applyrule.h" #include "base/array.h" namespace icinga @@ -86,6 +87,9 @@ public: static boost::signals2::signal OnNextNotificationChanged; + static void RegisterApplyRuleHandler(void); + static void EvaluateApplyRules(const std::vector& rules); + protected: virtual void Start(void); virtual void Stop(void); diff --git a/lib/icinga/scheduleddowntime-apply.cpp b/lib/icinga/scheduleddowntime-apply.cpp new file mode 100644 index 000000000..f7ad097ef --- /dev/null +++ b/lib/icinga/scheduleddowntime-apply.cpp @@ -0,0 +1,80 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "icinga/scheduleddowntime.h" +#include "config/configitembuilder.h" +#include "base/initialize.h" +#include "base/dynamictype.h" +#include "base/convert.h" +#include "base/logger_fwd.h" +#include "base/context.h" +#include + +using namespace icinga; + +INITIALIZE_ONCE(&ScheduledDowntime::RegisterApplyRuleHandler); + +void ScheduledDowntime::RegisterApplyRuleHandler(void) +{ + ApplyRule::RegisterType("ScheduledDowntime", &ScheduledDowntime::EvaluateApplyRules, 2); +} + +void ScheduledDowntime::EvaluateApplyRules(const std::vector& rules) +{ + BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects()) { + CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'"); + + Dictionary::Ptr locals = make_shared(); + locals->Set("host", service->GetHost()); + locals->Set("service", service); + + BOOST_FOREACH(const ApplyRule& rule, rules) { + DebugInfo di = rule.GetDebugInfo(); + + std::ostringstream msgbuf; + msgbuf << "Evaluating 'apply' rule (" << di << ")"; + CONTEXT(msgbuf.str()); + + if (!rule.EvaluateFilter(locals)) + continue; + + std::ostringstream msgbuf2; + msgbuf2 << "Applying scheduled downtime '" << rule.GetName() << "' to service '" << service->GetName() << "' for rule " << di; + Log(LogDebug, "icinga", msgbuf2.str()); + + std::ostringstream namebuf; + namebuf << service->GetName() << "!" << rule.GetName(); + String name = namebuf.str(); + + ConfigItemBuilder::Ptr builder = make_shared(di); + builder->SetType("ScheduledDowntime"); + builder->SetName(name); + builder->SetScope(rule.GetScope()); + + builder->AddExpression(make_shared(&AExpression::OpSet, "host", make_shared(&AExpression::OpLiteral, service->GetHost()->GetName(), di), di)); + builder->AddExpression(make_shared(&AExpression::OpSet, "service", make_shared(&AExpression::OpLiteral, service->GetShortName(), di), di)); + builder->AddExpression(rule.GetExpression()); + + ConfigItem::Ptr serviceItem = builder->Compile(); + serviceItem->Register(); + DynamicObject::Ptr dobj = serviceItem->Commit(); + dobj->OnConfigLoaded(); + } + } +} diff --git a/lib/icinga/scheduleddowntime.h b/lib/icinga/scheduleddowntime.h index 5db94c296..75e634268 100644 --- a/lib/icinga/scheduleddowntime.h +++ b/lib/icinga/scheduleddowntime.h @@ -23,6 +23,7 @@ #include "icinga/i2-icinga.h" #include "icinga/scheduleddowntime.th" #include "icinga/service.h" +#include "config/applyrule.h" #include namespace icinga @@ -43,6 +44,9 @@ public: Service::Ptr GetService(void) const; + static void RegisterApplyRuleHandler(void); + static void EvaluateApplyRules(const std::vector& rules); + protected: virtual void Start(void);