]> granicus.if.org Git - icinga2/commitdiff
Add group apply (creates object only once and sets membership).
authorMichael Friedrich <michael.friedrich@netways.de>
Tue, 15 Apr 2014 11:45:44 +0000 (13:45 +0200)
committerMichael Friedrich <michael.friedrich@netways.de>
Tue, 15 Apr 2014 12:55:29 +0000 (14:55 +0200)
Refs #5910

23 files changed:
doc/4.1-configuration-syntax.md
lib/base/scriptutils.cpp
lib/base/scriptutils.h
lib/config/applyrule.cpp
lib/config/applyrule.h
lib/db_ido/endpointdbobject.cpp
lib/db_ido/endpointdbobject.h
lib/icinga/CMakeLists.txt
lib/icinga/dependency-apply.cpp
lib/icinga/hostgroup-apply.cpp [new file with mode: 0644]
lib/icinga/hostgroup.h
lib/icinga/notification-apply.cpp
lib/icinga/scheduleddowntime-apply.cpp
lib/icinga/service-apply.cpp
lib/icinga/servicegroup-apply.cpp [new file with mode: 0644]
lib/icinga/servicegroup.h
lib/icinga/usergroup-apply.cpp [new file with mode: 0644]
lib/icinga/usergroup.h
lib/methods/castfuncs.cpp
lib/methods/castfuncs.h
lib/remote/CMakeLists.txt
lib/remote/i2-remote.h
lib/remote/remote-type.conf

index 0a4bfd6118370d1174bf5cba540bda7d25c4122c..7990ee76a45d31d1649d8ff35434768523a79ffb 100644 (file)
@@ -363,6 +363,7 @@ once they are set.
 
 The `apply` keyword can be used to create new objects which are associated with
 another group of objects.
+Applying group membership for objects can be done in a similar way using [group apply](#group-apply)
 
     apply Service "ping" to Host {
       import "generic-service"
@@ -396,6 +397,35 @@ Any valid config attribute can be accessed using the `host` and `service`
 variables. For example, `host.address` would return the value of the host's
 "address" attribute - or null if that attribute isn't set.
 
+#### <a id="group-membership-apply"></a> Group Membership Apply
+
+The `apply` keyword can be used for groups too. Instead of creating a new object
+(for example a new `HostGroup` object for every matching `Host`) it will create
+the group object only once and add the membership for the matching rule object.
+
+    apply HostGroup "www" to Host {
+      display_name = "Web Server"
+
+      assign where match("*www*", host.name)
+    }
+
+In this example the `assign where` condition is a boolean expression which is
+evaluated for all object of type `Host`. A new host group with name "www" is created
+and each matching host is added to this host group.
+
+Depending on the group object type used in the `apply` expression additional local
+variables may be available for use in the `where` condition:
+
+Source Type       | Target Type | Variables
+------------------|-------------|--------------
+HostGroup         | Host        | host
+ServiceGroup      | Service     | host, service
+UserGroup         | User        | user
+
+Any valid config attribute can be accessed using the `host`, `service` and `user`
+variables. For example, `user.vars.sla` would return the value of the user's custom
+attribute "sla" - or null if that attribute isn't set.
+
 ### <a id="boolean-values"></a> Boolean Values
 
 The `assign where` and `ignore where` statements, the `!`, `&&` and `||`
index 4eaacff9a00d39cc8e8d9fc1beaafd1887e14d8f..6cefd1d5cbdd75886557fd6eb8cc02dbe3ebea51 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index 904706ea1b58bdc3a0a41993ea5a0c5655a235c0..2e753560ada8e092e3562b5720cadedf8d76e407 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index 87a250cc3fdb0437fce373469d42bafe8aa9bd22..a9eba3026bbf6b152932d7495aab52b107e499af 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index 10b4970c62aefc5d30ed6f5986e1dfbe6c313dde..cdbe4bb3b3df683ac874479d490a4bddb9f6dd3e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index 94a0c881498f3a3343884602b70e7ed5fcde1d77..b95e1d177356ffba7323d2af7f8f2f504e290402 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index fa1982f26fa9266e92a91dd96c7e5006b09b65ed..7a69c548b2994c70678a65c225fd01e5e0698069 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index 590ae474a0268d4820c5a865f5e01b4c227126ff..acd043454d329ab8ccae4c6d9387717891b169c4 100644 (file)
@@ -41,19 +41,25 @@ mkclass_target(user.ti user.th)
 mkembedconfig_target(icinga-type.conf icinga-type.cpp)
 
 add_library(icinga SHARED
-  api.cpp checkable.cpp checkable.th checkable-dependency.cpp checkable-downtime.cpp checkable-event.cpp
-  checkable-flapping.cpp checkcommand.cpp checkcommand.th checkresult.cpp checkresult.th
-  cib.cpp command.cpp command.th comment.cpp comment.th compatutility.cpp dependency.cpp dependency.th
-  dependency-apply.cpp domain.cpp domain.th downtime.cpp downtime.th eventcommand.cpp eventcommand.th
-  externalcommandprocessor.cpp host.cpp host.th hostgroup.cpp hostgroup.th
-  icingaapplication.cpp icingaapplication.th icingastatuswriter.cpp
-  icingastatuswriter.th legacytimeperiod.cpp
-  macroprocessor.cpp macroresolver.cpp notificationcommand.cpp notificationcommand.th
-  notification.cpp notification.th notification-apply.cpp perfdatavalue.cpp perfdatavalue.th
-  pluginutility.cpp scheduleddowntime.cpp scheduleddowntime.th scheduleddowntime-apply.cpp
-  service-apply.cpp checkable-check.cpp checkable-comment.cpp service.cpp service.th
-  servicegroup.cpp servicegroup.th checkable-notification.cpp timeperiod.cpp timeperiod.th user.cpp user.th
-  usergroup.cpp usergroup.th icinga-type.cpp
+  api.cpp
+  checkable.cpp checkable.th
+  checkable-check.cpp checkable-comment.cpp checkable-dependency.cpp checkable-downtime.cpp
+  checkable-event.cpp checkable-flapping.cpp checkable-notification.cpp
+  checkcommand.cpp checkcommand.th checkresult.cpp checkresult.th
+  cib.cpp command.cpp command.th comment.cpp comment.th compatutility.cpp
+  dependency.cpp dependency.th dependency-apply.cpp domain.cpp domain.th downtime.cpp downtime.th
+  eventcommand.cpp eventcommand.th externalcommandprocessor.cpp
+  host.cpp host.th hostgroup.cpp hostgroup.th hostgroup-apply.cpp
+  icingaapplication.cpp icingaapplication.th icingastatuswriter.cpp icingastatuswriter.th
+  legacytimeperiod.cpp
+  macroprocessor.cpp macroresolver.cpp
+  notificationcommand.cpp notificationcommand.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.cpp service.th servicegroup.cpp servicegroup.th servicegroup-apply.cpp
+  timeperiod.cpp timeperiod.th
+  user.cpp user.th usergroup.cpp usergroup.th usergroup-apply.cpp
+  icinga-type.cpp
 )
 
 target_link_libraries(icinga ${Boost_LIBRARIES} base config)
index d00700225350b278ed5e851639aef5075c542345..feb111926c9de581f316872999f27b1486cc93bb 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
diff --git a/lib/icinga/hostgroup-apply.cpp b/lib/icinga/hostgroup-apply.cpp
new file mode 100644 (file)
index 0000000..2371a35
--- /dev/null
@@ -0,0 +1,122 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012-2014 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/hostgroup.h"
+#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 <boost/foreach.hpp>
+
+using namespace icinga;
+
+INITIALIZE_ONCE(&HostGroup::RegisterApplyRuleHandler);
+
+void HostGroup::RegisterApplyRuleHandler(void)
+{
+       std::vector<String> targets;
+       targets.push_back("Host");
+       ApplyRule::RegisterType("HostGroup", targets, &HostGroup::EvaluateApplyRules);
+}
+
+bool HostGroup::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
+{
+       DebugInfo di = rule.GetDebugInfo();
+
+       std::ostringstream msgbuf;
+       msgbuf << "Evaluating 'apply' rule (" << di << ")";
+       CONTEXT(msgbuf.str());
+
+       Host::Ptr host;
+       Service::Ptr service;
+       tie(host, service) = GetHostService(checkable);
+
+       Dictionary::Ptr locals = make_shared<Dictionary>();
+       locals->Set("host", host);
+       if (service)
+               locals->Set("service", service);
+
+       if (!rule.EvaluateFilter(locals))
+               return false;
+
+       std::ostringstream msgbuf2;
+       msgbuf2 << "Applying hostgroup '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
+       Log(LogDebug, "icinga", msgbuf2.str());
+
+
+       String group_name = rule.GetName();
+
+       ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
+       builder->SetType("HostGroup");
+       builder->SetName(group_name);
+       builder->SetScope(rule.GetScope());
+
+       builder->AddExpression(rule.GetExpression());
+
+       HostGroup::Ptr group = HostGroup::GetByName(group_name);
+
+       /* if group does not exist, create it only once */
+       if (!group) {
+               ConfigItem::Ptr hostgroupItem = builder->Compile();
+               hostgroupItem->Register();
+               DynamicObject::Ptr dobj = hostgroupItem->Commit();
+
+               group = dynamic_pointer_cast<HostGroup>(dobj);
+
+               if (!group) {
+                       Log(LogCritical, "icinga", "Unable to create group '" + group_name + "' for apply rule.");
+                       return false;
+               }
+
+               Log(LogDebug, "icinga", "Group '" + group_name + "' created for apply rule.");
+       } else
+               Log(LogDebug, "icinga", "Group '" + group_name + "' already exists. Skipping apply rule creation.");
+
+       /* assign host group membership */
+       group->AddMember(host);
+
+       return true;
+}
+
+void HostGroup::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
+{
+       int apply_count = 0;
+
+       BOOST_FOREACH(const ApplyRule& rule, rules) {
+               if (rule.GetTargetType() == "Host") {
+                       apply_count = 0;
+
+                       BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjects<Host>()) {
+                               CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
+
+                               if (EvaluateApplyRule(host, rule))
+                                       apply_count++;
+                       }
+
+                       if (apply_count == 0)
+                               Log(LogWarning, "icinga", "Apply rule '" + rule.GetName() + "' for host does not match anywhere!");
+
+               } else {
+                       Log(LogWarning, "icinga", "Wrong target type for apply rule '" + rule.GetName() + "'!");
+               }
+       }
+}
index c0187c7dbd43bad04ec764476b50e94bd161a31a..7294e469a4f4392e58d94665b0172e37040450ca 100644 (file)
@@ -23,6 +23,7 @@
 #include "icinga/i2-icinga.h"
 #include "icinga/hostgroup.th"
 #include "icinga/host.h"
+#include "config/applyrule.h"
 
 namespace icinga
 {
@@ -44,9 +45,14 @@ public:
 
         bool ResolveGroupMembership(Host::Ptr const& host, bool add = true, int rstack = 0);
 
+        static void RegisterApplyRuleHandler(void);
+
 private:
        mutable boost::mutex m_HostGroupMutex;
        std::set<Host::Ptr> m_Members;
+
+       static bool EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule);
+       static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
 };
 
 }
index ad501818a03944d727403478da84b9d9e1000e1a..8037cc72c5cebdabc2d8dd9703aba673af878c3b 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index 29442b72f5228808d8227df17cfe5c81984f2919..1142d5652d1565bb19a32e0d28a536e2de0d9b3a 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index 889ea66dc61c1a6cdc0ce2d86fb3ae4b18ef6cd6..bf6a93036b4e2dcd0d42c66ff98f4d5aef94c8bc 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
diff --git a/lib/icinga/servicegroup-apply.cpp b/lib/icinga/servicegroup-apply.cpp
new file mode 100644 (file)
index 0000000..d561055
--- /dev/null
@@ -0,0 +1,124 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012-2014 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/servicegroup.h"
+#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 <boost/foreach.hpp>
+
+using namespace icinga;
+
+INITIALIZE_ONCE(&ServiceGroup::RegisterApplyRuleHandler);
+
+void ServiceGroup::RegisterApplyRuleHandler(void)
+{
+       std::vector<String> targets;
+       targets.push_back("Service");
+       ApplyRule::RegisterType("ServiceGroup", targets, &ServiceGroup::EvaluateApplyRules);
+}
+
+bool ServiceGroup::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
+{
+       DebugInfo di = rule.GetDebugInfo();
+
+       std::ostringstream msgbuf;
+       msgbuf << "Evaluating 'apply' rule (" << di << ")";
+       CONTEXT(msgbuf.str());
+
+       Host::Ptr host;
+       Service::Ptr service;
+       tie(host, service) = GetHostService(checkable);
+
+       Dictionary::Ptr locals = make_shared<Dictionary>();
+       locals->Set("host", host);
+       if (service)
+               locals->Set("service", service);
+       else
+               return false;
+
+       if (!rule.EvaluateFilter(locals))
+               return false;
+
+       std::ostringstream msgbuf2;
+       msgbuf2 << "Applying hostgroup '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
+       Log(LogDebug, "icinga", msgbuf2.str());
+
+
+       String group_name = rule.GetName();
+
+       ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
+       builder->SetType("ServiceGroup");
+       builder->SetName(group_name);
+       builder->SetScope(rule.GetScope());
+
+       builder->AddExpression(rule.GetExpression());
+
+       ServiceGroup::Ptr group = ServiceGroup::GetByName(group_name);
+
+       /* if group does not exist, create it only once */
+       if (!group) {
+               ConfigItem::Ptr servicegroupItem = builder->Compile();
+               servicegroupItem->Register();
+               DynamicObject::Ptr dobj = servicegroupItem->Commit();
+
+               group = dynamic_pointer_cast<ServiceGroup>(dobj);
+
+               if (!group) {
+                       Log(LogCritical, "icinga", "Unable to create ServiceGroup '" + group_name + "' for apply rule.");
+                       return false;
+               }
+
+               Log(LogDebug, "icinga", "ServiceGroup '" + group_name + "' created for apply rule.");
+       } else
+               Log(LogDebug, "icinga", "ServiceGroup '" + group_name + "' already exists. Skipping apply rule creation.");
+
+       /* assign service group membership */
+       group->AddMember(service);
+
+       return true;
+}
+
+void ServiceGroup::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
+{
+       int apply_count = 0;
+
+       BOOST_FOREACH(const ApplyRule& rule, rules) {
+               if (rule.GetTargetType() == "Service") {
+                       apply_count = 0;
+
+                       BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects<Service>()) {
+                               CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'");
+
+                               if(EvaluateApplyRule(service, rule))
+                                       apply_count++;
+                       }
+
+                       if (apply_count == 0)
+                               Log(LogWarning, "icinga", "Apply rule '" + rule.GetName() + "' for service does not match anywhere!");
+
+               } else {
+                       Log(LogWarning, "icinga", "Wrong target type for apply rule '" + rule.GetName() + "'!");
+               }
+       }
+}
index 7e93ea5eb420875e5bee4623840b0b7200c8c9dd..32c2123e2369dd42921c29ed36b7917d8a168288 100644 (file)
@@ -23,6 +23,7 @@
 #include "icinga/i2-icinga.h"
 #include "icinga/servicegroup.th"
 #include "icinga/service.h"
+#include "config/applyrule.h"
 
 namespace icinga
 {
@@ -44,9 +45,14 @@ public:
 
         bool ResolveGroupMembership(Service::Ptr const& service, bool add = true, int rstack = 0);
 
+        static void RegisterApplyRuleHandler(void);
+
 private:
        mutable boost::mutex m_ServiceGroupMutex;
        std::set<Service::Ptr> m_Members;
+
+       static bool EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule);
+       static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
 };
 
 }
diff --git a/lib/icinga/usergroup-apply.cpp b/lib/icinga/usergroup-apply.cpp
new file mode 100644 (file)
index 0000000..66d4ede
--- /dev/null
@@ -0,0 +1,116 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012-2014 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/hostgroup.h"
+#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 <boost/foreach.hpp>
+
+using namespace icinga;
+
+INITIALIZE_ONCE(&UserGroup::RegisterApplyRuleHandler);
+
+void UserGroup::RegisterApplyRuleHandler(void)
+{
+       std::vector<String> targets;
+       targets.push_back("User");
+       ApplyRule::RegisterType("UserGroup", targets, &UserGroup::EvaluateApplyRules);
+}
+
+bool UserGroup::EvaluateApplyRule(const User::Ptr& user, const ApplyRule& rule)
+{
+       DebugInfo di = rule.GetDebugInfo();
+
+       std::ostringstream msgbuf;
+       msgbuf << "Evaluating 'apply' rule (" << di << ")";
+       CONTEXT(msgbuf.str());
+
+       Dictionary::Ptr locals = make_shared<Dictionary>();
+       locals->Set("user", user);
+
+       if (!rule.EvaluateFilter(locals))
+               return false;
+
+       std::ostringstream msgbuf2;
+       msgbuf2 << "Applying usergroup '" << rule.GetName() << "' to object '" << user->GetName() << "' for rule " << di;
+       Log(LogDebug, "icinga", msgbuf2.str());
+
+
+       String group_name = rule.GetName();
+
+       ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
+       builder->SetType("UserGroup");
+       builder->SetName(group_name);
+       builder->SetScope(rule.GetScope());
+
+       builder->AddExpression(rule.GetExpression());
+
+       UserGroup::Ptr group = UserGroup::GetByName(group_name);
+
+       /* if group does not exist, create it only once */
+       if (!group) {
+               ConfigItem::Ptr usergroupItem = builder->Compile();
+               usergroupItem->Register();
+               DynamicObject::Ptr dobj = usergroupItem->Commit();
+
+               group = dynamic_pointer_cast<UserGroup>(dobj);
+
+               if (!group) {
+                       Log(LogCritical, "icinga", "Unable to create UserGroup '" + group_name + "' for apply rule.");
+                       return false;
+               }
+
+               Log(LogDebug, "icinga", "UserGroup '" + group_name + "' created for apply rule.");
+       } else
+               Log(LogDebug, "icinga", "UserGroup '" + group_name + "' already exists. Skipping apply rule creation.");
+
+       /* assign user group membership */
+       group->AddMember(user);
+
+       return true;
+}
+
+void UserGroup::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
+{
+       int apply_count = 0;
+
+       BOOST_FOREACH(const ApplyRule& rule, rules) {
+               if (rule.GetTargetType() == "User") {
+                       apply_count = 0;
+
+                       BOOST_FOREACH(const User::Ptr& user, DynamicType::GetObjects<User>()) {
+                               CONTEXT("Evaluating 'apply' rules for User '" + user->GetName() + "'");
+
+                               if(EvaluateApplyRule(user, rule))
+                                       apply_count++;
+                       }
+
+                       if (apply_count == 0)
+                               Log(LogWarning, "icinga", "Apply rule '" + rule.GetName() + "' for user does not match anywhere!");
+
+               } else {
+                       Log(LogWarning, "icinga", "Wrong target type for apply rule '" + rule.GetName() + "'!");
+               }
+       }
+}
index 3338c6cda64074e24da4aa1b059deafb228791c1..1c4968315bae354a3c42ce5dbbdd848b73ee7051 100644 (file)
@@ -23,6 +23,7 @@
 #include "icinga/i2-icinga.h"
 #include "icinga/usergroup.th"
 #include "icinga/user.h"
+#include "config/applyrule.h"
 
 namespace icinga
 {
@@ -44,9 +45,14 @@ public:
 
         bool ResolveGroupMembership(User::Ptr const& user, bool add = true, int rstack = 0);
 
+        static void RegisterApplyRuleHandler(void);
+
 private:
        mutable boost::mutex m_UserGroupMutex;
        std::set<User::Ptr> m_Members;
+
+       static bool EvaluateApplyRule(const User::Ptr& user, const ApplyRule& rule);
+       static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
 };
 
 }
index 4b35b2f536b5b3cc7a7954128b54dc206cf8a3ad..c4c7a7aa1deab11db878d1e140933fa01e2ab709 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index 7d314bba9feccbe6fd11c51f2d5d73d4e3baa693..cd3ea4c9d82c5894f5fd6e2b3577f13c1d8799ee 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index c96631bd5fafe00d8a493500c4dffe8a7e5e641c..367fdfb92764a08d6cdc6da44ca2b14c4ad70085 100644 (file)
@@ -1,5 +1,5 @@
 # Icinga 2
-# Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org)
+# Copyright (C) 2012-2014 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
index d2e884f35c0cca88d7595286bc6896e1f395f40d..045d89476b628edc92a0e57909ed5280903790ba 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *
index f12945825ebbd84d47612a5a9b4a244dbd6d0b3f..e007068c1cb4f63430d1c142146d57f2906d073e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  * Icinga 2                                                                   *
- * Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
+ * Copyright (C) 2012-2014 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                *