Implement apply target types.

Fixes #5924
This commit is contained in:
Gunnar Beutner 2014-04-05 12:56:56 +02:00
parent 5ccdf017ac
commit 5e38c81eb5
16 changed files with 378 additions and 197 deletions

View File

@ -6,6 +6,14 @@ template Host "generic-host" {
check_command = "hostalive" check_command = "hostalive"
} }
apply Notification "mail-icingaadmin" to Host {
import "mail-notification"
user_groups = [ "icingaadmins"]
assign where "generic-host" in host.templates
}
template Host "linux-server" { template Host "linux-server" {
import "generic-host" import "generic-host"

View File

@ -9,7 +9,7 @@ template Service "generic-service" {
enable_perfdata = true enable_perfdata = true
} }
apply Notification "mail-icingaadmin" { apply Notification "mail-icingaadmin" to Service {
import "mail-notification" import "mail-notification"
user_groups = [ "icingaadmins"] user_groups = [ "icingaadmins"]

View File

@ -42,7 +42,7 @@ apply Service "load" {
assign where host.name == "localhost" assign where host.name == "localhost"
} }
apply ScheduledDowntime "backup-downtime" { apply ScheduledDowntime "backup-downtime" to Service {
import "backup-downtime" import "backup-downtime"
assign where host.name == "localhost" && service.name == "load" assign where host.name == "localhost" && service.name == "load"

View File

@ -499,12 +499,13 @@ Value AExpression::OpApply(const AExpression* expr, const Dictionary::Ptr& local
Array::Ptr left = expr->m_Operand1; Array::Ptr left = expr->m_Operand1;
AExpression::Ptr exprl = expr->m_Operand2; AExpression::Ptr exprl = expr->m_Operand2;
String type = left->Get(0); String type = left->Get(0);
AExpression::Ptr aname = left->Get(1); String target = left->Get(1);
AExpression::Ptr filter = left->Get(2); AExpression::Ptr aname = left->Get(2);
AExpression::Ptr filter = left->Get(3);
String name = aname->Evaluate(locals); String name = aname->Evaluate(locals);
ApplyRule::AddRule(type, name, exprl, filter, expr->m_DebugInfo, locals); ApplyRule::AddRule(type, target, name, exprl, filter, expr->m_DebugInfo, locals);
return Empty; return Empty;
} }

View File

@ -25,11 +25,16 @@ using namespace icinga;
ApplyRule::RuleMap ApplyRule::m_Rules; ApplyRule::RuleMap ApplyRule::m_Rules;
ApplyRule::CallbackMap ApplyRule::m_Callbacks; ApplyRule::CallbackMap ApplyRule::m_Callbacks;
ApplyRule::ApplyRule(const String& name, const AExpression::Ptr& expression, ApplyRule::ApplyRule(const String& targetType, const String& name, const AExpression::Ptr& expression,
const AExpression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope) const AExpression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope)
: m_Name(name), m_Expression(expression), m_Filter(filter), m_DebugInfo(di), m_Scope(scope) : m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_DebugInfo(di), m_Scope(scope)
{ } { }
String ApplyRule::GetTargetType(void) const
{
return m_TargetType;
}
String ApplyRule::GetName(void) const String ApplyRule::GetName(void) const
{ {
return m_Name; return m_Name;
@ -55,11 +60,11 @@ Dictionary::Ptr ApplyRule::GetScope(void) const
return m_Scope; return m_Scope;
} }
void ApplyRule::AddRule(const String& sourceType, const String& name, void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
const AExpression::Ptr& expression, const AExpression::Ptr& filter, const AExpression::Ptr& expression, const AExpression::Ptr& filter,
const DebugInfo& di, const Dictionary::Ptr& scope) const DebugInfo& di, const Dictionary::Ptr& scope)
{ {
m_Rules[sourceType].push_back(ApplyRule(name, expression, filter, di, scope)); m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, di, scope));
} }
bool ApplyRule::EvaluateFilter(const Dictionary::Ptr& scope) const bool ApplyRule::EvaluateFilter(const Dictionary::Ptr& scope) const
@ -75,7 +80,7 @@ void ApplyRule::EvaluateRules(void)
std::set<String> completedTypes; std::set<String> completedTypes;
while (completedTypes.size() < m_Callbacks.size()) { while (completedTypes.size() < m_Callbacks.size()) {
std::pair<String, std::pair<Callback, String> > kv; std::pair<String, std::pair<Callback, std::vector<String> > > kv;
BOOST_FOREACH(kv, m_Callbacks) { BOOST_FOREACH(kv, m_Callbacks) {
const String& sourceType = kv.first; const String& sourceType = kv.first;
@ -83,10 +88,16 @@ void ApplyRule::EvaluateRules(void)
continue; continue;
const Callback& callback = kv.second.first; const Callback& callback = kv.second.first;
const String& targetType = kv.second.second; const std::vector<String>& targetTypes = kv.second.second;
if (IsValidType(targetType) && completedTypes.find(targetType) == completedTypes.end()) bool cont = false;
continue;
BOOST_FOREACH(const String& targetType, targetTypes) {
if (IsValidSourceType(targetType) && completedTypes.find(targetType) == completedTypes.end()) {
cont = true;
break;
}
}
completedTypes.insert(sourceType); completedTypes.insert(sourceType);
@ -102,12 +113,41 @@ void ApplyRule::EvaluateRules(void)
m_Rules.clear(); m_Rules.clear();
} }
void ApplyRule::RegisterType(const String& sourceType, const String& targetType, const ApplyRule::Callback& callback) void ApplyRule::RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback)
{ {
m_Callbacks[sourceType] = make_pair(callback, targetType); m_Callbacks[sourceType] = make_pair(callback, targetTypes);
} }
bool ApplyRule::IsValidType(const String& sourceType) bool ApplyRule::IsValidSourceType(const String& sourceType)
{ {
return m_Callbacks.find(sourceType) != m_Callbacks.end(); return m_Callbacks.find(sourceType) != m_Callbacks.end();
} }
bool ApplyRule::IsValidTargetType(const String& sourceType, const String& targetType)
{
CallbackMap::const_iterator it = m_Callbacks.find(sourceType);
if (it == m_Callbacks.end())
return false;
if (it->second.second.size() == 1 && targetType == "")
return true;
BOOST_FOREACH(const String& type, it->second.second) {
if (type == targetType)
return true;
}
return false;
}
std::vector<String> ApplyRule::GetTargetTypes(const String& sourceType)
{
CallbackMap::const_iterator it = m_Callbacks.find(sourceType);
if (it == m_Callbacks.end())
return std::vector<String>();
return it->second.second;
}

View File

@ -35,9 +35,10 @@ class I2_CONFIG_API ApplyRule
{ {
public: public:
typedef boost::function<void (const std::vector<ApplyRule>& rules)> Callback; typedef boost::function<void (const std::vector<ApplyRule>& rules)> Callback;
typedef std::map<String, std::pair<Callback, String> > CallbackMap; typedef std::map<String, std::pair<Callback, std::vector<String> > > CallbackMap;
typedef std::map<String, std::vector<ApplyRule> > RuleMap; typedef std::map<String, std::vector<ApplyRule> > RuleMap;
String GetTargetType(void) const;
String GetName(void) const; String GetName(void) const;
AExpression::Ptr GetExpression(void) const; AExpression::Ptr GetExpression(void) const;
AExpression::Ptr GetFilter(void) const; AExpression::Ptr GetFilter(void) const;
@ -46,14 +47,17 @@ public:
bool EvaluateFilter(const Dictionary::Ptr& scope) const; bool EvaluateFilter(const Dictionary::Ptr& scope) const;
static void AddRule(const String& sourceType, const String& name, const AExpression::Ptr& expression, static void AddRule(const String& sourceType, const String& targetType, const String& name, const AExpression::Ptr& expression,
const AExpression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope); const AExpression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope);
static void EvaluateRules(void); static void EvaluateRules(void);
static void RegisterType(const String& sourceType, const String& targetType, const ApplyRule::Callback& callback); static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
static bool IsValidType(const String& sourceType); static bool IsValidSourceType(const String& sourceType);
static bool IsValidTargetType(const String& sourceType, const String& targetType);
static std::vector<String> GetTargetTypes(const String& sourceType);
private: private:
String m_TargetType;
String m_Name; String m_Name;
AExpression::Ptr m_Expression; AExpression::Ptr m_Expression;
AExpression::Ptr m_Filter; AExpression::Ptr m_Filter;
@ -63,7 +67,7 @@ private:
static CallbackMap m_Callbacks; static CallbackMap m_Callbacks;
static RuleMap m_Rules; static RuleMap m_Rules;
ApplyRule(const String& tmpl, const AExpression::Ptr& expression, ApplyRule(const String& targetType, const String& name, const AExpression::Ptr& expression,
const AExpression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope); const AExpression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope);
}; };

View File

@ -222,6 +222,7 @@ true { yylval->num = 1; return T_NUMBER; }
false { yylval->num = 0; return T_NUMBER; } false { yylval->num = 0; return T_NUMBER; }
const return T_CONST; const return T_CONST;
apply return T_APPLY; apply return T_APPLY;
to return T_TO;
where return T_WHERE; where return T_WHERE;
import return T_IMPORT; import return T_IMPORT;
assign return T_ASSIGN; assign return T_ASSIGN;

View File

@ -151,6 +151,7 @@ static void MakeRBinaryOp(Value** result, AExpression::OpCallback& op, Value *le
%token T_INHERITS "inherits (T_INHERITS)" %token T_INHERITS "inherits (T_INHERITS)"
%token T_PARTIAL "partial (T_PARTIAL)" %token T_PARTIAL "partial (T_PARTIAL)"
%token T_APPLY "apply (T_APPLY)" %token T_APPLY "apply (T_APPLY)"
%token T_TO "to (T_TO)"
%token T_WHERE "where (T_WHERE)" %token T_WHERE "where (T_WHERE)"
%token T_IMPORT "import (T_IMPORT)" %token T_IMPORT "import (T_IMPORT)"
%token T_ASSIGN "assign (T_ASSIGN)" %token T_ASSIGN "assign (T_ASSIGN)"
@ -174,6 +175,7 @@ static void MakeRBinaryOp(Value** result, AExpression::OpCallback& op, Value *le
%type <variant> lterm %type <variant> lterm
%type <variant> object %type <variant> object
%type <variant> apply %type <variant> apply
%type <text> target_type_specifier
%left T_LOGICAL_OR %left T_LOGICAL_OR
%left T_LOGICAL_AND %left T_LOGICAL_AND
@ -792,26 +794,59 @@ rterm: T_STRING
} }
; ;
target_type_specifier: /* empty */
{
$$ = strdup("");
}
| T_TO identifier
{
$$ = $2;
}
;
apply: apply:
{ {
m_Apply = true; m_Apply = true;
m_Assign = make_shared<AExpression>(&AExpression::OpLiteral, false, DebugInfo()); m_Assign = make_shared<AExpression>(&AExpression::OpLiteral, false, DebugInfo());
m_Ignore = make_shared<AExpression>(&AExpression::OpLiteral, false, DebugInfo()); m_Ignore = make_shared<AExpression>(&AExpression::OpLiteral, false, DebugInfo());
} }
T_APPLY identifier rterm rterm T_APPLY identifier rterm target_type_specifier rterm
{ {
m_Apply = false; m_Apply = false;
AExpression::Ptr aname = static_cast<AExpression::Ptr>(*$4);
delete $4;
String type = $3; String type = $3;
free($3); free($3);
AExpression::Ptr aname = static_cast<AExpression::Ptr>(*$4);
delete $4;
String target = $5;
free($5);
if (!ApplyRule::IsValidType(type)) if (!ApplyRule::IsValidSourceType(type))
BOOST_THROW_EXCEPTION(ConfigError("'apply' cannot be used with type '" + type + "'") << errinfo_debuginfo(DebugInfoRange(@2, @3))); BOOST_THROW_EXCEPTION(ConfigError("'apply' cannot be used with type '" + type + "'") << errinfo_debuginfo(DebugInfoRange(@2, @3)));
AExpression::Ptr exprl = static_cast<AExpression::Ptr>(*$5); if (!ApplyRule::IsValidTargetType(type, target)) {
delete $5; if (target == "") {
std::vector<String> types = ApplyRule::GetTargetTypes(type);
String typeNames;
for (int i = 0; i < types.size(); i++) {
if (typeNames != "") {
if (i == types.size() - 1)
typeNames += " or ";
else
typeNames += ", ";
}
typeNames += "'" + types[i] + "'";
}
BOOST_THROW_EXCEPTION(ConfigError("'apply' target type is ambiguous (can be one of " + typeNames + "): use 'to' to specify a type") << errinfo_debuginfo(DebugInfoRange(@2, @3)));
} else
BOOST_THROW_EXCEPTION(ConfigError("'apply' target type '" + target + "' is invalid") << errinfo_debuginfo(DebugInfoRange(@2, @5)));
}
AExpression::Ptr exprl = static_cast<AExpression::Ptr>(*$6);
delete $6;
exprl->MakeInline(); exprl->MakeInline();
@ -821,6 +856,7 @@ apply:
Array::Ptr args = make_shared<Array>(); Array::Ptr args = make_shared<Array>();
args->Add(type); args->Add(type);
args->Add(target);
args->Add(aname); args->Add(aname);
args->Add(filter); args->Add(filter);

View File

@ -33,34 +33,38 @@ INITIALIZE_ONCE(&Dependency::RegisterApplyRuleHandler);
void Dependency::RegisterApplyRuleHandler(void) void Dependency::RegisterApplyRuleHandler(void)
{ {
ApplyRule::RegisterType("Dependency", "Service", &Dependency::EvaluateApplyRules); std::vector<String> targets;
targets.push_back("Host");
targets.push_back("Service");
ApplyRule::RegisterType("Dependency", targets, &Dependency::EvaluateApplyRules);
} }
void Dependency::EvaluateApplyRules(const std::vector<ApplyRule>& rules) void Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
{ {
BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects<Service>()) {
CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'");
Dictionary::Ptr locals = make_shared<Dictionary>();
locals->Set("host", service->GetHost());
locals->Set("service", service);
BOOST_FOREACH(const ApplyRule& rule, rules) {
DebugInfo di = rule.GetDebugInfo(); DebugInfo di = rule.GetDebugInfo();
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "Evaluating 'apply' rule (" << di << ")"; msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str()); CONTEXT(msgbuf.str());
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
Dictionary::Ptr locals = make_shared<Dictionary>();
locals->Set("host", host);
if (service)
locals->Set("service", service);
if (!rule.EvaluateFilter(locals)) if (!rule.EvaluateFilter(locals))
continue; return;
std::ostringstream msgbuf2; std::ostringstream msgbuf2;
msgbuf2 << "Applying dependency '" << rule.GetName() << "' to service '" << service->GetName() << "' for rule " << di; msgbuf2 << "Applying dependency '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
Log(LogDebug, "icinga", msgbuf2.str()); Log(LogDebug, "icinga", msgbuf2.str());
std::ostringstream namebuf; std::ostringstream namebuf;
namebuf << service->GetName() << "!" << rule.GetName(); namebuf << checkable->GetName() << "!" << rule.GetName();
String name = namebuf.str(); String name = namebuf.str();
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di); ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
@ -70,19 +74,44 @@ void Dependency::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "child_host_name", di), make_shared<AExpression>(&AExpression::OpLiteral, "child_host_name", di),
make_shared<AExpression>(&AExpression::OpLiteral, service->GetHost()->GetName(), make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(),
di), di)); di), di));
if (service) {
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "child_service_name", di), make_shared<AExpression>(&AExpression::OpLiteral, "child_service_name", di),
make_shared<AExpression>(&AExpression::OpLiteral, service->GetShortName(), di), di)); make_shared<AExpression>(&AExpression::OpLiteral, service->GetShortName(), di), di));
}
builder->AddExpression(rule.GetExpression()); builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr serviceItem = builder->Compile(); ConfigItem::Ptr dependencyItem = builder->Compile();
serviceItem->Register(); dependencyItem->Register();
DynamicObject::Ptr dobj = serviceItem->Commit(); DynamicObject::Ptr dobj = dependencyItem->Commit();
dobj->OnConfigLoaded(); dobj->OnConfigLoaded();
} }
void Dependency::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
{
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjects<Host>()) {
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
BOOST_FOREACH(const ApplyRule& rule, rules) {
if (rule.GetTargetType() != "Host")
continue;
EvaluateApplyRule(host, rule);
}
}
BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects<Service>()) {
CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'");
BOOST_FOREACH(const ApplyRule& rule, rules) {
if (rule.GetTargetType() != "Service")
continue;
EvaluateApplyRule(service, rule);
}
} }
} }

View File

@ -48,11 +48,14 @@ public:
bool IsAvailable(DependencyType dt) const; bool IsAvailable(DependencyType dt) const;
static void RegisterApplyRuleHandler(void); static void RegisterApplyRuleHandler(void);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
protected: protected:
virtual void OnStateLoaded(void); virtual void OnStateLoaded(void);
virtual void Stop(void); virtual void Stop(void);
private:
static void EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
}; };
} }

View File

@ -32,34 +32,38 @@ INITIALIZE_ONCE(&Notification::RegisterApplyRuleHandler);
void Notification::RegisterApplyRuleHandler(void) void Notification::RegisterApplyRuleHandler(void)
{ {
ApplyRule::RegisterType("Notification", "Service", &Notification::EvaluateApplyRules); std::vector<String> targets;
targets.push_back("Host");
targets.push_back("Service");
ApplyRule::RegisterType("Notification", targets, &Notification::EvaluateApplyRules);
} }
void Notification::EvaluateApplyRules(const std::vector<ApplyRule>& rules) void Notification::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
{ {
BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects<Service>()) {
CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'");
Dictionary::Ptr locals = make_shared<Dictionary>();
locals->Set("host", service->GetHost());
locals->Set("service", service);
BOOST_FOREACH(const ApplyRule& rule, rules) {
DebugInfo di = rule.GetDebugInfo(); DebugInfo di = rule.GetDebugInfo();
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "Evaluating 'apply' rule (" << di << ")"; msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str()); CONTEXT(msgbuf.str());
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
Dictionary::Ptr locals = make_shared<Dictionary>();
locals->Set("host", host);
if (service)
locals->Set("service", service);
if (!rule.EvaluateFilter(locals)) if (!rule.EvaluateFilter(locals))
continue; return;
std::ostringstream msgbuf2; std::ostringstream msgbuf2;
msgbuf2 << "Applying notification '" << rule.GetName() << "' to service '" << service->GetName() << "' for rule " << di; msgbuf2 << "Applying notification '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
Log(LogDebug, "icinga", msgbuf2.str()); Log(LogDebug, "icinga", msgbuf2.str());
std::ostringstream namebuf; std::ostringstream namebuf;
namebuf << service->GetName() << "!" << rule.GetName(); namebuf << checkable->GetName() << "!" << rule.GetName();
String name = namebuf.str(); String name = namebuf.str();
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di); ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
@ -69,20 +73,45 @@ void Notification::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "host_name", di), make_shared<AExpression>(&AExpression::OpLiteral, "host_name", di),
make_shared<AExpression>(&AExpression::OpLiteral, service->GetHost()->GetName(), di), make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), di),
di)); di));
if (service) {
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "service_name", di), make_shared<AExpression>(&AExpression::OpLiteral, "service_name", di),
make_shared<AExpression>(&AExpression::OpLiteral, service->GetShortName(), di), make_shared<AExpression>(&AExpression::OpLiteral, service->GetShortName(), di),
di)); di));
}
builder->AddExpression(rule.GetExpression()); builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr serviceItem = builder->Compile(); ConfigItem::Ptr notificationItem = builder->Compile();
serviceItem->Register(); notificationItem->Register();
DynamicObject::Ptr dobj = serviceItem->Commit(); DynamicObject::Ptr dobj = notificationItem->Commit();
dobj->OnConfigLoaded(); dobj->OnConfigLoaded();
} }
void Notification::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
{
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjects<Host>()) {
CONTEXT("Evaluating 'apply' rules for Host '" + host->GetName() + "'");
BOOST_FOREACH(const ApplyRule& rule, rules) {
if (rule.GetTargetType() != "Host")
continue;
EvaluateApplyRule(host, rule);
}
}
BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects<Service>()) {
CONTEXT("Evaluating 'apply' rules for Service '" + service->GetName() + "'");
BOOST_FOREACH(const ApplyRule& rule, rules) {
if (rule.GetTargetType() != "Service")
continue;
EvaluateApplyRule(service, rule);
}
} }
} }

View File

@ -88,7 +88,6 @@ public:
static boost::signals2::signal<void (const Notification::Ptr&, double, const String&)> OnNextNotificationChanged; static boost::signals2::signal<void (const Notification::Ptr&, double, const String&)> OnNextNotificationChanged;
static void RegisterApplyRuleHandler(void); static void RegisterApplyRuleHandler(void);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
protected: protected:
virtual void Start(void); virtual void Start(void);
@ -96,6 +95,9 @@ protected:
private: private:
void ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const CheckResult::Ptr& cr, bool force, const String& author = "", const String& text = ""); void ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const CheckResult::Ptr& cr, bool force, const String& author = "", const String& text = "");
static void EvaluateApplyRule(const shared_ptr<Checkable>& checkable, const ApplyRule& rule);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
}; };
} }

View File

@ -32,7 +32,63 @@ INITIALIZE_ONCE(&ScheduledDowntime::RegisterApplyRuleHandler);
void ScheduledDowntime::RegisterApplyRuleHandler(void) void ScheduledDowntime::RegisterApplyRuleHandler(void)
{ {
ApplyRule::RegisterType("ScheduledDowntime", "Service", &ScheduledDowntime::EvaluateApplyRules); std::vector<String> targets;
targets.push_back("Host");
targets.push_back("Service");
ApplyRule::RegisterType("ScheduledDowntime", targets, &ScheduledDowntime::EvaluateApplyRules);
}
void ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
{
DebugInfo di = rule.GetDebugInfo();
std::ostringstream msgbuf;
msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str());
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
Dictionary::Ptr locals = make_shared<Dictionary>();
locals->Set("host", host);
if (service)
locals->Set("service", service);
if (!rule.EvaluateFilter(locals))
return;
std::ostringstream msgbuf2;
msgbuf2 << "Applying scheduled downtime '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
Log(LogDebug, "icinga", msgbuf2.str());
std::ostringstream namebuf;
namebuf << checkable->GetName() << "!" << rule.GetName();
String name = namebuf.str();
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("ScheduledDowntime");
builder->SetName(name);
builder->SetScope(rule.GetScope());
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "host_name", di),
make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), di),
di));
if (service) {
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "service_name", di),
make_shared<AExpression>(&AExpression::OpLiteral, service->GetShortName(), di),
di));
}
builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr downtimeItem = builder->Compile();
downtimeItem->Register();
DynamicObject::Ptr dobj = downtimeItem->Commit();
dobj->OnConfigLoaded();
} }
void ScheduledDowntime::EvaluateApplyRules(const std::vector<ApplyRule>& rules) void ScheduledDowntime::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
@ -45,44 +101,6 @@ void ScheduledDowntime::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
locals->Set("service", service); locals->Set("service", service);
BOOST_FOREACH(const ApplyRule& rule, rules) { BOOST_FOREACH(const ApplyRule& rule, rules) {
DebugInfo di = rule.GetDebugInfo();
std::ostringstream msgbuf;
msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str());
if (!rule.EvaluateFilter(locals))
continue;
std::ostringstream msgbuf2;
msgbuf2 << "Applying scheduled downtime '" << rule.GetName() << "' to service '" << service->GetName() << "' for rule " << di;
Log(LogDebug, "icinga", msgbuf2.str());
std::ostringstream namebuf;
namebuf << service->GetName() << "!" << rule.GetName();
String name = namebuf.str();
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("ScheduledDowntime");
builder->SetName(name);
builder->SetScope(rule.GetScope());
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "host_name", di),
make_shared<AExpression>(&AExpression::OpLiteral, service->GetHost()->GetName(), di),
di));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "service_name", di),
make_shared<AExpression>(&AExpression::OpLiteral, service->GetShortName(), di),
di));
builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr serviceItem = builder->Compile();
serviceItem->Register();
DynamicObject::Ptr dobj = serviceItem->Commit();
dobj->OnConfigLoaded();
} }
} }
} }

View File

@ -45,7 +45,6 @@ public:
Checkable::Ptr GetCheckable(void) const; Checkable::Ptr GetCheckable(void) const;
static void RegisterApplyRuleHandler(void); static void RegisterApplyRuleHandler(void);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
protected: protected:
virtual void Start(void); virtual void Start(void);
@ -55,6 +54,9 @@ private:
std::pair<double, double> FindNextSegment(void); std::pair<double, double> FindNextSegment(void);
void CreateNextDowntime(void); void CreateNextDowntime(void);
static void EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
}; };
} }

View File

@ -32,26 +32,24 @@ INITIALIZE_ONCE(&Service::RegisterApplyRuleHandler);
void Service::RegisterApplyRuleHandler(void) void Service::RegisterApplyRuleHandler(void)
{ {
ApplyRule::RegisterType("Service", "Host", &Service::EvaluateApplyRules); std::vector<String> targets;
targets.push_back("Host");
ApplyRule::RegisterType("Service", targets, &Service::EvaluateApplyRules);
} }
void Service::EvaluateApplyRules(const std::vector<ApplyRule>& rules) void Service::EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule)
{ {
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjects<Host>()) {
CONTEXT("Evaluating 'apply' rules for Host '" + host->GetName() + "'");
Dictionary::Ptr locals = make_shared<Dictionary>();
locals->Set("host", host);
BOOST_FOREACH(const ApplyRule& rule, rules) {
DebugInfo di = rule.GetDebugInfo(); DebugInfo di = rule.GetDebugInfo();
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "Evaluating 'apply' rule (" << di << ")"; msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str()); CONTEXT(msgbuf.str());
Dictionary::Ptr locals = make_shared<Dictionary>();
locals->Set("host", host);
if (!rule.EvaluateFilter(locals)) if (!rule.EvaluateFilter(locals))
continue; return;
std::ostringstream msgbuf2; std::ostringstream msgbuf2;
msgbuf2 << "Applying service '" << rule.GetName() << "' to host '" << host->GetName() << "' for rule " << di; msgbuf2 << "Applying service '" << rule.GetName() << "' to host '" << host->GetName() << "' for rule " << di;
@ -83,5 +81,13 @@ void Service::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
DynamicObject::Ptr dobj = serviceItem->Commit(); DynamicObject::Ptr dobj = serviceItem->Commit();
dobj->OnConfigLoaded(); dobj->OnConfigLoaded();
} }
void Service::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
{
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjects<Host>()) {
CONTEXT("Evaluating 'apply' rules for Host '" + host->GetName() + "'");
BOOST_FOREACH(const ApplyRule& rule, rules)
EvaluateApplyRule(host, rule);
} }
} }

View File

@ -60,13 +60,15 @@ public:
static String StateTypeToString(StateType state); static String StateTypeToString(StateType state);
static void RegisterApplyRuleHandler(void); static void RegisterApplyRuleHandler(void);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
protected: protected:
virtual void OnConfigLoaded(void); virtual void OnConfigLoaded(void);
private: private:
Host::Ptr m_Host; Host::Ptr m_Host;
static void EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
}; };
I2_ICINGA_API boost::tuple<Host::Ptr, Service::Ptr> GetHostService(const Checkable::Ptr& checkable); I2_ICINGA_API boost::tuple<Host::Ptr, Service::Ptr> GetHostService(const Checkable::Ptr& checkable);