]> granicus.if.org Git - icinga2/commitdiff
Implement notification conditions.
authorGunnar Beutner <gunnar.beutner@netways.de>
Wed, 26 Jun 2013 07:08:50 +0000 (09:08 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Wed, 26 Jun 2013 07:08:50 +0000 (09:08 +0200)
Fixes #2841

icinga-app/icinga.cpp
lib/base/scriptvariable.cpp
lib/icinga/icinga-type.conf
lib/icinga/notification.cpp
lib/icinga/notification.h
lib/icinga/user.cpp
lib/icinga/user.h

index 94e7fed28e70394c66258c1a6477fc7bfe6da345..18a91afacdddb8611868854e28aa5a0229fceea7 100644 (file)
@@ -52,15 +52,15 @@ static bool LoadConfigFiles(bool validateOnly)
 
        ConfigCompilerContext::SetContext(&context);
 
-       BOOST_FOREACH(const String& configPath, g_AppParams["config"].as<std::vector<String> >()) {
-               ConfigCompiler::CompileFile(configPath);
-       }
-
        String name, fragment;
        BOOST_FOREACH(boost::tie(name, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) {
                ConfigCompiler::CompileText(name, fragment);
        }
 
+       BOOST_FOREACH(const String& configPath, g_AppParams["config"].as<std::vector<String> >()) {
+               ConfigCompiler::CompileFile(configPath);
+       }
+
        ConfigCompilerContext::SetContext(NULL);
 
        bool hasError = false;
index 149ad60a5352532a39e0d5c8548ac4827a47f076..6c93513b4c16d018b3efd68f973ca67468e60bd0 100644 (file)
@@ -18,6 +18,7 @@
  ******************************************************************************/
 
 #include "base/scriptvariable.h"
+#include "base/logger_fwd.h"
 
 using namespace icinga;
 
@@ -25,7 +26,11 @@ Registry<String> ScriptVariable::m_Registry;
 
 Value ScriptVariable::Get(const String& name)
 {
-       return m_Registry.GetItem(name);
+       Value value = m_Registry.GetItem(name);
+       if (value.IsEmpty())
+               Log(LogWarning, "icinga", "Tried to access empty variable: " + name);
+
+       return value;
 }
 
 void ScriptVariable::Set(const String& name, const Value& value)
index 37179d2129d9b532cddfdfe28613105b57de0056..bac85be1bacc54d576fabda2e3e62fbd59142ef1 100644 (file)
@@ -231,6 +231,8 @@ type Service {
                                %attribute number "end",
                        },
 
+                       %attribute number "type_filter",
+                       %attribute number "state_filter"
                }
        }
 }
@@ -241,6 +243,44 @@ type ServiceGroup {
        %attribute string "action_url"
 }
 
+set StateOK = (0)
+set StateWarning = (1)
+set StateCritical = (2)
+set StateUnknown = (3)
+set StateUncheckable = (4)
+
+/*
+ * Converting states to their filter values: 1<<state
+ */
+set StateFilterOK = (1<<StateOK)
+set StateFilterWarning = (1<<StateWarning)
+set StateFilterCritical = (1<<StateCritical)
+set StateFilterUnknown = (1<<StateUnknown)
+set StateFilterUncheckable = (1<<StateUncheckable)
+
+set NotificationDowntimeStart = (0)
+set NotificationDowntimeEnd = (1)
+set NotificationDowntimeRemoved = (2)
+set NotificationCustom = (3)
+set NotificationAcknowledgement = (4)
+set NotificationProblem = (5)
+set NotificationRecovery = (6)
+set NotificationFlappingStart = (7)
+set NotificationFlappingEnd = (8)
+
+/*
+ * Converting notification types to their filter values: 1<<type
+ */
+set NotificationFilterDowntimeStart = (1<<NotificationDowntimeStart)
+set NotificationFilterDowntimeEnd = (1<<NotificationDowntimeEnd)
+set NotificationFilterDowntimeRemoved = (1<<NotificationDowntimeRemoved)
+set NotificationFilterCustom = (1<<NotificationCustom)
+set NotificationFilterAcknowledgement = (1<<NotificationAcknowledgement)
+set NotificationFilterProblem = (1<<NotificationProblem)
+set NotificationFilterRecovery = (1<<NotificationRecovery)
+set NotificationFilterFlappingStart = (1<<NotificationFlappingStart)
+set NotificationFilterFlappingEnd = (1<<NotificationFlappingEnd)
+
 type Notification {
        %require "host_name",
        %attribute string "host_name",
@@ -265,7 +305,10 @@ type Notification {
        %attribute name(NotificationCommand) "notification_command",
 
        %attribute number "notification_interval",
-       %attribute name(TimePeriod) "notification_period"
+       %attribute name(TimePeriod) "notification_period",
+
+       %attribute number "type_filter",
+       %attribute number "state_filter"
 }
 
 type User {
@@ -277,7 +320,11 @@ type User {
 
        %attribute array "groups" {
                %attribute name(UserGroup) "*"
-       }
+       },
+
+       %attribute number "type_filter",
+       %attribute number "state_filter"
+
 }
 
 type UserGroup {
index b0dcbb6dcb5e955662e83351d28de1c990eb5890..9329e98c87d9449b827bb0571c12a13c9b7206cf 100644 (file)
@@ -25,6 +25,7 @@
 #include "base/objectlock.h"
 #include "base/logger_fwd.h"
 #include "base/utility.h"
+#include "base/convert.h"
 #include <boost/tuple/tuple.hpp>
 #include <boost/foreach.hpp>
 #include <boost/exception/diagnostic_information.hpp>
@@ -45,6 +46,8 @@ Notification::Notification(const Dictionary::Ptr& serializedUpdate)
        RegisterAttribute("users", Attribute_Config, &m_Users);
        RegisterAttribute("groups", Attribute_Config, &m_Groups);
        RegisterAttribute("times", Attribute_Config, &m_Times);
+       RegisterAttribute("type_filter", Attribute_Config, &m_TypeFilter);
+       RegisterAttribute("state_filter", Attribute_Config, &m_StateFilter);
        RegisterAttribute("host_name", Attribute_Config, &m_HostName);
        RegisterAttribute("service", Attribute_Config, &m_Service);
        RegisterAttribute("export_macros", Attribute_Config, &m_ExportMacros);
@@ -139,6 +142,22 @@ Dictionary::Ptr Notification::GetTimes(void) const
        return m_Times;
 }
 
+unsigned long Notification::GetTypeFilter(void) const
+{
+       if (m_TypeFilter.IsEmpty())
+               return ~(unsigned long)0; /* All states. */
+       else
+               return m_TypeFilter;
+}
+
+unsigned long Notification::GetStateFilter(void) const
+{
+       if (m_StateFilter.IsEmpty())
+               return ~(unsigned long)0; /* All states. */
+       else
+               return m_StateFilter;
+}
+
 double Notification::GetNotificationInterval(void) const
 {
        if (m_NotificationInterval.IsEmpty())
@@ -238,6 +257,24 @@ void Notification::BeginExecuteNotification(NotificationType type, const Diction
                        Log(LogInformation, "icinga", "Not sending notifications for notification object '" + GetName() + "': after escalation range");
                        return;
                }
+
+               unsigned long ftype = 1 << type;
+
+               Log(LogDebug, "icinga", "FType=" + Convert::ToString(ftype) + ", TypeFilter=" + Convert::ToString(GetTypeFilter()));
+
+               if (!(ftype & GetTypeFilter())) {
+                       Log(LogInformation, "icinga", "Not sending notifications for notification object '" + GetName() + "': type filter does not match");
+                       return;
+               }
+
+               unsigned long fstate = 1 << GetService()->GetState();
+
+               Log(LogDebug, "icinga", "FState=" + Convert::ToString(fstate) + ", StateFilter=" + Convert::ToString(GetStateFilter()));
+
+               if (!(fstate & GetStateFilter())) {
+                       Log(LogInformation, "icinga", "Not sending notifications for notification object '" + GetName() + "': state filter does not match");
+                       return;
+               }
        }
 
        {
@@ -262,11 +299,11 @@ void Notification::BeginExecuteNotification(NotificationType type, const Diction
        }
 }
 
-void Notification::ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const Dictionary::Ptr& cr, bool ignore_timeperiod)
+void Notification::ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const Dictionary::Ptr& cr, bool force)
 {
        ASSERT(!OwnsLock());
 
-       if (!ignore_timeperiod) {
+       if (!force) {
                TimePeriod::Ptr tp = user->GetNotificationPeriod();
 
                if (tp && !tp->IsInside(Utility::GetTime())) {
@@ -274,6 +311,22 @@ void Notification::ExecuteNotificationHelper(NotificationType type, const User::
                            GetName() + " and user '" + user->GetName() + "': user not in timeperiod");
                        return;
                }
+
+               unsigned long ftype = 1 << type;
+
+               if (!(ftype & user->GetTypeFilter())) {
+                       Log(LogInformation, "icinga", "Not sending notifications for notification object '" +
+                           GetName() + " and user '" + user->GetName() + "': type filter does not match");
+                       return;
+               }
+
+               unsigned long fstate = 1 << GetService()->GetState();
+
+               if (!(fstate & user->GetStateFilter())) {
+                       Log(LogInformation, "icinga", "Not sending notifications for notification object '" +
+                           GetName() + " and user '" + user->GetName() + "': state filter does not match");
+                       return;
+               }
        }
 
        try {
index 95024a0d614bb29b9fc7fb3da92ab071c927da47..6fa736253f5eca32e3a5724169c463c7f8de1976 100644 (file)
@@ -36,15 +36,15 @@ namespace icinga
  */
 enum NotificationType
 {
-       NotificationDowntimeStart,
-       NotificationDowntimeEnd,
-       NotificationDowntimeRemoved,
-       NotificationCustom,
-       NotificationAcknowledgement,
-       NotificationProblem,
-       NotificationRecovery,
-       NotificationFlappingStart,
-       NotificationFlappingEnd,
+       NotificationDowntimeStart = 0,
+       NotificationDowntimeEnd = 1,
+       NotificationDowntimeRemoved = 2,
+       NotificationCustom = 3,
+       NotificationAcknowledgement = 4,
+       NotificationProblem = 5,
+       NotificationRecovery = 6,
+       NotificationFlappingStart = 7 ,
+       NotificationFlappingEnd = 8,
 };
 
 class Service;
@@ -75,6 +75,8 @@ public:
        std::set<User::Ptr> GetUsers(void) const;
        std::set<UserGroup::Ptr> GetGroups(void) const;
        Dictionary::Ptr GetTimes(void) const;
+       unsigned long GetTypeFilter(void) const;
+       unsigned long GetStateFilter(void) const;
 
        double GetLastNotification(void) const;
        void SetLastNotification(double time);
@@ -102,6 +104,8 @@ private:
        Attribute<Array::Ptr> m_Users;
        Attribute<Array::Ptr> m_Groups;
        Attribute<Dictionary::Ptr> m_Times;
+       Attribute<long> m_TypeFilter;
+       Attribute<long> m_StateFilter;
        Attribute<String> m_HostName;
        Attribute<String> m_Service;
 
index c0cabb492ecc72710192f85d637a9118b7f2a858..2b740963a17cca995049bb5ecf42f8ee0c311717 100644 (file)
@@ -34,6 +34,8 @@ User::User(const Dictionary::Ptr& serializedUpdate)
        RegisterAttribute("macros", Attribute_Config, &m_Macros);
        RegisterAttribute("groups", Attribute_Config, &m_Groups);
        RegisterAttribute("notification_period", Attribute_Config, &m_NotificationPeriod);
+       RegisterAttribute("type_filter", Attribute_Config, &m_TypeFilter);
+       RegisterAttribute("state_filter", Attribute_Config, &m_StateFilter);
 }
 
 User::~User(void)
@@ -79,6 +81,22 @@ TimePeriod::Ptr User::GetNotificationPeriod(void) const
        return TimePeriod::GetByName(m_NotificationPeriod);
 }
 
+unsigned long User::GetTypeFilter(void) const
+{
+       if (m_TypeFilter.IsEmpty())
+               return ~(unsigned long)0; /* All states. */
+       else
+               return m_TypeFilter;
+}
+
+unsigned long User::GetStateFilter(void) const
+{
+       if (m_StateFilter.IsEmpty())
+               return ~(unsigned long)0; /* All states. */
+       else
+               return m_StateFilter;
+}
+
 bool User::ResolveMacro(const String& macro, const Dictionary::Ptr& cr, String *result) const
 {
        if (macro == "CONTACTNAME") {
index f8f89a649e9f8849bb091e9254df4f8ead63ebf0..855a8ecdc21bb049ff0e8adeebcd6953ab149f4c 100644 (file)
@@ -48,6 +48,8 @@ public:
        String GetDisplayName(void) const;
        Array::Ptr GetGroups(void) const;
        TimePeriod::Ptr GetNotificationPeriod(void) const;
+       unsigned long GetTypeFilter(void) const;
+       unsigned long GetStateFilter(void) const;
 
        Dictionary::Ptr GetMacros(void) const;
 
@@ -61,6 +63,8 @@ private:
        Attribute<Dictionary::Ptr> m_Macros;
        Attribute<String> m_NotificationPeriod;
        Attribute<Array::Ptr> m_Groups;
+       Attribute<long> m_TypeFilter;
+       Attribute<long> m_StateFilter;
 };
 
 }