From 7a147d268e9d8fe5b9766ab7a02605fc4ec63905 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Wed, 23 Apr 2014 12:44:36 +0200 Subject: [PATCH] Add group assign/ignore rules. Fixes #5910 --- doc/4.1-configuration-syntax.md | 23 ++++++ etc/icinga2/conf.d/generic-host.conf | 24 +----- etc/icinga2/conf.d/generic-service.conf | 1 - etc/icinga2/conf.d/groups.conf | 28 ++++++- etc/icinga2/conf.d/hosts/localhost.conf | 4 +- lib/config/CMakeLists.txt | 2 +- lib/config/aexpression.cpp | 4 + lib/config/config_parser.yy | 26 ++++++- lib/config/configitem.cpp | 4 + lib/config/objectrule.cpp | 99 +++++++++++++++++++++++++ lib/config/objectrule.h | 72 ++++++++++++++++++ lib/icinga/hostgroup.cpp | 51 +++++++++++++ lib/icinga/hostgroup.h | 6 ++ lib/icinga/servicegroup.cpp | 54 ++++++++++++++ lib/icinga/servicegroup.h | 6 ++ lib/icinga/usergroup.cpp | 51 +++++++++++++ lib/icinga/usergroup.h | 6 ++ 17 files changed, 434 insertions(+), 27 deletions(-) create mode 100644 lib/config/objectrule.cpp create mode 100644 lib/config/objectrule.h diff --git a/doc/4.1-configuration-syntax.md b/doc/4.1-configuration-syntax.md index 0a4bfd611..b6a541e64 100644 --- a/doc/4.1-configuration-syntax.md +++ b/doc/4.1-configuration-syntax.md @@ -396,6 +396,29 @@ 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. +### Group Assign + +Group objects can be assigned to specific member objects using the `assign where` +and `ignore where` conditions. + + object HostGroup "linux-servers" { + display_name = "Linux Servers" + + assign where host.vars.os == "linux" + } + +In this example the `assign where` condition is a boolean expression which is evaluated +for all objects of the type `Host`. Each matching host is added as member to the host group +with the name "linux-servers". Membership exclusion can be controlled using the `ignore where` +condition. + +Source Type | Variables +------------------|-------------- +HostGroup | host +ServiceGroup | host, service +UserGroup | user + + ### Boolean Values The `assign where` and `ignore where` statements, the `!`, `&&` and `||` diff --git a/etc/icinga2/conf.d/generic-host.conf b/etc/icinga2/conf.d/generic-host.conf index cd61eff9f..f0740b636 100644 --- a/etc/icinga2/conf.d/generic-host.conf +++ b/etc/icinga2/conf.d/generic-host.conf @@ -3,6 +3,10 @@ * all hosts should import this template. */ template Host "generic-host" { + max_check_attempts = 5 + check_interval = 5m + retry_interval = 1m + check_command = "hostalive" } @@ -31,23 +35,3 @@ apply Notification "mail-icingaadmin" to Host { assign where "generic-host" in host.templates } - -template Host "linux-server" { - import "generic-host" - - groups += [ "linux-servers" ] -} - -template Host "windows-server" { - import "generic-host" - - groups += [ "windows-servers" ] -} - -template Host "generic-printer" { - import "generic-host" -} - -template Host "generic-switch" { - import "generic-host" -} diff --git a/etc/icinga2/conf.d/generic-service.conf b/etc/icinga2/conf.d/generic-service.conf index 3912ab8f3..332216b1a 100644 --- a/etc/icinga2/conf.d/generic-service.conf +++ b/etc/icinga2/conf.d/generic-service.conf @@ -6,7 +6,6 @@ template Service "generic-service" { max_check_attempts = 3 check_interval = 5m retry_interval = 1m - enable_perfdata = true } apply Notification "mail-icingaadmin" to Service { diff --git a/etc/icinga2/conf.d/groups.conf b/etc/icinga2/conf.d/groups.conf index 9bdc96256..94618eac9 100644 --- a/etc/icinga2/conf.d/groups.conf +++ b/etc/icinga2/conf.d/groups.conf @@ -1,11 +1,37 @@ /** - * Host and service group examples. + * Host group examples. */ object HostGroup "linux-servers" { display_name = "Linux Servers" + + assign where host.vars.os == "Linux" } object HostGroup "windows-servers" { display_name = "Windows Servers" + + assign where host.vars.os == "Windows" +} + +/** + * Service group examples. + */ + +object ServiceGroup "ping" { + display_name = "Ping Checks" + + assign where match("ping*", service.name) +} + +object ServiceGroup "http" { + display_name = "HTTP Checks" + + assign where match("http_*", service.check_command) +} + +object ServiceGroup "disk" { + display_name = "Disk Checks" + + assign where service.check_command == "disk" } diff --git a/etc/icinga2/conf.d/hosts/localhost.conf b/etc/icinga2/conf.d/hosts/localhost.conf index 49e192606..7005d9ccf 100644 --- a/etc/icinga2/conf.d/hosts/localhost.conf +++ b/etc/icinga2/conf.d/hosts/localhost.conf @@ -4,8 +4,10 @@ * files in this directory are included. */ object Host "localhost" { - import "linux-server" + import "generic-host" address = "127.0.0.1" address6 = "::1" + + vars.os = "Linux" } diff --git a/lib/config/CMakeLists.txt b/lib/config/CMakeLists.txt index 05f9990b0..30dafd5a2 100644 --- a/lib/config/CMakeLists.txt +++ b/lib/config/CMakeLists.txt @@ -30,7 +30,7 @@ add_library(config SHARED aexpression.cpp applyrule.cpp base-type.conf base-type.cpp configcompilercontext.cpp configcompiler.cpp configerror.cpp configitembuilder.cpp configitem.cpp ${FLEX_config_lexer_OUTPUTS} ${BISON_config_parser_OUTPUTS} - configtype.cpp debuginfo.cpp typerule.cpp typerulelist.cpp + configtype.cpp debuginfo.cpp objectrule.cpp typerule.cpp typerulelist.cpp ) target_link_libraries(config ${Boost_LIBRARIES} base) diff --git a/lib/config/aexpression.cpp b/lib/config/aexpression.cpp index d557e2290..81ba0290f 100644 --- a/lib/config/aexpression.cpp +++ b/lib/config/aexpression.cpp @@ -22,6 +22,7 @@ #include "config/configitem.h" #include "config/configitembuilder.h" #include "config/applyrule.h" +#include "config/objectrule.h" #include "base/array.h" #include "base/serializer.h" #include "base/context.h" @@ -521,6 +522,7 @@ Value AExpression::OpObject(const AExpression* expr, const Dictionary::Ptr& loca bool abstract = left->Get(0); String type = left->Get(1); AExpression::Ptr aname = left->Get(2); + AExpression::Ptr filter = left->Get(3); String name = aname->Evaluate(locals); @@ -560,5 +562,7 @@ Value AExpression::OpObject(const AExpression* expr, const Dictionary::Ptr& loca item->SetScope(locals); item->Compile()->Register(); + ObjectRule::AddRule(type, name, exprl, filter, expr->m_DebugInfo, locals); + return Empty; } diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index fe3e01eda..841105eb7 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -29,6 +29,7 @@ #include "config/typerulelist.h" #include "config/aexpression.h" #include "config/applyrule.h" +#include "config/objectrule.h" #include "base/value.h" #include "base/utility.h" #include "base/array.h" @@ -214,6 +215,7 @@ static ConfigType::Ptr m_Type; static Dictionary::Ptr m_ModuleScope; static bool m_Apply; +static bool m_ObjectAssign; static bool m_SeenAssign; static AExpression::Ptr m_Assign; static AExpression::Ptr m_Ignore; @@ -426,14 +428,21 @@ type: T_TYPE_DICTIONARY object: { m_Abstract = false; + m_ObjectAssign = true; + m_SeenAssign = false; + m_Assign = make_shared(&AExpression::OpLiteral, false, DebugInfo()); + m_Ignore = make_shared(&AExpression::OpLiteral, false, DebugInfo()); } object_declaration identifier rterm rterm_scope sep { + m_ObjectAssign = false; + Array::Ptr args = make_shared(); args->Add(m_Abstract); - args->Add($3); + String type = $3; + args->Add(type); free($3); args->Add(*$4); @@ -443,7 +452,18 @@ object: delete $5; exprl->MakeInline(); + if (m_SeenAssign && !ObjectRule::IsValidSourceType(type)) + BOOST_THROW_EXCEPTION(ConfigError("object rule 'assign' cannot be used for type '" + type + "'") << errinfo_debuginfo(DebugInfoRange(@2, @3))); + + AExpression::Ptr rex = make_shared(&AExpression::OpLogicalNegate, m_Ignore, DebugInfoRange(@2, @5)); + AExpression::Ptr filter = make_shared(&AExpression::OpLogicalAnd, m_Assign, rex, DebugInfoRange(@2, @5)); + + args->Add(filter); + $$ = new Value(make_shared(&AExpression::OpObject, args, exprl, DebugInfoRange(@2, @5))); + + m_Assign.reset(); + m_Ignore.reset(); } ; @@ -573,7 +593,7 @@ lterm: identifier lbinary_op rterm } | T_ASSIGN T_WHERE rterm { - if (!m_Apply) + if (!(m_Apply || m_ObjectAssign)) BOOST_THROW_EXCEPTION(ConfigError("'assign' keyword not valid in this context.")); m_SeenAssign = true; @@ -585,7 +605,7 @@ lterm: identifier lbinary_op rterm } | T_IGNORE T_WHERE rterm { - if (!m_Apply) + if (!(m_Apply || m_ObjectAssign)) BOOST_THROW_EXCEPTION(ConfigError("'ignore' keyword not valid in this context.")); m_Ignore = make_shared(&AExpression::OpLogicalOr, m_Ignore, *$3, DebugInfoRange(@1, @3)); diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 9b976383c..c1fb97e72 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -20,6 +20,7 @@ #include "config/configitem.h" #include "config/configcompilercontext.h" #include "config/applyrule.h" +#include "config/objectrule.h" #include "base/application.h" #include "base/dynamictype.h" #include "base/objectlock.h" @@ -324,6 +325,9 @@ bool ConfigItem::ActivateItems(ValidationType validate) Log(LogInformation, "config", "Evaluating 'apply' rules..."); ApplyRule::EvaluateRules(); + Log(LogInformation, "config", "Evaluating 'object' rules..."); + ObjectRule::EvaluateRules(); + if (validate != ValidateNone) { Log(LogInformation, "config", "Validating config items (step 2)..."); diff --git a/lib/config/objectrule.cpp b/lib/config/objectrule.cpp new file mode 100644 index 000000000..5c580e89d --- /dev/null +++ b/lib/config/objectrule.cpp @@ -0,0 +1,99 @@ +/****************************************************************************** + * 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 "config/objectrule.h" +#include "base/logger_fwd.h" + +using namespace icinga; + +ObjectRule::RuleMap ObjectRule::m_Rules; +ObjectRule::CallbackMap ObjectRule::m_Callbacks; + +ObjectRule::ObjectRule(const String& name, const AExpression::Ptr& expression, + const AExpression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope) + : m_Name(name), m_Expression(expression), m_Filter(filter), m_DebugInfo(di), m_Scope(scope) +{ } + +String ObjectRule::GetName(void) const +{ + return m_Name; +} + +AExpression::Ptr ObjectRule::GetExpression(void) const +{ + return m_Expression; +} + +AExpression::Ptr ObjectRule::GetFilter(void) const +{ + return m_Filter; +} + +DebugInfo ObjectRule::GetDebugInfo(void) const +{ + return m_DebugInfo; +} + +Dictionary::Ptr ObjectRule::GetScope(void) const +{ + return m_Scope; +} + +void ObjectRule::AddRule(const String& sourceType, const String& name, + const AExpression::Ptr& expression, const AExpression::Ptr& filter, + const DebugInfo& di, const Dictionary::Ptr& scope) +{ + m_Rules[sourceType].push_back(ObjectRule(name, expression, filter, di, scope)); +} + +bool ObjectRule::EvaluateFilter(const Dictionary::Ptr& scope) const +{ + scope->Set("__parent", m_Scope); + bool result = m_Filter->Evaluate(scope); + scope->Remove("__parent"); + return result; +} + +void ObjectRule::EvaluateRules(void) +{ + std::pair kv; + BOOST_FOREACH(kv, m_Callbacks) { + const Callback& callback = kv.second; + + RuleMap::const_iterator it = m_Rules.find(kv.first); + + if (it == m_Rules.end()) + continue; + + callback(it->second); + } + + m_Rules.clear(); +} + +void ObjectRule::RegisterType(const String& sourceType, const ObjectRule::Callback& callback) +{ + m_Callbacks[sourceType] = callback; +} + +bool ObjectRule::IsValidSourceType(const String& sourceType) +{ + return m_Callbacks.find(sourceType) != m_Callbacks.end(); +} + diff --git a/lib/config/objectrule.h b/lib/config/objectrule.h new file mode 100644 index 000000000..c0c9a3650 --- /dev/null +++ b/lib/config/objectrule.h @@ -0,0 +1,72 @@ +/****************************************************************************** + * 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. * + ******************************************************************************/ + +#ifndef OBJECTRULE_H +#define OBJECTRULE_H + +#include "config/i2-config.h" +#include "config/aexpression.h" +#include "config/debuginfo.h" +#include "base/dynamictype.h" + +namespace icinga +{ + +/** + * @ingroup config + */ +class I2_CONFIG_API ObjectRule +{ +public: + typedef boost::function& rules)> Callback; + typedef std::map CallbackMap; + typedef std::map > RuleMap; + + String GetName(void) const; + AExpression::Ptr GetExpression(void) const; + AExpression::Ptr GetFilter(void) const; + DebugInfo GetDebugInfo(void) const; + Dictionary::Ptr GetScope(void) const; + + bool EvaluateFilter(const Dictionary::Ptr& scope) const; + + static void AddRule(const String& sourceType, const String& name, const AExpression::Ptr& expression, + const AExpression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope); + static void EvaluateRules(void); + + static void RegisterType(const String& sourceType, const ObjectRule::Callback& callback); + static bool IsValidSourceType(const String& sourceType); + +private: + String m_Name; + AExpression::Ptr m_Expression; + AExpression::Ptr m_Filter; + DebugInfo m_DebugInfo; + Dictionary::Ptr m_Scope; + + static CallbackMap m_Callbacks; + static RuleMap m_Rules; + + ObjectRule(const String& name, const AExpression::Ptr& expression, + const AExpression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope); +}; + +} + +#endif /* OBJECTRULE_H */ diff --git a/lib/icinga/hostgroup.cpp b/lib/icinga/hostgroup.cpp index d24e18dab..cc6d2ac6e 100644 --- a/lib/icinga/hostgroup.cpp +++ b/lib/icinga/hostgroup.cpp @@ -23,12 +23,63 @@ #include "base/objectlock.h" #include "base/utility.h" #include "base/timer.h" +#include "base/context.h" #include using namespace icinga; REGISTER_TYPE(HostGroup); +INITIALIZE_ONCE(&HostGroup::RegisterObjectRuleHandler); + +void HostGroup::RegisterObjectRuleHandler(void) +{ + ObjectRule::RegisterType("HostGroup", &HostGroup::EvaluateObjectRules); +} + +bool HostGroup::EvaluateObjectRule(const Host::Ptr host, const ObjectRule& rule) +{ + DebugInfo di = rule.GetDebugInfo(); + + std::ostringstream msgbuf; + msgbuf << "Evaluating 'object' rule (" << di << ")"; + CONTEXT(msgbuf.str()); + + Dictionary::Ptr locals = make_shared(); + locals->Set("host", host); + + if (!rule.EvaluateFilter(locals)) + return false; + + std::ostringstream msgbuf2; + msgbuf2 << "Assigning membership for group '" << rule.GetName() << "' to host '" << host->GetName() << "' for rule " << di; + Log(LogDebug, "icinga", msgbuf2.str()); + + String group_name = rule.GetName(); + HostGroup::Ptr group = HostGroup::GetByName(group_name); + + if (!group) { + Log(LogCritical, "icinga", "Invalid membership assignment. Group '" + group_name + "' does not exist."); + return false; + } + + /* assign host group membership */ + group->ResolveGroupMembership(host, true); + + return true; +} + +void HostGroup::EvaluateObjectRules(const std::vector& rules) +{ + BOOST_FOREACH(const ObjectRule& rule, rules) { + BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjects()) { + CONTEXT("Evaluating group membership in '" + rule.GetName() + "' for host '" + host->GetName() + "'"); + + EvaluateObjectRule(host, rule); + } + } +} + std::set HostGroup::GetMembers(void) const { boost::mutex::scoped_lock lock(m_HostGroupMutex); diff --git a/lib/icinga/hostgroup.h b/lib/icinga/hostgroup.h index c0187c7db..0ce0cbeea 100644 --- a/lib/icinga/hostgroup.h +++ b/lib/icinga/hostgroup.h @@ -23,6 +23,7 @@ #include "icinga/i2-icinga.h" #include "icinga/hostgroup.th" #include "icinga/host.h" +#include "config/objectrule.h" namespace icinga { @@ -44,9 +45,14 @@ public: bool ResolveGroupMembership(Host::Ptr const& host, bool add = true, int rstack = 0); + static void RegisterObjectRuleHandler(void); + private: mutable boost::mutex m_HostGroupMutex; std::set m_Members; + + static bool EvaluateObjectRule(const Host::Ptr host, const ObjectRule& rule); + static void EvaluateObjectRules(const std::vector& rules); }; } diff --git a/lib/icinga/servicegroup.cpp b/lib/icinga/servicegroup.cpp index 9cf1b4042..09f82cc43 100644 --- a/lib/icinga/servicegroup.cpp +++ b/lib/icinga/servicegroup.cpp @@ -24,12 +24,66 @@ #include "base/logger_fwd.h" #include "base/timer.h" #include "base/utility.h" +#include "base/context.h" #include using namespace icinga; REGISTER_TYPE(ServiceGroup); +INITIALIZE_ONCE(&ServiceGroup::RegisterObjectRuleHandler); + +void ServiceGroup::RegisterObjectRuleHandler(void) +{ + ObjectRule::RegisterType("ServiceGroup", &ServiceGroup::EvaluateObjectRules); +} + +bool ServiceGroup::EvaluateObjectRule(const Service::Ptr service, const ObjectRule& rule) +{ + DebugInfo di = rule.GetDebugInfo(); + + std::ostringstream msgbuf; + msgbuf << "Evaluating 'object' rule (" << di << ")"; + CONTEXT(msgbuf.str()); + + Host::Ptr host = service->GetHost(); + + Dictionary::Ptr locals = make_shared(); + locals->Set("host", host); + locals->Set("service", service); + + if (!rule.EvaluateFilter(locals)) + return false; + + std::ostringstream msgbuf2; + msgbuf2 << "Assigning membership for group '" << rule.GetName() << "' to service '" << service->GetName() << "' for rule " << di; + Log(LogDebug, "icinga", msgbuf2.str()); + + String group_name = rule.GetName(); + ServiceGroup::Ptr group = ServiceGroup::GetByName(group_name); + + if (!group) { + Log(LogCritical, "icinga", "Invalid membership assignment. Group '" + group_name + "' does not exist."); + return false; + } + + /* assign service group membership */ + group->ResolveGroupMembership(service, true); + + return true; +} + +void ServiceGroup::EvaluateObjectRules(const std::vector& rules) +{ + BOOST_FOREACH(const ObjectRule& rule, rules) { + BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects()) { + CONTEXT("Evaluating group membership in '" + rule.GetName() + "' for service '" + service->GetName() + "'"); + + EvaluateObjectRule(service, rule); + } + } +} + std::set ServiceGroup::GetMembers(void) const { boost::mutex::scoped_lock lock(m_ServiceGroupMutex); diff --git a/lib/icinga/servicegroup.h b/lib/icinga/servicegroup.h index 7e93ea5eb..580560623 100644 --- a/lib/icinga/servicegroup.h +++ b/lib/icinga/servicegroup.h @@ -23,6 +23,7 @@ #include "icinga/i2-icinga.h" #include "icinga/servicegroup.th" #include "icinga/service.h" +#include "config/objectrule.h" namespace icinga { @@ -44,9 +45,14 @@ public: bool ResolveGroupMembership(Service::Ptr const& service, bool add = true, int rstack = 0); + static void RegisterObjectRuleHandler(void); + private: mutable boost::mutex m_ServiceGroupMutex; std::set m_Members; + + static bool EvaluateObjectRule(const Service::Ptr service, const ObjectRule& rule); + static void EvaluateObjectRules(const std::vector& rules); }; } diff --git a/lib/icinga/usergroup.cpp b/lib/icinga/usergroup.cpp index 8ff0a88fb..2ee963709 100644 --- a/lib/icinga/usergroup.cpp +++ b/lib/icinga/usergroup.cpp @@ -23,12 +23,63 @@ #include "base/logger_fwd.h" #include "base/timer.h" #include "base/utility.h" +#include "base/context.h" #include using namespace icinga; REGISTER_TYPE(UserGroup); +INITIALIZE_ONCE(&UserGroup::RegisterObjectRuleHandler); + +void UserGroup::RegisterObjectRuleHandler(void) +{ + ObjectRule::RegisterType("UserGroup", &UserGroup::EvaluateObjectRules); +} + +bool UserGroup::EvaluateObjectRule(const User::Ptr user, const ObjectRule& rule) +{ + DebugInfo di = rule.GetDebugInfo(); + + std::ostringstream msgbuf; + msgbuf << "Evaluating 'object' rule (" << di << ")"; + CONTEXT(msgbuf.str()); + + Dictionary::Ptr locals = make_shared(); + locals->Set("user", user); + + if (!rule.EvaluateFilter(locals)) + return false; + + std::ostringstream msgbuf2; + msgbuf2 << "Assigning membership for group '" << rule.GetName() << "' to user '" << user->GetName() << "' for rule " << di; + Log(LogDebug, "icinga", msgbuf2.str()); + + String group_name = rule.GetName(); + UserGroup::Ptr group = UserGroup::GetByName(group_name); + + if (!group) { + Log(LogCritical, "icinga", "Invalid membership assignment. Group '" + group_name + "' does not exist."); + return false; + } + + /* assign user group membership */ + group->ResolveGroupMembership(user, true); + + return true; +} + +void UserGroup::EvaluateObjectRules(const std::vector& rules) +{ + BOOST_FOREACH(const ObjectRule& rule, rules) { + BOOST_FOREACH(const User::Ptr& user, DynamicType::GetObjects()) { + CONTEXT("Evaluating group membership in '" + rule.GetName() + "' for user '" + user->GetName() + "'"); + + EvaluateObjectRule(user, rule); + } + } +} + std::set UserGroup::GetMembers(void) const { boost::mutex::scoped_lock lock(m_UserGroupMutex); diff --git a/lib/icinga/usergroup.h b/lib/icinga/usergroup.h index 3338c6cda..60870fd4c 100644 --- a/lib/icinga/usergroup.h +++ b/lib/icinga/usergroup.h @@ -23,6 +23,7 @@ #include "icinga/i2-icinga.h" #include "icinga/usergroup.th" #include "icinga/user.h" +#include "config/objectrule.h" namespace icinga { @@ -44,9 +45,14 @@ public: bool ResolveGroupMembership(User::Ptr const& user, bool add = true, int rstack = 0); + static void RegisterObjectRuleHandler(void); + private: mutable boost::mutex m_UserGroupMutex; std::set m_Members; + + static bool EvaluateObjectRule(const User::Ptr user, const ObjectRule& rule); + static void EvaluateObjectRules(const std::vector& rules); }; } -- 2.40.0