Refactor apply/object rules

fixes #7700
This commit is contained in:
Gunnar Beutner 2014-11-16 16:20:39 +01:00
parent ee89f54679
commit 0078e00c13
26 changed files with 374 additions and 491 deletions

View File

@ -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();
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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);
};
}

View File

@ -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);
}

View File

@ -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. */

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
};
}

View File

@ -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();
}

View File

@ -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);
};
}

View File

@ -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)

View File

@ -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);

View File

@ -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);
};
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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);
};
}

View File

@ -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();
}

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);
};
}

View File

@ -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)

View File

@ -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);

View File

@ -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);
};
}