mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-21 04:34:43 +02:00
parent
ee89f54679
commit
0078e00c13
@ -25,13 +25,13 @@
|
||||
using namespace icinga;
|
||||
|
||||
ApplyRule::RuleMap ApplyRule::m_Rules;
|
||||
ApplyRule::CallbackMap ApplyRule::m_Callbacks;
|
||||
ApplyRule::TypeMap ApplyRule::m_Types;
|
||||
|
||||
ApplyRule::ApplyRule(const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
|
||||
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm,
|
||||
const DebugInfo& di, const Object::Ptr& scope)
|
||||
: m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_FKVar(fkvar),
|
||||
m_FVVar(fvvar), m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope)
|
||||
m_FVVar(fvvar), m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope), m_HasMatches(false)
|
||||
{ }
|
||||
|
||||
String ApplyRule::GetTargetType(void) const
|
||||
@ -91,69 +91,27 @@ bool ApplyRule::EvaluateFilter(const Object::Ptr& scope) const
|
||||
return m_Filter->Evaluate(scope).ToBool();
|
||||
}
|
||||
|
||||
void ApplyRule::EvaluateRules(bool clear)
|
||||
void ApplyRule::RegisterType(const String& sourceType, const std::vector<String>& targetTypes)
|
||||
{
|
||||
std::set<String> completedTypes;
|
||||
|
||||
while (completedTypes.size() < m_Callbacks.size()) {
|
||||
std::pair<String, std::pair<Callback, std::vector<String> > > kv;
|
||||
BOOST_FOREACH(kv, m_Callbacks) {
|
||||
const String& sourceType = kv.first;
|
||||
|
||||
if (completedTypes.find(sourceType) != completedTypes.end())
|
||||
continue;
|
||||
|
||||
const Callback& callback = kv.second.first;
|
||||
const std::vector<String>& targetTypes = kv.second.second;
|
||||
|
||||
bool cont = false;
|
||||
|
||||
BOOST_FOREACH(const String& targetType, targetTypes) {
|
||||
if (IsValidSourceType(targetType) && completedTypes.find(targetType) == completedTypes.end()) {
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cont)
|
||||
continue;
|
||||
|
||||
completedTypes.insert(sourceType);
|
||||
|
||||
RuleMap::const_iterator it = m_Rules.find(kv.first);
|
||||
|
||||
if (it == m_Rules.end())
|
||||
continue;
|
||||
|
||||
callback(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
if (clear)
|
||||
m_Rules.clear();
|
||||
}
|
||||
|
||||
void ApplyRule::RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback)
|
||||
{
|
||||
m_Callbacks[sourceType] = make_pair(callback, targetTypes);
|
||||
m_Types[sourceType] = targetTypes;
|
||||
}
|
||||
|
||||
bool ApplyRule::IsValidSourceType(const String& sourceType)
|
||||
{
|
||||
return m_Callbacks.find(sourceType) != m_Callbacks.end();
|
||||
return m_Types.find(sourceType) != m_Types.end();
|
||||
}
|
||||
|
||||
bool ApplyRule::IsValidTargetType(const String& sourceType, const String& targetType)
|
||||
{
|
||||
CallbackMap::const_iterator it = m_Callbacks.find(sourceType);
|
||||
TypeMap::const_iterator it = m_Types.find(sourceType);
|
||||
|
||||
if (it == m_Callbacks.end())
|
||||
if (it == m_Types.end())
|
||||
return false;
|
||||
|
||||
if (it->second.second.size() == 1 && targetType == "")
|
||||
if (it->second.size() == 1 && targetType == "")
|
||||
return true;
|
||||
|
||||
BOOST_FOREACH(const String& type, it->second.second) {
|
||||
BOOST_FOREACH(const String& type, it->second) {
|
||||
if (type == targetType)
|
||||
return true;
|
||||
}
|
||||
@ -163,11 +121,47 @@ bool ApplyRule::IsValidTargetType(const String& sourceType, const String& target
|
||||
|
||||
std::vector<String> ApplyRule::GetTargetTypes(const String& sourceType)
|
||||
{
|
||||
CallbackMap::const_iterator it = m_Callbacks.find(sourceType);
|
||||
TypeMap::const_iterator it = m_Types.find(sourceType);
|
||||
|
||||
if (it == m_Callbacks.end())
|
||||
if (it == m_Types.end())
|
||||
return std::vector<String>();
|
||||
|
||||
return it->second.second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void ApplyRule::AddMatch(void)
|
||||
{
|
||||
m_HasMatches = true;
|
||||
}
|
||||
|
||||
bool ApplyRule::HasMatches(void) const
|
||||
{
|
||||
return m_HasMatches;
|
||||
}
|
||||
|
||||
std::vector<ApplyRule>& ApplyRule::GetRules(const String& type)
|
||||
{
|
||||
RuleMap::iterator it = m_Rules.find(type);
|
||||
if (it == m_Rules.end()) {
|
||||
static std::vector<ApplyRule> emptyList;
|
||||
return emptyList;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void ApplyRule::CheckMatches(void)
|
||||
{
|
||||
BOOST_FOREACH(const RuleMap::value_type& kv, m_Rules) {
|
||||
BOOST_FOREACH(const ApplyRule& rule, kv.second) {
|
||||
if (!rule.HasMatches())
|
||||
Log(LogWarning, "ApplyRule")
|
||||
<< "Apply rule '" + rule.GetName() + "' for type '" + kv.first + "' does not match anywhere!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyRule::DiscardRules(void)
|
||||
{
|
||||
m_Rules.clear();
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,7 @@ namespace icinga
|
||||
class I2_CONFIG_API ApplyRule
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void (const std::vector<ApplyRule>& rules)> Callback;
|
||||
typedef std::map<String, std::pair<Callback, std::vector<String> > > CallbackMap;
|
||||
typedef std::map<String, std::vector<String> > TypeMap;
|
||||
typedef std::map<String, std::vector<ApplyRule> > RuleMap;
|
||||
|
||||
String GetTargetType(void) const;
|
||||
@ -47,18 +46,23 @@ public:
|
||||
boost::shared_ptr<Expression> GetFTerm(void) const;
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
Object::Ptr GetScope(void) const;
|
||||
void AddMatch(void);
|
||||
bool HasMatches(void) const;
|
||||
|
||||
bool EvaluateFilter(const Object::Ptr& scope) const;
|
||||
|
||||
static void AddRule(const String& sourceType, const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
|
||||
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Object::Ptr& scope);
|
||||
static void EvaluateRules(bool clear);
|
||||
static std::vector<ApplyRule>& GetRules(const String& type);
|
||||
|
||||
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
|
||||
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes);
|
||||
static bool IsValidSourceType(const String& sourceType);
|
||||
static bool IsValidTargetType(const String& sourceType, const String& targetType);
|
||||
static std::vector<String> GetTargetTypes(const String& sourceType);
|
||||
|
||||
static void CheckMatches(void);
|
||||
static void DiscardRules(void);
|
||||
|
||||
private:
|
||||
String m_TargetType;
|
||||
String m_Name;
|
||||
@ -69,8 +73,9 @@ private:
|
||||
boost::shared_ptr<Expression> m_FTerm;
|
||||
DebugInfo m_DebugInfo;
|
||||
Object::Ptr m_Scope;
|
||||
bool m_HasMatches;
|
||||
|
||||
static CallbackMap m_Callbacks;
|
||||
static TypeMap m_Types;
|
||||
static RuleMap m_Rules;
|
||||
|
||||
ApplyRule(const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
|
||||
|
@ -42,7 +42,7 @@
|
||||
using namespace icinga;
|
||||
|
||||
boost::mutex ConfigItem::m_Mutex;
|
||||
ConfigItem::ItemMap ConfigItem::m_Items;
|
||||
ConfigItem::TypeMap ConfigItem::m_Items;
|
||||
ConfigItem::ItemList ConfigItem::m_UnnamedItems;
|
||||
|
||||
/**
|
||||
@ -57,11 +57,12 @@ ConfigItem::ItemList ConfigItem::m_UnnamedItems;
|
||||
*/
|
||||
ConfigItem::ConfigItem(const String& type, const String& name,
|
||||
bool abstract, const boost::shared_ptr<Expression>& exprl,
|
||||
const boost::shared_ptr<Expression>& filter,
|
||||
const DebugInfo& debuginfo, const Object::Ptr& scope,
|
||||
const String& zone)
|
||||
: m_Type(type), m_Name(name), m_Abstract(abstract),
|
||||
m_Expression(exprl), m_DebugInfo(debuginfo),
|
||||
m_Scope(scope), m_Zone(zone)
|
||||
m_Expression(exprl), m_Filter(filter),
|
||||
m_DebugInfo(debuginfo), m_Scope(scope), m_Zone(zone)
|
||||
{
|
||||
}
|
||||
|
||||
@ -120,6 +121,16 @@ boost::shared_ptr<Expression> ConfigItem::GetExpression(void) const
|
||||
return m_Expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the object filter for the configuration item.
|
||||
*
|
||||
* @returns The filter expression.
|
||||
*/
|
||||
boost::shared_ptr<Expression> ConfigItem::GetFilter(void) const
|
||||
{
|
||||
return m_Filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the configuration item by creating a DynamicObject
|
||||
* object.
|
||||
@ -150,7 +161,6 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
|
||||
|
||||
Dictionary::Ptr locals = new Dictionary();
|
||||
locals->Set("__parent", m_Scope);
|
||||
m_Scope.reset();
|
||||
|
||||
dobj->SetParentScope(locals);
|
||||
locals.reset();
|
||||
@ -238,10 +248,8 @@ void ConfigItem::Register(void)
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_UnnamedItems.push_back(this);
|
||||
} else {
|
||||
std::pair<String, String> key = std::make_pair(m_Type, m_Name);
|
||||
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_Items[key] = this;
|
||||
m_Items[m_Type][m_Name] = this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,57 +262,61 @@ void ConfigItem::Register(void)
|
||||
*/
|
||||
ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
||||
{
|
||||
std::pair<String, String> key = std::make_pair(type, name);
|
||||
ConfigItem::ItemMap::iterator it;
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
it = m_Items.find(key);
|
||||
}
|
||||
|
||||
if (it != m_Items.end())
|
||||
return it->second;
|
||||
ConfigItem::TypeMap::const_iterator it = m_Items.find(type);
|
||||
|
||||
if (it == m_Items.end())
|
||||
return ConfigItem::Ptr();
|
||||
|
||||
ConfigItem::ItemMap::const_iterator it2 = it->second.find(name);
|
||||
|
||||
if (it2 == it->second.end())
|
||||
return ConfigItem::Ptr();
|
||||
|
||||
return it2->second;
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigItem::CommitNewItems(void)
|
||||
bool ConfigItem::CommitNewItems(ParallelWorkQueue& upq)
|
||||
{
|
||||
std::vector<ConfigItem::Ptr> items;
|
||||
typedef std::pair<ConfigItem::Ptr, bool> ItemPair;
|
||||
std::vector<ItemPair> items;
|
||||
|
||||
do {
|
||||
ParallelWorkQueue upq;
|
||||
|
||||
items.clear();
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
|
||||
if (!kv.second->m_Abstract && !kv.second->m_Object) {
|
||||
upq.Enqueue(boost::bind(&ConfigItem::Commit, kv.second, false));
|
||||
items.push_back(kv.second);
|
||||
BOOST_FOREACH(const TypeMap::value_type& kv, m_Items) {
|
||||
BOOST_FOREACH(const ItemMap::value_type& kv2, kv.second)
|
||||
{
|
||||
if (!kv2.second->m_Abstract && !kv2.second->m_Object)
|
||||
items.push_back(std::make_pair(kv2.second, false));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& item, m_UnnamedItems) {
|
||||
if (!item->m_Abstract && !item->m_Object) {
|
||||
upq.Enqueue(boost::bind(&ConfigItem::Commit, item, true));
|
||||
items.push_back(item);
|
||||
}
|
||||
if (!item->m_Abstract && !item->m_Object)
|
||||
items.push_back(std::make_pair(item, true));
|
||||
}
|
||||
|
||||
m_UnnamedItems.clear();
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const ItemPair& ip, items) {
|
||||
upq.Enqueue(boost::bind(&ConfigItem::Commit, ip.first, ip.second));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
return false;
|
||||
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& item, items) {
|
||||
upq.Enqueue(boost::bind(&DynamicObject::OnConfigLoaded, item->m_Object));
|
||||
BOOST_FOREACH(const ItemPair& ip, items) {
|
||||
upq.Enqueue(boost::bind(&DynamicObject::OnConfigLoaded, ip.first->m_Object));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
@ -315,25 +327,18 @@ bool ConfigItem::CommitNewItems(void)
|
||||
|
||||
bool ConfigItem::ValidateItems(void)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
return false;
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Committing config items");
|
||||
|
||||
if (!CommitNewItems())
|
||||
if (!CommitNewItems(upq))
|
||||
return false;
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Evaluating 'object' rules (step 1)...");
|
||||
ObjectRule::EvaluateRules(false);
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Evaluating 'apply' rules...");
|
||||
ApplyRule::EvaluateRules(true);
|
||||
|
||||
if (!CommitNewItems())
|
||||
return false;
|
||||
|
||||
Log(LogInformation, "ConfigItem", "Evaluating 'object' rules (step 2)...");
|
||||
ObjectRule::EvaluateRules(true);
|
||||
ApplyRule::CheckMatches();
|
||||
ApplyRule::DiscardRules();
|
||||
|
||||
ConfigItem::DiscardItems();
|
||||
ConfigType::DiscardTypes();
|
||||
@ -400,3 +405,22 @@ void ConfigItem::DiscardItems(void)
|
||||
|
||||
m_Items.clear();
|
||||
}
|
||||
|
||||
std::vector<ConfigItem::Ptr> ConfigItem::GetItems(const String& type)
|
||||
{
|
||||
std::vector<ConfigItem::Ptr> items;
|
||||
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
TypeMap::const_iterator it = m_Items.find(type);
|
||||
|
||||
if (it == m_Items.end())
|
||||
return items;
|
||||
|
||||
BOOST_FOREACH(const ItemMap::value_type& kv, it->second)
|
||||
{
|
||||
items.push_back(kv.second);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "config/i2-config.hpp"
|
||||
#include "config/expression.hpp"
|
||||
#include "base/dynamicobject.hpp"
|
||||
#include "base/workqueue.hpp"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
@ -38,7 +39,9 @@ public:
|
||||
DECLARE_PTR_TYPEDEFS(ConfigItem);
|
||||
|
||||
ConfigItem(const String& type, const String& name, bool abstract,
|
||||
const boost::shared_ptr<Expression>& exprl, const DebugInfo& debuginfo,
|
||||
const boost::shared_ptr<Expression>& exprl,
|
||||
const boost::shared_ptr<Expression>& filter,
|
||||
const DebugInfo& debuginfo,
|
||||
const Object::Ptr& scope, const String& zone);
|
||||
|
||||
String GetType(void) const;
|
||||
@ -48,12 +51,12 @@ public:
|
||||
std::vector<ConfigItem::Ptr> GetParents(void) const;
|
||||
|
||||
boost::shared_ptr<Expression> GetExpression(void) const;
|
||||
boost::shared_ptr<Expression> GetFilter(void) const;
|
||||
|
||||
DynamicObject::Ptr Commit(bool discard = true);
|
||||
void Register(void);
|
||||
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
|
||||
Object::Ptr GetScope(void) const;
|
||||
|
||||
String GetZone(void) const;
|
||||
@ -65,12 +68,15 @@ public:
|
||||
static bool ActivateItems(void);
|
||||
static void DiscardItems(void);
|
||||
|
||||
static std::vector<ConfigItem::Ptr> GetItems(const String& type);
|
||||
|
||||
private:
|
||||
String m_Type; /**< The object type. */
|
||||
String m_Name; /**< The name. */
|
||||
bool m_Abstract; /**< Whether this is a template. */
|
||||
|
||||
boost::shared_ptr<Expression> m_Expression;
|
||||
boost::shared_ptr<Expression> m_Filter;
|
||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||
Object::Ptr m_Scope; /**< variable scope. */
|
||||
String m_Zone; /**< The zone. */
|
||||
@ -79,8 +85,9 @@ private:
|
||||
|
||||
static boost::mutex m_Mutex;
|
||||
|
||||
typedef std::map<std::pair<String, String>, ConfigItem::Ptr> ItemMap;
|
||||
static ItemMap m_Items; /**< All registered configuration items. */
|
||||
typedef std::map<String, ConfigItem::Ptr> ItemMap;
|
||||
typedef std::map<String, ItemMap> TypeMap;
|
||||
static TypeMap m_Items; /**< All registered configuration items. */
|
||||
|
||||
typedef std::vector<ConfigItem::Ptr> ItemList;
|
||||
static ItemList m_UnnamedItems;
|
||||
@ -88,7 +95,7 @@ private:
|
||||
static ConfigItem::Ptr GetObjectUnlocked(const String& type,
|
||||
const String& name);
|
||||
|
||||
static bool CommitNewItems(void);
|
||||
static bool CommitNewItems(ParallelWorkQueue& upq);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "base/dynamictype.hpp"
|
||||
#include <sstream>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
@ -69,6 +70,11 @@ void ConfigItemBuilder::AddExpression(Expression *expr)
|
||||
m_Expressions.push_back(expr);
|
||||
}
|
||||
|
||||
void ConfigItemBuilder::SetFilter(const boost::shared_ptr<Expression>& filter)
|
||||
{
|
||||
m_Filter = filter;
|
||||
}
|
||||
|
||||
ConfigItem::Ptr ConfigItemBuilder::Compile(void)
|
||||
{
|
||||
if (m_Type.IsEmpty()) {
|
||||
@ -104,10 +110,10 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
|
||||
dexpr->MakeInline();
|
||||
exprs.push_back(dexpr);
|
||||
|
||||
DictExpression *exprl = new DictExpression(exprs, m_DebugInfo);
|
||||
boost::shared_ptr<DictExpression> exprl = boost::make_shared<DictExpression>(exprs, m_DebugInfo);
|
||||
exprl->MakeInline();
|
||||
|
||||
return new ConfigItem(m_Type, m_Name, m_Abstract, boost::shared_ptr<Expression>(exprl),
|
||||
return new ConfigItem(m_Type, m_Name, m_Abstract, exprl, m_Filter,
|
||||
m_DebugInfo, m_Scope, m_Zone);
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
void SetZone(const String& zone);
|
||||
|
||||
void AddExpression(Expression *expr);
|
||||
void SetFilter(const boost::shared_ptr<Expression>& filter);
|
||||
|
||||
ConfigItem::Ptr Compile(void);
|
||||
|
||||
@ -57,6 +58,7 @@ private:
|
||||
String m_Name; /**< The name. */
|
||||
bool m_Abstract; /**< Whether the item is abstract. */
|
||||
std::vector<Expression *> m_Expressions; /**< Expressions for this item. */
|
||||
boost::shared_ptr<Expression> m_Filter; /**< Filter expression. */
|
||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||
Object::Ptr m_Scope; /**< variable scope. */
|
||||
String m_Zone; /**< The zone. */
|
||||
|
@ -46,10 +46,10 @@ Value Expression::Evaluate(const Object::Ptr& context, DebugHint *dhint) const
|
||||
{
|
||||
try {
|
||||
#ifdef _DEBUG
|
||||
std::ostringstream msgbuf;
|
||||
/* std::ostringstream msgbuf;
|
||||
ShowCodeFragment(msgbuf, GetDebugInfo(), false);
|
||||
Log(LogDebug, "Expression")
|
||||
<< "Executing:\n" << msgbuf.str();
|
||||
<< "Executing:\n" << msgbuf.str();*/
|
||||
#endif /* _DEBUG */
|
||||
|
||||
return DoEvaluate(context, dhint);
|
||||
@ -508,10 +508,9 @@ Value ObjectExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint)
|
||||
item->SetAbstract(m_Abstract);
|
||||
item->SetScope(context);
|
||||
item->SetZone(m_Zone);
|
||||
item->Compile()->Register();
|
||||
item->SetFilter(m_Filter);
|
||||
|
||||
if (m_Filter)
|
||||
ObjectRule::AddRule(m_Type, name, m_Filter, m_DebugInfo, context);
|
||||
item->Compile()->Register();
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
@ -23,70 +23,14 @@
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
ObjectRule::RuleMap ObjectRule::m_Rules;
|
||||
ObjectRule::CallbackMap ObjectRule::m_Callbacks;
|
||||
ObjectRule::TypeSet ObjectRule::m_Types;
|
||||
|
||||
ObjectRule::ObjectRule(const String& name, const boost::shared_ptr<Expression>& filter,
|
||||
const DebugInfo& di, const Object::Ptr& scope)
|
||||
: m_Name(name), m_Filter(filter), m_DebugInfo(di), m_Scope(scope)
|
||||
{ }
|
||||
|
||||
String ObjectRule::GetName(void) const
|
||||
void ObjectRule::RegisterType(const String& sourceType)
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Expression> ObjectRule::GetFilter(void) const
|
||||
{
|
||||
return m_Filter;
|
||||
}
|
||||
|
||||
DebugInfo ObjectRule::GetDebugInfo(void) const
|
||||
{
|
||||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
Object::Ptr ObjectRule::GetScope(void) const
|
||||
{
|
||||
return m_Scope;
|
||||
}
|
||||
|
||||
void ObjectRule::AddRule(const String& sourceType, const String& name,
|
||||
const boost::shared_ptr<Expression>& filter, const DebugInfo& di, const Object::Ptr& scope)
|
||||
{
|
||||
m_Rules[sourceType].push_back(ObjectRule(name, filter, di, scope));
|
||||
}
|
||||
|
||||
bool ObjectRule::EvaluateFilter(const Object::Ptr& scope) const
|
||||
{
|
||||
return m_Filter->Evaluate(scope).ToBool();
|
||||
}
|
||||
|
||||
void ObjectRule::EvaluateRules(bool clear)
|
||||
{
|
||||
std::pair<String, Callback> 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);
|
||||
}
|
||||
|
||||
if (clear)
|
||||
m_Rules.clear();
|
||||
}
|
||||
|
||||
void ObjectRule::RegisterType(const String& sourceType, const ObjectRule::Callback& callback)
|
||||
{
|
||||
m_Callbacks[sourceType] = callback;
|
||||
m_Types.insert(sourceType);
|
||||
}
|
||||
|
||||
bool ObjectRule::IsValidSourceType(const String& sourceType)
|
||||
{
|
||||
return m_Callbacks.find(sourceType) != m_Callbacks.end();
|
||||
return m_Types.find(sourceType) != m_Types.end();
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "config/i2-config.hpp"
|
||||
#include "config/expression.hpp"
|
||||
#include "base/debuginfo.hpp"
|
||||
#include "base/dynamictype.hpp"
|
||||
#include <set>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
@ -34,34 +34,15 @@ namespace icinga
|
||||
class I2_CONFIG_API ObjectRule
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void (const std::vector<ObjectRule>& rules)> Callback;
|
||||
typedef std::map<String, Callback> CallbackMap;
|
||||
typedef std::map<String, std::vector<ObjectRule> > RuleMap;
|
||||
typedef std::set<String> TypeSet;
|
||||
|
||||
String GetName(void) const;
|
||||
boost::shared_ptr<Expression> GetFilter(void) const;
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
Object::Ptr GetScope(void) const;
|
||||
|
||||
bool EvaluateFilter(const Object::Ptr& scope) const;
|
||||
|
||||
static void AddRule(const String& sourceType, const String& name,
|
||||
const boost::shared_ptr<Expression>& filter, const DebugInfo& di, const Object::Ptr& scope);
|
||||
static void EvaluateRules(bool clear);
|
||||
|
||||
static void RegisterType(const String& sourceType, const ObjectRule::Callback& callback);
|
||||
static void RegisterType(const String& sourceType);
|
||||
static bool IsValidSourceType(const String& sourceType);
|
||||
|
||||
private:
|
||||
String m_Name;
|
||||
boost::shared_ptr<Expression> m_Filter;
|
||||
DebugInfo m_DebugInfo;
|
||||
Object::Ptr m_Scope;
|
||||
ObjectRule(void);
|
||||
|
||||
static CallbackMap m_Callbacks;
|
||||
static RuleMap m_Rules;
|
||||
|
||||
ObjectRule(const String& name, const boost::shared_ptr<Expression>& filter, const DebugInfo& di, const Object::Ptr& scope);
|
||||
static TypeSet m_Types;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ void Dependency::RegisterApplyRuleHandler(void)
|
||||
std::vector<String> targets;
|
||||
targets.push_back("Host");
|
||||
targets.push_back("Service");
|
||||
ApplyRule::RegisterType("Dependency", targets, &Dependency::EvaluateApplyRules);
|
||||
ApplyRule::RegisterType("Dependency", targets);
|
||||
}
|
||||
|
||||
void Dependency::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
void Dependency::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
@ -77,7 +77,7 @@ void Dependency::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, c
|
||||
|
||||
}
|
||||
|
||||
bool Dependency::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
bool Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
@ -123,7 +123,7 @@ bool Dependency::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const App
|
||||
name += instance;
|
||||
}
|
||||
|
||||
EvaluateApplyRuleOneInstance(checkable, name, locals, rule);
|
||||
EvaluateApplyRuleInstance(checkable, name, locals, rule);
|
||||
}
|
||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||
if (rule.GetFVVar().IsEmpty())
|
||||
@ -136,68 +136,47 @@ bool Dependency::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const App
|
||||
locals->Set(rule.GetFKVar(), kv.first);
|
||||
locals->Set(rule.GetFVVar(), kv.second);
|
||||
|
||||
EvaluateApplyRuleOneInstance(checkable, rule.GetName() + kv.first, locals, rule);
|
||||
EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, locals, rule);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dependency::EvaluateApplyRule(const ApplyRule& rule)
|
||||
void Dependency::EvaluateApplyRules(const Host::Ptr& host)
|
||||
{
|
||||
int apply_count = 0;
|
||||
|
||||
if (rule.GetTargetType() == "Host") {
|
||||
apply_count = 0;
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjectsByType<Host>()) {
|
||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||
|
||||
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("Dependency"))
|
||||
{
|
||||
if (rule.GetTargetType() != "Host")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRuleOne(host, rule))
|
||||
apply_count++;
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_count == 0)
|
||||
Log(LogWarning, "Dependency")
|
||||
<< "Apply rule '" << rule.GetName() << "' for host does not match anywhere!";
|
||||
|
||||
} else if (rule.GetTargetType() == "Service") {
|
||||
apply_count = 0;
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjectsByType<Service>()) {
|
||||
CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'");
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRuleOne(service, rule))
|
||||
apply_count++;
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_count == 0)
|
||||
Log(LogWarning, "Dependency")
|
||||
<< "Apply rule '" << rule.GetName() << "' for service does not match anywhere!";
|
||||
|
||||
} else {
|
||||
Log(LogWarning, "Dependency")
|
||||
<< "Wrong target type for apply rule '" << rule.GetName() << "'!";
|
||||
}
|
||||
}
|
||||
|
||||
void Dependency::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
|
||||
void Dependency::EvaluateApplyRules(const Service::Ptr& service)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
|
||||
|
||||
BOOST_FOREACH(const ApplyRule& rule, rules) {
|
||||
upq.Enqueue(boost::bind(&Dependency::EvaluateApplyRule, boost::cref(rule)));
|
||||
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("Dependency"))
|
||||
{
|
||||
if (rule.GetTargetType() != "Service")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(service, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ namespace icinga
|
||||
{
|
||||
|
||||
class ApplyRule;
|
||||
class Host;
|
||||
class Service;
|
||||
|
||||
/**
|
||||
* A service dependency..
|
||||
@ -51,6 +53,9 @@ public:
|
||||
|
||||
static void ValidateFilters(const String& location, const Dependency::Ptr& object);
|
||||
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);
|
||||
|
||||
protected:
|
||||
virtual void OnConfigLoaded(void);
|
||||
virtual void OnStateLoaded(void);
|
||||
@ -60,10 +65,8 @@ private:
|
||||
Checkable::Ptr m_Parent;
|
||||
Checkable::Ptr m_Child;
|
||||
|
||||
static void EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
|
||||
static bool EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const ApplyRule& rule);
|
||||
static void EvaluateApplyRule(const ApplyRule& rule);
|
||||
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
|
||||
static void EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
|
||||
static bool EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include "icinga/service.hpp"
|
||||
#include "icinga/hostgroup.hpp"
|
||||
#include "icinga/pluginutility.hpp"
|
||||
#include "icinga/scheduleddowntime.hpp"
|
||||
#include "config/configcompilercontext.hpp"
|
||||
#include "base/configerror.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include "base/utility.hpp"
|
||||
@ -52,6 +55,12 @@ void Host::OnConfigLoaded(void)
|
||||
hg->ResolveGroupMembership(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
HostGroup::EvaluateObjectRules(this);
|
||||
ScheduledDowntime::EvaluateApplyRules(this);
|
||||
Notification::EvaluateApplyRules(this);
|
||||
Dependency::EvaluateApplyRules(this);
|
||||
Service::EvaluateApplyRules(this);
|
||||
}
|
||||
|
||||
void Host::Stop(void)
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "icinga/hostgroup.hpp"
|
||||
#include "config/objectrule.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "base/dynamictype.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
@ -34,62 +35,52 @@ INITIALIZE_ONCE(&HostGroup::RegisterObjectRuleHandler);
|
||||
|
||||
void HostGroup::RegisterObjectRuleHandler(void)
|
||||
{
|
||||
ObjectRule::RegisterType("HostGroup", &HostGroup::EvaluateObjectRules);
|
||||
ObjectRule::RegisterType("HostGroup");
|
||||
}
|
||||
|
||||
bool HostGroup::EvaluateObjectRuleOne(const Host::Ptr& host, const ObjectRule& rule)
|
||||
bool HostGroup::EvaluateObjectRule(const Host::Ptr& host, const ConfigItem::Ptr& group)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
String group_name = group->GetName();
|
||||
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Evaluating 'object' rule (" << di << ")";
|
||||
CONTEXT(msgbuf.str());
|
||||
CONTEXT("Evaluating rule for group '" + group_name + "'");
|
||||
|
||||
Dictionary::Ptr locals = new Dictionary();
|
||||
locals->Set("__parent", rule.GetScope());
|
||||
locals->Set("__parent", group->GetScope());
|
||||
locals->Set("host", host);
|
||||
|
||||
if (!rule.EvaluateFilter(locals))
|
||||
if (!group->GetFilter()->Evaluate(locals))
|
||||
return false;
|
||||
|
||||
Log(LogDebug, "HostGroup")
|
||||
<< "Assigning membership for group '" << rule.GetName() << "' to host '" << host->GetName() << "' for rule " << di;
|
||||
<< "Assigning membership for group '" << group_name << "' to host '" << host->GetName() << "'";
|
||||
|
||||
String group_name = rule.GetName();
|
||||
HostGroup::Ptr group = HostGroup::GetByName(group_name);
|
||||
HostGroup::Ptr groupObject = HostGroup::GetByName(group_name);
|
||||
|
||||
if (!group) {
|
||||
if (!groupObject) {
|
||||
Log(LogCritical, "HostGroup")
|
||||
<< "Invalid membership assignment. Group '" << group_name << "' does not exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
/* assign host group membership */
|
||||
group->ResolveGroupMembership(host, true);
|
||||
groupObject->ResolveGroupMembership(host, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HostGroup::EvaluateObjectRule(const ObjectRule& rule)
|
||||
void HostGroup::EvaluateObjectRules(const Host::Ptr& host)
|
||||
{
|
||||
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjectsByType<Host>()) {
|
||||
CONTEXT("Evaluating group membership in '" + rule.GetName() + "' for host '" + host->GetName() + "'");
|
||||
CONTEXT("Evaluating group memberships for host '" + host->GetName() + "'");
|
||||
|
||||
EvaluateObjectRuleOne(host, rule);
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& group, ConfigItem::GetItems("HostGroup"))
|
||||
{
|
||||
if (!group->GetFilter())
|
||||
continue;
|
||||
|
||||
EvaluateObjectRule(host, group);
|
||||
}
|
||||
}
|
||||
|
||||
void HostGroup::EvaluateObjectRules(const std::vector<ObjectRule>& rules)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
|
||||
BOOST_FOREACH(const ObjectRule& rule, rules) {
|
||||
upq.Enqueue(boost::bind(HostGroup::EvaluateObjectRule, boost::cref(rule)));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
}
|
||||
|
||||
std::set<Host::Ptr> HostGroup::GetMembers(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_HostGroupMutex);
|
||||
|
@ -27,7 +27,7 @@
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
class ObjectRule;
|
||||
class ConfigItem;
|
||||
|
||||
/**
|
||||
* An Icinga host group.
|
||||
@ -48,13 +48,13 @@ public:
|
||||
|
||||
static void RegisterObjectRuleHandler(void);
|
||||
|
||||
static void EvaluateObjectRules(const Host::Ptr& host);
|
||||
|
||||
private:
|
||||
mutable boost::mutex m_HostGroupMutex;
|
||||
std::set<Host::Ptr> m_Members;
|
||||
|
||||
static bool EvaluateObjectRuleOne(const Host::Ptr& host, const ObjectRule& rule);
|
||||
static void EvaluateObjectRule(const ObjectRule& rule);
|
||||
static void EvaluateObjectRules(const std::vector<ObjectRule>& rules);
|
||||
static bool EvaluateObjectRule(const Host::Ptr& host, const intrusive_ptr<ConfigItem>& item);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ void Notification::RegisterApplyRuleHandler(void)
|
||||
std::vector<String> targets;
|
||||
targets.push_back("Host");
|
||||
targets.push_back("Service");
|
||||
ApplyRule::RegisterType("Notification", targets, &Notification::EvaluateApplyRules);
|
||||
ApplyRule::RegisterType("Notification", targets);
|
||||
}
|
||||
|
||||
void Notification::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
void Notification::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
@ -76,7 +76,7 @@ void Notification::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable,
|
||||
|
||||
}
|
||||
|
||||
bool Notification::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
bool Notification::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
@ -122,7 +122,7 @@ bool Notification::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const A
|
||||
name += instance;
|
||||
}
|
||||
|
||||
EvaluateApplyRuleOneInstance(checkable, name, locals, rule);
|
||||
EvaluateApplyRuleInstance(checkable, name, locals, rule);
|
||||
}
|
||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||
if (rule.GetFVVar().IsEmpty())
|
||||
@ -135,67 +135,47 @@ bool Notification::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const A
|
||||
locals->Set(rule.GetFKVar(), kv.first);
|
||||
locals->Set(rule.GetFVVar(), kv.second);
|
||||
|
||||
EvaluateApplyRuleOneInstance(checkable, rule.GetName() + kv.first, locals, rule);
|
||||
EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, locals, rule);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Notification::EvaluateApplyRule(const ApplyRule& rule)
|
||||
void Notification::EvaluateApplyRules(const Host::Ptr& host)
|
||||
{
|
||||
int apply_count = 0;
|
||||
|
||||
if (rule.GetTargetType() == "Host") {
|
||||
apply_count = 0;
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjectsByType<Host>()) {
|
||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||
|
||||
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("Notification"))
|
||||
{
|
||||
if (rule.GetTargetType() != "Host")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRuleOne(host, rule))
|
||||
apply_count++;
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_count == 0)
|
||||
Log(LogWarning, "Notification")
|
||||
<< "Apply rule '" << rule.GetName() << "' for host does not match anywhere!";
|
||||
|
||||
} else if (rule.GetTargetType() == "Service") {
|
||||
apply_count = 0;
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjectsByType<Service>()) {
|
||||
CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'");
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRuleOne(service, rule))
|
||||
apply_count++;
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_count == 0)
|
||||
Log(LogWarning, "Notification")
|
||||
<< "Apply rule '" << rule.GetName() << "' for service does not match anywhere!";
|
||||
|
||||
} else {
|
||||
Log(LogWarning, "Notification")
|
||||
<< "Wrong target type for apply rule '" << rule.GetName() << "'!";
|
||||
}
|
||||
}
|
||||
void Notification::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
|
||||
|
||||
void Notification::EvaluateApplyRules(const Service::Ptr& service)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
|
||||
|
||||
BOOST_FOREACH(const ApplyRule& rule, rules) {
|
||||
upq.Enqueue(boost::bind(&Notification::EvaluateApplyRule, boost::cref(rule)));
|
||||
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("Notification"))
|
||||
{
|
||||
if (rule.GetTargetType() != "Service")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(service, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
}
|
||||
|
@ -68,6 +68,8 @@ enum NotificationType
|
||||
class NotificationCommand;
|
||||
class Checkable;
|
||||
class ApplyRule;
|
||||
class Host;
|
||||
class Service;
|
||||
|
||||
/**
|
||||
* An Icinga notification specification.
|
||||
@ -108,6 +110,9 @@ public:
|
||||
|
||||
static void ValidateFilters(const String& location, const Notification::Ptr& object);
|
||||
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);
|
||||
|
||||
protected:
|
||||
virtual void OnConfigLoaded(void);
|
||||
virtual void Start(void);
|
||||
@ -116,10 +121,8 @@ protected:
|
||||
private:
|
||||
void ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const CheckResult::Ptr& cr, bool force, const String& author = "", const String& text = "");
|
||||
|
||||
static void EvaluateApplyRuleOneInstance(const intrusive_ptr<Checkable>& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
|
||||
static bool EvaluateApplyRuleOne(const intrusive_ptr<Checkable>& checkable, const ApplyRule& rule);
|
||||
static void EvaluateApplyRule(const ApplyRule& rule);
|
||||
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
|
||||
static void EvaluateApplyRuleInstance(const intrusive_ptr<Checkable>& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
|
||||
static bool EvaluateApplyRule(const intrusive_ptr<Checkable>& checkable, const ApplyRule& rule);
|
||||
};
|
||||
|
||||
I2_ICINGA_API int ServiceStateToFilter(ServiceState state);
|
||||
|
@ -38,10 +38,10 @@ void ScheduledDowntime::RegisterApplyRuleHandler(void)
|
||||
std::vector<String> targets;
|
||||
targets.push_back("Host");
|
||||
targets.push_back("Service");
|
||||
ApplyRule::RegisterType("ScheduledDowntime", targets, &ScheduledDowntime::EvaluateApplyRules);
|
||||
ApplyRule::RegisterType("ScheduledDowntime", targets);
|
||||
}
|
||||
|
||||
void ScheduledDowntime::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
void ScheduledDowntime::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
@ -75,7 +75,7 @@ void ScheduledDowntime::EvaluateApplyRuleOneInstance(const Checkable::Ptr& check
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
||||
bool ScheduledDowntime::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
@ -121,7 +121,7 @@ bool ScheduledDowntime::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, co
|
||||
name += instance;
|
||||
}
|
||||
|
||||
EvaluateApplyRuleOneInstance(checkable, name, locals, rule);
|
||||
EvaluateApplyRuleInstance(checkable, name, locals, rule);
|
||||
}
|
||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||
if (rule.GetFVVar().IsEmpty())
|
||||
@ -134,68 +134,47 @@ bool ScheduledDowntime::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, co
|
||||
locals->Set(rule.GetFKVar(), kv.first);
|
||||
locals->Set(rule.GetFVVar(), kv.second);
|
||||
|
||||
EvaluateApplyRuleOneInstance(checkable, rule.GetName() + kv.first, locals, rule);
|
||||
EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, locals, rule);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScheduledDowntime::EvaluateApplyRule(const ApplyRule& rule)
|
||||
void ScheduledDowntime::EvaluateApplyRules(const Host::Ptr& host)
|
||||
{
|
||||
int apply_count = 0;
|
||||
|
||||
if (rule.GetTargetType() == "Host") {
|
||||
apply_count = 0;
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjectsByType<Host>()) {
|
||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||
|
||||
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("ScheduledDowntime"))
|
||||
{
|
||||
if (rule.GetTargetType() != "Host")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRuleOne(host, rule))
|
||||
apply_count++;
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_count == 0)
|
||||
Log(LogWarning, "ScheduledDowntime")
|
||||
<< "Apply rule '" << rule.GetName() << "' for host does not match anywhere!";
|
||||
|
||||
} else if (rule.GetTargetType() == "Service") {
|
||||
apply_count = 0;
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjectsByType<Service>()) {
|
||||
CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'");
|
||||
|
||||
try {
|
||||
if(EvaluateApplyRuleOne(service, rule))
|
||||
apply_count++;
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_count == 0)
|
||||
Log(LogWarning, "ScheduledDowntime")
|
||||
<< "Apply rule '" << rule.GetName() << "' for service does not match anywhere!";
|
||||
|
||||
} else {
|
||||
Log(LogWarning, "ScheduledDowntime")
|
||||
<< "Wrong target type for apply rule '" << rule.GetName() << "'!";
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduledDowntime::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
|
||||
void ScheduledDowntime::EvaluateApplyRules(const Service::Ptr& service)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
CONTEXT("Evaluating 'apply' rules for service '" + service->GetName() + "'");
|
||||
|
||||
BOOST_FOREACH(const ApplyRule& rule, rules) {
|
||||
upq.Enqueue(boost::bind(&ScheduledDowntime::EvaluateApplyRule, boost::cref(rule)));
|
||||
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("ScheduledDowntime"))
|
||||
{
|
||||
if (rule.GetTargetType() != "Service")
|
||||
continue;
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(service, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ namespace icinga
|
||||
{
|
||||
|
||||
class ApplyRule;
|
||||
class Host;
|
||||
class Service;
|
||||
|
||||
/**
|
||||
* An Icinga scheduled downtime specification.
|
||||
@ -47,6 +49,9 @@ public:
|
||||
|
||||
static void RegisterApplyRuleHandler(void);
|
||||
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);
|
||||
|
||||
protected:
|
||||
virtual void Start(void);
|
||||
|
||||
@ -56,10 +61,8 @@ private:
|
||||
std::pair<double, double> FindNextSegment(void);
|
||||
void CreateNextDowntime(void);
|
||||
|
||||
static void EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
|
||||
static bool EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const ApplyRule& rule);
|
||||
static void EvaluateApplyRule(const ApplyRule& rule);
|
||||
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
|
||||
static void EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
|
||||
static bool EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -37,10 +37,10 @@ void Service::RegisterApplyRuleHandler(void)
|
||||
{
|
||||
std::vector<String> targets;
|
||||
targets.push_back("Host");
|
||||
ApplyRule::RegisterType("Service", targets, &Service::EvaluateApplyRules);
|
||||
ApplyRule::RegisterType("Service", targets);
|
||||
}
|
||||
|
||||
void Service::EvaluateApplyRuleOneInstance(const Host::Ptr& host, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
void Service::EvaluateApplyRuleInstance(const Host::Ptr& host, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
@ -68,7 +68,7 @@ void Service::EvaluateApplyRuleOneInstance(const Host::Ptr& host, const String&
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
||||
bool Service::EvaluateApplyRuleOne(const Host::Ptr& host, const ApplyRule& rule)
|
||||
bool Service::EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
@ -108,7 +108,7 @@ bool Service::EvaluateApplyRuleOne(const Host::Ptr& host, const ApplyRule& rule)
|
||||
name += instance;
|
||||
}
|
||||
|
||||
EvaluateApplyRuleOneInstance(host, name, locals, rule);
|
||||
EvaluateApplyRuleInstance(host, name, locals, rule);
|
||||
}
|
||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||
if (rule.GetFVVar().IsEmpty())
|
||||
@ -121,41 +121,24 @@ bool Service::EvaluateApplyRuleOne(const Host::Ptr& host, const ApplyRule& rule)
|
||||
locals->Set(rule.GetFKVar(), kv.first);
|
||||
locals->Set(rule.GetFVVar(), kv.second);
|
||||
|
||||
EvaluateApplyRuleOneInstance(host, rule.GetName() + kv.first, locals, rule);
|
||||
EvaluateApplyRuleInstance(host, rule.GetName() + kv.first, locals, rule);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Service::EvaluateApplyRule(const ApplyRule& rule)
|
||||
void Service::EvaluateApplyRules(const Host::Ptr& host)
|
||||
{
|
||||
int apply_count = 0;
|
||||
|
||||
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjectsByType<Host>()) {
|
||||
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("Service")) {
|
||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRuleOne(host, rule))
|
||||
apply_count++;
|
||||
if (EvaluateApplyRule(host, rule))
|
||||
rule.AddMatch();
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if (apply_count == 0)
|
||||
Log(LogWarning, "Service")
|
||||
<< "Apply rule '" << rule.GetName() << "' for host does not match anywhere!";
|
||||
}
|
||||
|
||||
void Service::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
|
||||
BOOST_FOREACH(const ApplyRule& rule, rules) {
|
||||
upq.Enqueue(boost::bind(&Service::EvaluateApplyRule, boost::cref(rule)));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "icinga/service.hpp"
|
||||
#include "icinga/servicegroup.hpp"
|
||||
#include "icinga/scheduleddowntime.hpp"
|
||||
#include "icinga/pluginutility.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/convert.hpp"
|
||||
@ -65,6 +66,11 @@ void Service::OnConfigLoaded(void)
|
||||
SetSchedulingOffset(Utility::Random());
|
||||
|
||||
Checkable::OnConfigLoaded();
|
||||
|
||||
ServiceGroup::EvaluateObjectRules(this);
|
||||
ScheduledDowntime::EvaluateApplyRules(this);
|
||||
Notification::EvaluateApplyRules(this);
|
||||
Dependency::EvaluateApplyRules(this);
|
||||
}
|
||||
|
||||
Service::Ptr Service::GetByNamePair(const String& hostName, const String& serviceName)
|
||||
|
@ -53,16 +53,16 @@ public:
|
||||
|
||||
static void RegisterApplyRuleHandler(void);
|
||||
|
||||
static void EvaluateApplyRules(const Host::Ptr& host);
|
||||
|
||||
protected:
|
||||
virtual void OnConfigLoaded(void);
|
||||
|
||||
private:
|
||||
Host::Ptr m_Host;
|
||||
|
||||
static void EvaluateApplyRuleOneInstance(const Host::Ptr& host, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
|
||||
static bool EvaluateApplyRuleOne(const Host::Ptr& host, const ApplyRule& rule);
|
||||
static void EvaluateApplyRule(const ApplyRule& rule);
|
||||
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
|
||||
static void EvaluateApplyRuleInstance(const Host::Ptr& host, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
|
||||
static bool EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule);
|
||||
};
|
||||
|
||||
I2_ICINGA_API boost::tuple<Host::Ptr, Service::Ptr> GetHostService(const Checkable::Ptr& checkable);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "icinga/servicegroup.hpp"
|
||||
#include "config/objectrule.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "base/dynamictype.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/logger.hpp"
|
||||
@ -34,65 +35,55 @@ INITIALIZE_ONCE(&ServiceGroup::RegisterObjectRuleHandler);
|
||||
|
||||
void ServiceGroup::RegisterObjectRuleHandler(void)
|
||||
{
|
||||
ObjectRule::RegisterType("ServiceGroup", &ServiceGroup::EvaluateObjectRules);
|
||||
ObjectRule::RegisterType("ServiceGroup");
|
||||
}
|
||||
|
||||
bool ServiceGroup::EvaluateObjectRuleOne(const Service::Ptr& service, const ObjectRule& rule)
|
||||
bool ServiceGroup::EvaluateObjectRule(const Service::Ptr& service, const ConfigItem::Ptr& group)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
String group_name = group->GetName();
|
||||
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Evaluating 'object' rule (" << di << ")";
|
||||
CONTEXT(msgbuf.str());
|
||||
CONTEXT("Evaluating rule for group '" + group_name + "'");
|
||||
|
||||
Host::Ptr host = service->GetHost();
|
||||
|
||||
Dictionary::Ptr locals = new Dictionary();
|
||||
locals->Set("__parent", rule.GetScope());
|
||||
locals->Set("__parent", group->GetScope());
|
||||
locals->Set("host", host);
|
||||
locals->Set("service", service);
|
||||
|
||||
if (!rule.EvaluateFilter(locals))
|
||||
if (!group->GetFilter()->Evaluate(locals))
|
||||
return false;
|
||||
|
||||
Log(LogDebug, "ServiceGroup")
|
||||
<< "Assigning membership for group '" << rule.GetName() << "' to service '" << service->GetName() << "' for rule " << di;
|
||||
<< "Assigning membership for group '" << group_name << "' to service '" << service->GetName() << "'";
|
||||
|
||||
String group_name = rule.GetName();
|
||||
ServiceGroup::Ptr group = ServiceGroup::GetByName(group_name);
|
||||
ServiceGroup::Ptr groupObject = ServiceGroup::GetByName(group_name);
|
||||
|
||||
if (!group) {
|
||||
if (!groupObject) {
|
||||
Log(LogCritical, "ServiceGroup")
|
||||
<< "Invalid membership assignment. Group '" << group_name << "' does not exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
/* assign service group membership */
|
||||
group->ResolveGroupMembership(service, true);
|
||||
groupObject->ResolveGroupMembership(service, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServiceGroup::EvaluateObjectRule(const ObjectRule& rule)
|
||||
void ServiceGroup::EvaluateObjectRules(const Service::Ptr& service)
|
||||
{
|
||||
BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjectsByType<Service>()) {
|
||||
CONTEXT("Evaluating group membership in '" + rule.GetName() + "' for service '" + service->GetName() + "'");
|
||||
CONTEXT("Evaluating group membership for service '" + service->GetName() + "'");
|
||||
|
||||
EvaluateObjectRuleOne(service, rule);
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& group, ConfigItem::GetItems("ServiceGroup"))
|
||||
{
|
||||
if (!group->GetFilter())
|
||||
continue;
|
||||
|
||||
EvaluateObjectRule(service, group);
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceGroup::EvaluateObjectRules(const std::vector<ObjectRule>& rules)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
|
||||
BOOST_FOREACH(const ObjectRule& rule, rules) {
|
||||
upq.Enqueue(boost::bind(ServiceGroup::EvaluateObjectRule, boost::cref(rule)));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
}
|
||||
|
||||
std::set<Service::Ptr> ServiceGroup::GetMembers(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_ServiceGroupMutex);
|
||||
|
@ -27,7 +27,7 @@
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
class ObjectRule;
|
||||
class ConfigItem;
|
||||
|
||||
/**
|
||||
* An Icinga service group.
|
||||
@ -48,13 +48,13 @@ public:
|
||||
|
||||
static void RegisterObjectRuleHandler(void);
|
||||
|
||||
static void EvaluateObjectRules(const Service::Ptr& service);
|
||||
|
||||
private:
|
||||
mutable boost::mutex m_ServiceGroupMutex;
|
||||
std::set<Service::Ptr> m_Members;
|
||||
|
||||
static bool EvaluateObjectRuleOne(const Service::Ptr& service, const ObjectRule& rule);
|
||||
static void EvaluateObjectRule(const ObjectRule& rule);
|
||||
static void EvaluateObjectRules(const std::vector<ObjectRule>& rules);
|
||||
static bool EvaluateObjectRule(const Service::Ptr& service, const intrusive_ptr<ConfigItem>& group);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "icinga/user.hpp"
|
||||
#include "icinga/usergroup.hpp"
|
||||
#include "icinga/notification.hpp"
|
||||
#include "icinga/usergroup.hpp"
|
||||
#include "config/configcompilercontext.hpp"
|
||||
@ -51,6 +52,8 @@ void User::OnConfigLoaded(void)
|
||||
ug->ResolveGroupMembership(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
UserGroup::EvaluateObjectRules(this);
|
||||
}
|
||||
|
||||
void User::Stop(void)
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "icinga/usergroup.hpp"
|
||||
#include "config/objectrule.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "base/dynamictype.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/logger.hpp"
|
||||
@ -34,62 +35,52 @@ INITIALIZE_ONCE(&UserGroup::RegisterObjectRuleHandler);
|
||||
|
||||
void UserGroup::RegisterObjectRuleHandler(void)
|
||||
{
|
||||
ObjectRule::RegisterType("UserGroup", &UserGroup::EvaluateObjectRules);
|
||||
ObjectRule::RegisterType("UserGroup");
|
||||
}
|
||||
|
||||
bool UserGroup::EvaluateObjectRuleOne(const User::Ptr& user, const ObjectRule& rule)
|
||||
bool UserGroup::EvaluateObjectRule(const User::Ptr& user, const ConfigItem::Ptr& group)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
String group_name = group->GetName();
|
||||
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Evaluating 'object' rule (" << di << ")";
|
||||
CONTEXT(msgbuf.str());
|
||||
CONTEXT("Evaluating rule for group '" + group_name + "'");
|
||||
|
||||
Dictionary::Ptr locals = new Dictionary();
|
||||
locals->Set("__parent", rule.GetScope());
|
||||
locals->Set("__parent", group->GetScope());
|
||||
locals->Set("user", user);
|
||||
|
||||
if (!rule.EvaluateFilter(locals))
|
||||
if (!group->GetFilter()->Evaluate(locals))
|
||||
return false;
|
||||
|
||||
Log(LogDebug, "UserGroup")
|
||||
<< "Assigning membership for group '" << rule.GetName() << "' to user '" << user->GetName() << "' for rule " << di;
|
||||
<< "Assigning membership for group '" << group_name << "' to user '" << user->GetName() << "'";
|
||||
|
||||
String group_name = rule.GetName();
|
||||
UserGroup::Ptr group = UserGroup::GetByName(group_name);
|
||||
UserGroup::Ptr groupObject = UserGroup::GetByName(group_name);
|
||||
|
||||
if (!group) {
|
||||
if (!groupObject) {
|
||||
Log(LogCritical, "UserGroup")
|
||||
<< "Invalid membership assignment. Group '" << group_name << "' does not exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
/* assign user group membership */
|
||||
group->ResolveGroupMembership(user, true);
|
||||
groupObject->ResolveGroupMembership(user, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UserGroup::EvaluateObjectRule(const ObjectRule& rule)
|
||||
void UserGroup::EvaluateObjectRules(const User::Ptr& user)
|
||||
{
|
||||
BOOST_FOREACH(const User::Ptr& user, DynamicType::GetObjectsByType<User>()) {
|
||||
CONTEXT("Evaluating group membership in '" + rule.GetName() + "' for user '" + user->GetName() + "'");
|
||||
CONTEXT("Evaluating group membership for user '" + user->GetName() + "'");
|
||||
|
||||
EvaluateObjectRuleOne(user, rule);
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& group, ConfigItem::GetItems("UserGroup"))
|
||||
{
|
||||
if (!group->GetFilter())
|
||||
continue;
|
||||
|
||||
EvaluateObjectRule(user, group);
|
||||
}
|
||||
}
|
||||
|
||||
void UserGroup::EvaluateObjectRules(const std::vector<ObjectRule>& rules)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
|
||||
BOOST_FOREACH(const ObjectRule& rule, rules) {
|
||||
upq.Enqueue(boost::bind(UserGroup::EvaluateObjectRule, boost::cref(rule)));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
}
|
||||
|
||||
std::set<User::Ptr> UserGroup::GetMembers(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_UserGroupMutex);
|
||||
|
@ -27,7 +27,7 @@
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
class ObjectRule;
|
||||
class ConfigItem;
|
||||
|
||||
/**
|
||||
* An Icinga user group.
|
||||
@ -48,13 +48,13 @@ public:
|
||||
|
||||
static void RegisterObjectRuleHandler(void);
|
||||
|
||||
static void EvaluateObjectRules(const User::Ptr& user);
|
||||
|
||||
private:
|
||||
mutable boost::mutex m_UserGroupMutex;
|
||||
std::set<User::Ptr> m_Members;
|
||||
|
||||
static bool EvaluateObjectRuleOne(const User::Ptr& user, const ObjectRule& rule);
|
||||
static void EvaluateObjectRule(const ObjectRule& rule);
|
||||
static void EvaluateObjectRules(const std::vector<ObjectRule>& rules);
|
||||
static bool EvaluateObjectRule(const User::Ptr& user, const intrusive_ptr<ConfigItem>& group);
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user