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"
}
apply Notification "mail-icingaadmin" to Host {
import "mail-notification"
user_groups = [ "icingaadmins"]
assign where "generic-host" in host.templates
}
template Host "linux-server" {
import "generic-host"

View File

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

View File

@ -42,7 +42,7 @@ apply Service "load" {
assign where host.name == "localhost"
}
apply ScheduledDowntime "backup-downtime" {
apply ScheduledDowntime "backup-downtime" to Service {
import "backup-downtime"
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;
AExpression::Ptr exprl = expr->m_Operand2;
String type = left->Get(0);
AExpression::Ptr aname = left->Get(1);
AExpression::Ptr filter = left->Get(2);
String target = left->Get(1);
AExpression::Ptr aname = left->Get(2);
AExpression::Ptr filter = left->Get(3);
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;
}

View File

@ -25,11 +25,16 @@ using namespace icinga;
ApplyRule::RuleMap ApplyRule::m_Rules;
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)
: 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
{
return m_Name;
@ -55,11 +60,11 @@ Dictionary::Ptr ApplyRule::GetScope(void) const
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 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
@ -75,7 +80,7 @@ void ApplyRule::EvaluateRules(void)
std::set<String> completedTypes;
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) {
const String& sourceType = kv.first;
@ -83,10 +88,16 @@ void ApplyRule::EvaluateRules(void)
continue;
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())
continue;
bool cont = false;
BOOST_FOREACH(const String& targetType, targetTypes) {
if (IsValidSourceType(targetType) && completedTypes.find(targetType) == completedTypes.end()) {
cont = true;
break;
}
}
completedTypes.insert(sourceType);
@ -102,12 +113,41 @@ void ApplyRule::EvaluateRules(void)
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();
}
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:
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;
String GetTargetType(void) const;
String GetName(void) const;
AExpression::Ptr GetExpression(void) const;
AExpression::Ptr GetFilter(void) const;
@ -46,14 +47,17 @@ public:
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);
static void EvaluateRules(void);
static void RegisterType(const String& sourceType, const String& targetType, const ApplyRule::Callback& callback);
static bool IsValidType(const String& sourceType);
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
static bool IsValidSourceType(const String& sourceType);
static bool IsValidTargetType(const String& sourceType, const String& targetType);
static std::vector<String> GetTargetTypes(const String& sourceType);
private:
String m_TargetType;
String m_Name;
AExpression::Ptr m_Expression;
AExpression::Ptr m_Filter;
@ -63,7 +67,7 @@ private:
static CallbackMap m_Callbacks;
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);
};

View File

@ -222,6 +222,7 @@ true { yylval->num = 1; return T_NUMBER; }
false { yylval->num = 0; return T_NUMBER; }
const return T_CONST;
apply return T_APPLY;
to return T_TO;
where return T_WHERE;
import return T_IMPORT;
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_PARTIAL "partial (T_PARTIAL)"
%token T_APPLY "apply (T_APPLY)"
%token T_TO "to (T_TO)"
%token T_WHERE "where (T_WHERE)"
%token T_IMPORT "import (T_IMPORT)"
%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> object
%type <variant> apply
%type <text> target_type_specifier
%left T_LOGICAL_OR
%left T_LOGICAL_AND
@ -792,26 +794,59 @@ rterm: T_STRING
}
;
target_type_specifier: /* empty */
{
$$ = strdup("");
}
| T_TO identifier
{
$$ = $2;
}
;
apply:
{
m_Apply = true;
m_Assign = 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;
AExpression::Ptr aname = static_cast<AExpression::Ptr>(*$4);
delete $4;
String type = $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)));
AExpression::Ptr exprl = static_cast<AExpression::Ptr>(*$5);
delete $5;
if (!ApplyRule::IsValidTargetType(type, target)) {
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();
@ -821,6 +856,7 @@ apply:
Array::Ptr args = make_shared<Array>();
args->Add(type);
args->Add(target);
args->Add(aname);
args->Add(filter);

View File

@ -33,56 +33,85 @@ INITIALIZE_ONCE(&Dependency::RegisterApplyRuleHandler);
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::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 dependency '" << 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("Dependency");
builder->SetName(name);
builder->SetScope(rule.GetScope());
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "child_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, "child_service_name", di),
make_shared<AExpression>(&AExpression::OpLiteral, service->GetShortName(), di), di));
}
builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr dependencyItem = builder->Compile();
dependencyItem->Register();
DynamicObject::Ptr dobj = dependencyItem->Commit();
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() + "'");
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();
std::ostringstream msgbuf;
msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str());
if (!rule.EvaluateFilter(locals))
if (rule.GetTargetType() != "Service")
continue;
std::ostringstream msgbuf2;
msgbuf2 << "Applying dependency '" << 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("Dependency");
builder->SetName(name);
builder->SetScope(rule.GetScope());
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "child_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, "child_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();
EvaluateApplyRule(service, rule);
}
}
}

View File

@ -48,11 +48,14 @@ public:
bool IsAvailable(DependencyType dt) const;
static void RegisterApplyRuleHandler(void);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
protected:
virtual void OnStateLoaded(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,57 +32,86 @@ INITIALIZE_ONCE(&Notification::RegisterApplyRuleHandler);
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::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 notification '" << 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("Notification");
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 notificationItem = builder->Compile();
notificationItem->Register();
DynamicObject::Ptr dobj = notificationItem->Commit();
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() + "'");
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();
std::ostringstream msgbuf;
msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str());
if (!rule.EvaluateFilter(locals))
if (rule.GetTargetType() != "Service")
continue;
std::ostringstream msgbuf2;
msgbuf2 << "Applying notification '" << 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("Notification");
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();
EvaluateApplyRule(service, rule);
}
}
}

View File

@ -88,14 +88,16 @@ public:
static boost::signals2::signal<void (const Notification::Ptr&, double, const String&)> OnNextNotificationChanged;
static void RegisterApplyRuleHandler(void);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
protected:
virtual void Start(void);
virtual void Stop(void);
private:
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)
{
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)
@ -45,44 +101,6 @@ void ScheduledDowntime::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
locals->Set("service", service);
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,8 +45,7 @@ public:
Checkable::Ptr GetCheckable(void) const;
static void RegisterApplyRuleHandler(void);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
protected:
virtual void Start(void);
@ -55,6 +54,9 @@ private:
std::pair<double, double> FindNextSegment(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,7 +32,54 @@ INITIALIZE_ONCE(&Service::RegisterApplyRuleHandler);
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::EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule)
{
DebugInfo di = rule.GetDebugInfo();
std::ostringstream msgbuf;
msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str());
Dictionary::Ptr locals = make_shared<Dictionary>();
locals->Set("host", host);
if (!rule.EvaluateFilter(locals))
return;
std::ostringstream msgbuf2;
msgbuf2 << "Applying service '" << rule.GetName() << "' to host '" << host->GetName() << "' for rule " << di;
Log(LogDebug, "icinga", msgbuf2.str());
std::ostringstream namebuf;
namebuf << host->GetName() << "!" << rule.GetName();
String name = namebuf.str();
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("Service");
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));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "name", di),
make_shared<AExpression>(&AExpression::OpLiteral, rule.GetName(), di),
di));
builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr serviceItem = builder->Compile();
serviceItem->Register();
DynamicObject::Ptr dobj = serviceItem->Commit();
dobj->OnConfigLoaded();
}
void Service::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
@ -40,48 +87,7 @@ 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() + "'");
Dictionary::Ptr locals = make_shared<Dictionary>();
locals->Set("host", host);
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 service '" << rule.GetName() << "' to host '" << host->GetName() << "' for rule " << di;
Log(LogDebug, "icinga", msgbuf2.str());
std::ostringstream namebuf;
namebuf << host->GetName() << "!" << rule.GetName();
String name = namebuf.str();
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
builder->SetType("Service");
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));
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet,
make_shared<AExpression>(&AExpression::OpLiteral, "name", di),
make_shared<AExpression>(&AExpression::OpLiteral, rule.GetName(), di),
di));
builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr serviceItem = builder->Compile();
serviceItem->Register();
DynamicObject::Ptr dobj = serviceItem->Commit();
dobj->OnConfigLoaded();
}
BOOST_FOREACH(const ApplyRule& rule, rules)
EvaluateApplyRule(host, rule);
}
}

View File

@ -60,13 +60,15 @@ public:
static String StateTypeToString(StateType state);
static void RegisterApplyRuleHandler(void);
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
protected:
virtual void OnConfigLoaded(void);
private:
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);