mirror of https://github.com/Icinga/icinga2.git
parent
8c9ba23cdc
commit
a1c905bf62
|
@ -28,10 +28,10 @@ ApplyRule::RuleMap ApplyRule::m_Rules;
|
|||
ApplyRule::CallbackMap ApplyRule::m_Callbacks;
|
||||
|
||||
ApplyRule::ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
|
||||
const Expression::Ptr& filter, const String& fvar, const Expression::Ptr& fterm,
|
||||
const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm,
|
||||
const DebugInfo& di, const Dictionary::Ptr& scope)
|
||||
: m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_FVar(fvar),
|
||||
m_FTerm(fterm), m_DebugInfo(di), m_Scope(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)
|
||||
{ }
|
||||
|
||||
String ApplyRule::GetTargetType(void) const
|
||||
|
@ -54,9 +54,14 @@ Expression::Ptr ApplyRule::GetFilter(void) const
|
|||
return m_Filter;
|
||||
}
|
||||
|
||||
String ApplyRule::GetFVar(void) const
|
||||
String ApplyRule::GetFKVar(void) const
|
||||
{
|
||||
return m_FVar;
|
||||
return m_FKVar;
|
||||
}
|
||||
|
||||
String ApplyRule::GetFVVar(void) const
|
||||
{
|
||||
return m_FVVar;
|
||||
}
|
||||
|
||||
Expression::Ptr ApplyRule::GetFTerm(void) const
|
||||
|
@ -75,10 +80,10 @@ Dictionary::Ptr ApplyRule::GetScope(void) const
|
|||
}
|
||||
|
||||
void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
|
||||
const Expression::Ptr& expression, const Expression::Ptr& filter, const String& fvar,
|
||||
const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope)
|
||||
const Expression::Ptr& expression, const Expression::Ptr& filter, const String& fkvar,
|
||||
const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope)
|
||||
{
|
||||
m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, fvar, fterm, di, scope));
|
||||
m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, fkvar, fvvar, fterm, di, scope));
|
||||
}
|
||||
|
||||
bool ApplyRule::EvaluateFilter(const Dictionary::Ptr& scope) const
|
||||
|
|
|
@ -42,7 +42,8 @@ public:
|
|||
String GetName(void) const;
|
||||
Expression::Ptr GetExpression(void) const;
|
||||
Expression::Ptr GetFilter(void) const;
|
||||
String GetFVar(void) const;
|
||||
String GetFKVar(void) const;
|
||||
String GetFVVar(void) const;
|
||||
Expression::Ptr GetFTerm(void) const;
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
Dictionary::Ptr GetScope(void) const;
|
||||
|
@ -50,7 +51,7 @@ public:
|
|||
bool EvaluateFilter(const Dictionary::Ptr& scope) const;
|
||||
|
||||
static void AddRule(const String& sourceType, const String& targetType, const String& name, const Expression::Ptr& expression,
|
||||
const Expression::Ptr& filter, const String& fvar, const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope);
|
||||
const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope);
|
||||
static void EvaluateRules(bool clear);
|
||||
|
||||
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
|
||||
|
@ -63,7 +64,8 @@ private:
|
|||
String m_Name;
|
||||
Expression::Ptr m_Expression;
|
||||
Expression::Ptr m_Filter;
|
||||
String m_FVar;
|
||||
String m_FKVar;
|
||||
String m_FVVar;
|
||||
Expression::Ptr m_FTerm;
|
||||
DebugInfo m_DebugInfo;
|
||||
Dictionary::Ptr m_Scope;
|
||||
|
@ -72,7 +74,7 @@ private:
|
|||
static RuleMap m_Rules;
|
||||
|
||||
ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
|
||||
const Expression::Ptr& filter, const String& fvar, const Expression::Ptr& fterm,
|
||||
const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm,
|
||||
const DebugInfo& di, const Dictionary::Ptr& scope);
|
||||
};
|
||||
|
||||
|
|
|
@ -32,12 +32,7 @@
|
|||
|
||||
%attribute %dictionary "methods",
|
||||
|
||||
%attribute %dictionary "vars" {
|
||||
%attribute %string "*",
|
||||
%attribute %array "*" {
|
||||
%attribute %string "*"
|
||||
}
|
||||
},
|
||||
%attribute %dictionary "vars"
|
||||
}
|
||||
|
||||
%type Logger {
|
||||
|
|
|
@ -228,9 +228,11 @@ where return T_WHERE;
|
|||
import return T_IMPORT;
|
||||
assign return T_ASSIGN;
|
||||
ignore return T_IGNORE;
|
||||
for return T_APPLY_FOR;
|
||||
__function return T_FUNCTION;
|
||||
__return return T_RETURN;
|
||||
__for return T_FOR;
|
||||
=\> return T_FOLLOWS;
|
||||
\<\< { yylval->op = &Expression::OpShiftLeft; return T_SHIFT_LEFT; }
|
||||
\>\> { yylval->op = &Expression::OpShiftRight; return T_SHIFT_RIGHT; }
|
||||
\<= { yylval->op = &Expression::OpLessThanOrEqual; return T_LESS_THAN_OR_EQUAL; }
|
||||
|
|
|
@ -157,9 +157,11 @@ static void MakeRBinaryOp(Value** result, Expression::OpCallback& op, Value *lef
|
|||
%token T_IMPORT "import (T_IMPORT)"
|
||||
%token T_ASSIGN "assign (T_ASSIGN)"
|
||||
%token T_IGNORE "ignore (T_IGNORE)"
|
||||
%token T_APPLY_FOR "for (T_APPLY_FOR)"
|
||||
%token T_FUNCTION "function (T_FUNCTION)"
|
||||
%token T_RETURN "return (T_RETURN)"
|
||||
%token T_FOR "for (T_FOR)"
|
||||
%token T_FOLLOWS "=> (T_FOLLOWS)"
|
||||
|
||||
%type <text> identifier
|
||||
%type <array> rterm_items
|
||||
|
@ -177,6 +179,7 @@ static void MakeRBinaryOp(Value** result, Expression::OpCallback& op, Value *lef
|
|||
%type <variant> lterm
|
||||
%type <variant> object
|
||||
%type <variant> apply
|
||||
%type <variant> optional_rterm
|
||||
%type <text> target_type_specifier
|
||||
|
||||
%left T_LOGICAL_OR
|
||||
|
@ -218,7 +221,8 @@ static std::stack<bool> m_ObjectAssign;
|
|||
static std::stack<bool> m_SeenAssign;
|
||||
static std::stack<Expression::Ptr> m_Assign;
|
||||
static std::stack<Expression::Ptr> m_Ignore;
|
||||
static std::stack<String> m_FVar;
|
||||
static std::stack<String> m_FKVar;
|
||||
static std::stack<String> m_FVVar;
|
||||
static std::stack<Expression::Ptr> m_FTerm;
|
||||
|
||||
void ConfigCompiler::Compile(void)
|
||||
|
@ -233,7 +237,8 @@ void ConfigCompiler::Compile(void)
|
|||
m_SeenAssign = std::stack<bool>();
|
||||
m_Assign = std::stack<Expression::Ptr>();
|
||||
m_Ignore = std::stack<Expression::Ptr>();
|
||||
m_FVar = std::stack<String>();
|
||||
m_FKVar = std::stack<String>();
|
||||
m_FVVar = std::stack<String>();
|
||||
m_FTerm = std::stack<Expression::Ptr>();
|
||||
|
||||
try {
|
||||
|
@ -812,6 +817,25 @@ rterm: T_STRING
|
|||
|
||||
$$ = new Value(make_shared<Expression>(&Expression::OpFunction, arr, Array::Ptr($3), DebugInfoRange(@1, @5)));
|
||||
}
|
||||
| T_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')' rterm_scope
|
||||
{
|
||||
Array::Ptr arr = make_shared<Array>();
|
||||
|
||||
arr->Add($3);
|
||||
free($3);
|
||||
|
||||
arr->Add($5);
|
||||
free($5);
|
||||
|
||||
Expression::Ptr aexpr = *$7;
|
||||
delete $7;
|
||||
arr->Add(aexpr);
|
||||
|
||||
Expression::Ptr ascope = *$9;
|
||||
delete $9;
|
||||
|
||||
$$ = new Value(make_shared<Expression>(&Expression::OpFor, arr, ascope, DebugInfoRange(@1, @9)));
|
||||
}
|
||||
| T_FOR '(' identifier T_IN rterm ')' rterm_scope
|
||||
{
|
||||
Array::Ptr arr = make_shared<Array>();
|
||||
|
@ -819,6 +843,8 @@ rterm: T_STRING
|
|||
arr->Add($3);
|
||||
free($3);
|
||||
|
||||
arr->Add(Empty);
|
||||
|
||||
Expression::Ptr aexpr = *$5;
|
||||
delete $5;
|
||||
arr->Add(aexpr);
|
||||
|
@ -841,26 +867,50 @@ target_type_specifier: /* empty */
|
|||
;
|
||||
|
||||
apply_for_specifier: /* empty */
|
||||
| T_FOR '(' identifier T_IN rterm ')'
|
||||
| T_APPLY_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')'
|
||||
{
|
||||
m_FVar.top() = $3;
|
||||
m_FKVar.top() = $3;
|
||||
free($3);
|
||||
|
||||
m_FVVar.top() = $5;
|
||||
free($5);
|
||||
|
||||
m_FTerm.top() = *$7;
|
||||
delete $7;
|
||||
}
|
||||
| T_APPLY_FOR '(' identifier T_IN rterm ')'
|
||||
{
|
||||
m_FKVar.top() = $3;
|
||||
free($3);
|
||||
|
||||
m_FVVar.top() = "";
|
||||
|
||||
m_FTerm.top() = *$5;
|
||||
delete $5;
|
||||
}
|
||||
;
|
||||
|
||||
optional_rterm: /* empty */
|
||||
{
|
||||
$$ = new Value(make_shared<Expression>(&Expression::OpLiteral, Empty, DebugInfo()));
|
||||
}
|
||||
| rterm
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
apply:
|
||||
{
|
||||
m_Apply.push(true);
|
||||
m_SeenAssign.push(false);
|
||||
m_Assign.push(make_shared<Expression>(&Expression::OpLiteral, false, DebugInfo()));
|
||||
m_Ignore.push(make_shared<Expression>(&Expression::OpLiteral, false, DebugInfo()));
|
||||
m_FVar.push("");
|
||||
m_FKVar.push("");
|
||||
m_FVVar.push("");
|
||||
m_FTerm.push(Expression::Ptr());
|
||||
}
|
||||
T_APPLY identifier rterm apply_for_specifier target_type_specifier rterm
|
||||
T_APPLY identifier optional_rterm apply_for_specifier target_type_specifier rterm
|
||||
{
|
||||
m_Apply.pop();
|
||||
|
||||
|
@ -912,8 +962,11 @@ apply:
|
|||
Expression::Ptr filter = make_shared<Expression>(&Expression::OpLogicalAnd, m_Assign.top(), rex, DebugInfoRange(@2, @5));
|
||||
m_Assign.pop();
|
||||
|
||||
String fvar = m_FVar.top();
|
||||
m_FVar.pop();
|
||||
String fkvar = m_FKVar.top();
|
||||
m_FKVar.pop();
|
||||
|
||||
String fvvar = m_FVVar.top();
|
||||
m_FVVar.pop();
|
||||
|
||||
Expression::Ptr fterm = m_FTerm.top();
|
||||
m_FTerm.pop();
|
||||
|
@ -923,7 +976,8 @@ apply:
|
|||
args->Add(target);
|
||||
args->Add(aname);
|
||||
args->Add(filter);
|
||||
args->Add(fvar);
|
||||
args->Add(fkvar);
|
||||
args->Add(fvvar);
|
||||
args->Add(fterm);
|
||||
|
||||
$$ = new Value(make_shared<Expression>(&Expression::OpApply, args, exprl, DebugInfoRange(@2, @5)));
|
||||
|
|
|
@ -551,12 +551,13 @@ Value Expression::OpApply(const Expression* expr, const Dictionary::Ptr& locals,
|
|||
String target = left->Get(1);
|
||||
Expression::Ptr aname = left->Get(2);
|
||||
Expression::Ptr filter = left->Get(3);
|
||||
String fvar = left->Get(4);
|
||||
Expression::Ptr fterm = left->Get(5);
|
||||
String fkvar = left->Get(4);
|
||||
String fvvar = left->Get(5);
|
||||
Expression::Ptr fterm = left->Get(6);
|
||||
|
||||
String name = aname->Evaluate(locals, dhint);
|
||||
|
||||
ApplyRule::AddRule(type, target, name, exprl, filter, fvar, fterm, expr->m_DebugInfo, locals);
|
||||
ApplyRule::AddRule(type, target, name, exprl, filter, fkvar, fvvar, fterm, expr->m_DebugInfo, locals);
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
@ -618,20 +619,44 @@ Value Expression::OpObject(const Expression* expr, const Dictionary::Ptr& locals
|
|||
Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint)
|
||||
{
|
||||
Array::Ptr left = expr->m_Operand1;
|
||||
String varname = left->Get(0);
|
||||
Expression::Ptr aexpr = left->Get(1);
|
||||
String kvar = left->Get(0);
|
||||
String vvar = left->Get(1);
|
||||
Expression::Ptr aexpr = left->Get(2);
|
||||
Expression::Ptr ascope = expr->m_Operand2;
|
||||
|
||||
Array::Ptr arr = aexpr->Evaluate(locals, dhint);
|
||||
Value value = aexpr->Evaluate(locals, dhint);
|
||||
|
||||
ObjectLock olock(arr);
|
||||
BOOST_FOREACH(const Value& value, arr) {
|
||||
Dictionary::Ptr xlocals = make_shared<Dictionary>();
|
||||
xlocals->Set("__parent", locals);
|
||||
xlocals->Set(varname, value);
|
||||
if (value.IsObjectType<Array>()) {
|
||||
if (!vvar.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Cannot use dictionary iterator for array.") << errinfo_debuginfo(expr->m_DebugInfo));
|
||||
|
||||
ascope->Evaluate(xlocals, dhint);
|
||||
}
|
||||
Array::Ptr arr = value;
|
||||
|
||||
ObjectLock olock(arr);
|
||||
BOOST_FOREACH(const Value& value, arr) {
|
||||
Dictionary::Ptr xlocals = make_shared<Dictionary>();
|
||||
xlocals->Set("__parent", locals);
|
||||
xlocals->Set(kvar, value);
|
||||
|
||||
ascope->Evaluate(xlocals, dhint);
|
||||
}
|
||||
} else if (value.IsObjectType<Dictionary>()) {
|
||||
if (vvar.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Cannot use array iterator for dictionary.") << errinfo_debuginfo(expr->m_DebugInfo));
|
||||
|
||||
Dictionary::Ptr dict = value;
|
||||
|
||||
ObjectLock olock(dict);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
||||
Dictionary::Ptr xlocals = make_shared<Dictionary>();
|
||||
xlocals->Set("__parent", locals);
|
||||
xlocals->Set(kvar, kv.first);
|
||||
xlocals->Set(vvar, kv.second);
|
||||
|
||||
ascope->Evaluate(xlocals, dhint);
|
||||
}
|
||||
} else
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Invalid type in __for expression: " + value.GetTypeName()) << errinfo_debuginfo(expr->m_DebugInfo));
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,57 @@ void Dependency::RegisterApplyRuleHandler(void)
|
|||
ApplyRule::RegisterType("Dependency", targets, &Dependency::EvaluateApplyRules);
|
||||
}
|
||||
|
||||
void Dependency::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
Log(LogDebug, "Dependency")
|
||||
<< "Applying dependency '" << name << "' to object '" << checkable->GetName() << "' for rule " << di;
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Dependency");
|
||||
builder->SetName(name);
|
||||
builder->SetScope(locals);
|
||||
|
||||
Host::Ptr host;
|
||||
Service::Ptr service;
|
||||
tie(host, service) = GetHostService(checkable);
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "parent_host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "child_host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
if (service) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "child_service_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, service->GetShortName(), di),
|
||||
di));
|
||||
}
|
||||
|
||||
String zone = checkable->GetZone();
|
||||
|
||||
if (!zone.IsEmpty()) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "zone", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, zone, di),
|
||||
di));
|
||||
}
|
||||
|
||||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr dependencyItem = builder->Compile();
|
||||
dependencyItem->Register();
|
||||
DynamicObject::Ptr dobj = dependencyItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
|
||||
}
|
||||
|
||||
bool Dependency::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
@ -63,69 +114,46 @@ bool Dependency::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const App
|
|||
if (!rule.EvaluateFilter(locals))
|
||||
return false;
|
||||
|
||||
Array::Ptr instances;
|
||||
Value vinstances;
|
||||
|
||||
if (rule.GetFTerm()) {
|
||||
Value vinstances = rule.GetFTerm()->Evaluate(locals);
|
||||
|
||||
if (!vinstances.IsObjectType<Array>())
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("for expression must be an array"));
|
||||
|
||||
instances = vinstances;
|
||||
vinstances = rule.GetFTerm()->Evaluate(locals);
|
||||
} else {
|
||||
instances = make_shared<Array>();
|
||||
Array::Ptr instances = make_shared<Array>();
|
||||
instances->Add("");
|
||||
vinstances = instances;
|
||||
}
|
||||
|
||||
ObjectLock olock(instances);
|
||||
BOOST_FOREACH(const String& instance, instances) {
|
||||
String objName = rule.GetName();
|
||||
if (vinstances.IsObjectType<Array>()) {
|
||||
if (!rule.GetFVVar().IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Array iterator requires value to be an array.") << errinfo_debuginfo(di));
|
||||
|
||||
if (!rule.GetFVar().IsEmpty()) {
|
||||
locals->Set(rule.GetFVar(), instance);
|
||||
objName += "-" + instance;
|
||||
Array::Ptr arr = vinstances;
|
||||
|
||||
ObjectLock olock(arr);
|
||||
BOOST_FOREACH(const String& instance, arr) {
|
||||
String name = rule.GetName();
|
||||
|
||||
if (!rule.GetFKVar().IsEmpty()) {
|
||||
locals->Set(rule.GetFKVar(), instance);
|
||||
name += instance;
|
||||
}
|
||||
|
||||
EvaluateApplyRuleOneInstance(checkable, name, locals, rule);
|
||||
}
|
||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||
if (rule.GetFVVar().IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Dictionary iterator requires value to be a dictionary.") << errinfo_debuginfo(di));
|
||||
|
||||
Dictionary::Ptr dict = vinstances;
|
||||
|
||||
Log(LogDebug, "Dependency")
|
||||
<< "Applying dependency '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
|
||||
ObjectLock olock(dict);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
||||
locals->Set(rule.GetFKVar(), kv.first);
|
||||
locals->Set(rule.GetFVVar(), kv.second);
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Dependency");
|
||||
builder->SetName(objName);
|
||||
builder->SetScope(locals);
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "parent_host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "child_host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
if (service) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "child_service_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, service->GetShortName(), di),
|
||||
di));
|
||||
EvaluateApplyRuleOneInstance(checkable, rule.GetName() + kv.first, locals, rule);
|
||||
}
|
||||
|
||||
String zone = checkable->GetZone();
|
||||
|
||||
if (!zone.IsEmpty()) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "zone", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, zone, di),
|
||||
di));
|
||||
}
|
||||
|
||||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr dependencyItem = builder->Compile();
|
||||
dependencyItem->Register();
|
||||
DynamicObject::Ptr dobj = dependencyItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -60,6 +60,7 @@ 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);
|
||||
|
|
|
@ -42,6 +42,52 @@ void Notification::RegisterApplyRuleHandler(void)
|
|||
ApplyRule::RegisterType("Notification", targets, &Notification::EvaluateApplyRules);
|
||||
}
|
||||
|
||||
void Notification::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
Log(LogDebug, "Notification")
|
||||
<< "Applying notification '" << name << "' to object '" << checkable->GetName() << "' for rule " << di;
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Notification");
|
||||
builder->SetName(name);
|
||||
builder->SetScope(locals);
|
||||
|
||||
Host::Ptr host;
|
||||
Service::Ptr service;
|
||||
tie(host, service) = GetHostService(checkable);
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
if (service) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "service_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, service->GetShortName(), di),
|
||||
di));
|
||||
}
|
||||
|
||||
String zone = checkable->GetZone();
|
||||
|
||||
if (!zone.IsEmpty()) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "zone", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, zone, di),
|
||||
di));
|
||||
}
|
||||
|
||||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr notificationItem = builder->Compile();
|
||||
notificationItem->Register();
|
||||
DynamicObject::Ptr dobj = notificationItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
|
||||
}
|
||||
|
||||
bool Notification::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
@ -63,64 +109,46 @@ bool Notification::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const A
|
|||
if (!rule.EvaluateFilter(locals))
|
||||
return false;
|
||||
|
||||
Array::Ptr instances;
|
||||
Value vinstances;
|
||||
|
||||
if (rule.GetFTerm()) {
|
||||
Value vinstances = rule.GetFTerm()->Evaluate(locals);
|
||||
|
||||
if (!vinstances.IsObjectType<Array>())
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("for expression must be an array"));
|
||||
|
||||
instances = vinstances;
|
||||
vinstances = rule.GetFTerm()->Evaluate(locals);
|
||||
} else {
|
||||
instances = make_shared<Array>();
|
||||
Array::Ptr instances = make_shared<Array>();
|
||||
instances->Add("");
|
||||
vinstances = instances;
|
||||
}
|
||||
|
||||
ObjectLock olock(instances);
|
||||
BOOST_FOREACH(const String& instance, instances) {
|
||||
String objName = rule.GetName();
|
||||
if (vinstances.IsObjectType<Array>()) {
|
||||
if (!rule.GetFVVar().IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Array iterator requires value to be an array.") << errinfo_debuginfo(di));
|
||||
|
||||
if (!rule.GetFVar().IsEmpty()) {
|
||||
locals->Set(rule.GetFVar(), instance);
|
||||
objName += "-" + instance;
|
||||
Array::Ptr arr = vinstances;
|
||||
|
||||
ObjectLock olock(arr);
|
||||
BOOST_FOREACH(const String& instance, arr) {
|
||||
String name = rule.GetName();
|
||||
|
||||
if (!rule.GetFKVar().IsEmpty()) {
|
||||
locals->Set(rule.GetFKVar(), instance);
|
||||
name += instance;
|
||||
}
|
||||
|
||||
EvaluateApplyRuleOneInstance(checkable, name, locals, rule);
|
||||
}
|
||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||
if (rule.GetFVVar().IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Dictionary iterator requires value to be a dictionary.") << errinfo_debuginfo(di));
|
||||
|
||||
Dictionary::Ptr dict = vinstances;
|
||||
|
||||
Log(LogDebug, "Notification")
|
||||
<< "Applying notification '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
|
||||
ObjectLock olock(dict);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
||||
locals->Set(rule.GetFKVar(), kv.first);
|
||||
locals->Set(rule.GetFVVar(), kv.second);
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Notification");
|
||||
builder->SetName(objName);
|
||||
builder->SetScope(locals);
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
if (service) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "service_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, service->GetShortName(), di),
|
||||
di));
|
||||
EvaluateApplyRuleOneInstance(checkable, rule.GetName() + kv.first, locals, rule);
|
||||
}
|
||||
|
||||
String zone = checkable->GetZone();
|
||||
|
||||
if (!zone.IsEmpty()) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "zone", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, zone, di),
|
||||
di));
|
||||
}
|
||||
|
||||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr notificationItem = builder->Compile();
|
||||
notificationItem->Register();
|
||||
DynamicObject::Ptr dobj = notificationItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -113,6 +113,7 @@ 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 shared_ptr<Checkable>& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
|
||||
static bool EvaluateApplyRuleOne(const shared_ptr<Checkable>& checkable, const ApplyRule& rule);
|
||||
static void EvaluateApplyRule(const ApplyRule& rule);
|
||||
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
|
||||
|
|
|
@ -41,7 +41,52 @@ void ScheduledDowntime::RegisterApplyRuleHandler(void)
|
|||
ApplyRule::RegisterType("ScheduledDowntime", targets, &ScheduledDowntime::EvaluateApplyRules);
|
||||
}
|
||||
|
||||
bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
void ScheduledDowntime::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
Log(LogDebug, "ScheduledDowntime")
|
||||
<< "Applying scheduled downtime '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("ScheduledDowntime");
|
||||
builder->SetName(name);
|
||||
builder->SetScope(locals);
|
||||
|
||||
Host::Ptr host;
|
||||
Service::Ptr service;
|
||||
tie(host, service) = GetHostService(checkable);
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
if (service) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "service_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, service->GetShortName(), di),
|
||||
di));
|
||||
}
|
||||
|
||||
String zone = checkable->GetZone();
|
||||
|
||||
if (!zone.IsEmpty()) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "zone", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, zone, di),
|
||||
di));
|
||||
}
|
||||
|
||||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr downtimeItem = builder->Compile();
|
||||
downtimeItem->Register();
|
||||
DynamicObject::Ptr dobj = downtimeItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
||||
bool ScheduledDowntime::EvaluateApplyRuleOne(const Checkable::Ptr& checkable, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
|
@ -62,115 +107,106 @@ bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const
|
|||
if (!rule.EvaluateFilter(locals))
|
||||
return false;
|
||||
|
||||
Array::Ptr instances;
|
||||
Value vinstances;
|
||||
|
||||
if (rule.GetFTerm()) {
|
||||
Value vinstances = rule.GetFTerm()->Evaluate(locals);
|
||||
|
||||
if (!vinstances.IsObjectType<Array>())
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("for expression must be an array"));
|
||||
|
||||
instances = vinstances;
|
||||
vinstances = rule.GetFTerm()->Evaluate(locals);
|
||||
} else {
|
||||
instances = make_shared<Array>();
|
||||
Array::Ptr instances = make_shared<Array>();
|
||||
instances->Add("");
|
||||
vinstances = instances;
|
||||
}
|
||||
|
||||
ObjectLock olock(instances);
|
||||
BOOST_FOREACH(const String& instance, instances) {
|
||||
String objName = rule.GetName();
|
||||
if (vinstances.IsObjectType<Array>()) {
|
||||
if (!rule.GetFVVar().IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Array iterator requires value to be an array.") << errinfo_debuginfo(di));
|
||||
|
||||
if (!rule.GetFVar().IsEmpty()) {
|
||||
locals->Set(rule.GetFVar(), instance);
|
||||
objName += "-" + instance;
|
||||
Array::Ptr arr = vinstances;
|
||||
|
||||
ObjectLock olock(arr);
|
||||
BOOST_FOREACH(const String& instance, arr) {
|
||||
String name = rule.GetName();
|
||||
|
||||
if (!rule.GetFKVar().IsEmpty()) {
|
||||
locals->Set(rule.GetFKVar(), instance);
|
||||
name += instance;
|
||||
}
|
||||
|
||||
EvaluateApplyRuleOneInstance(checkable, name, locals, rule);
|
||||
}
|
||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||
if (rule.GetFVVar().IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Dictionary iterator requires value to be a dictionary.") << errinfo_debuginfo(di));
|
||||
|
||||
Dictionary::Ptr dict = vinstances;
|
||||
|
||||
Log(LogDebug, "ScheduledDowntime")
|
||||
<< "Applying scheduled downtime '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di;
|
||||
ObjectLock olock(dict);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
||||
locals->Set(rule.GetFKVar(), kv.first);
|
||||
locals->Set(rule.GetFVVar(), kv.second);
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("ScheduledDowntime");
|
||||
builder->SetName(objName);
|
||||
builder->SetScope(locals);
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
if (service) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "service_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, service->GetShortName(), di),
|
||||
di));
|
||||
EvaluateApplyRuleOneInstance(checkable, rule.GetName() + kv.first, locals, rule);
|
||||
}
|
||||
|
||||
String zone = checkable->GetZone();
|
||||
|
||||
if (!zone.IsEmpty()) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "zone", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, zone, di),
|
||||
di));
|
||||
}
|
||||
|
||||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr downtimeItem = builder->Compile();
|
||||
downtimeItem->Register();
|
||||
DynamicObject::Ptr dobj = downtimeItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScheduledDowntime::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
|
||||
void ScheduledDowntime::EvaluateApplyRule(const ApplyRule& rule)
|
||||
{
|
||||
int apply_count = 0;
|
||||
|
||||
BOOST_FOREACH(const ApplyRule& rule, rules) {
|
||||
if (rule.GetTargetType() == "Host") {
|
||||
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(const Host::Ptr& host, DynamicType::GetObjectsByType<Host>()) {
|
||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||
|
||||
try {
|
||||
if (EvaluateApplyRule(host, 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());
|
||||
}
|
||||
try {
|
||||
if (EvaluateApplyRuleOne(host, 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 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(EvaluateApplyRule(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() << "'!";
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ParallelWorkQueue upq;
|
||||
|
||||
BOOST_FOREACH(const ApplyRule& rule, rules) {
|
||||
upq.Enqueue(boost::bind(&ScheduledDowntime::EvaluateApplyRule, boost::cref(rule)));
|
||||
}
|
||||
|
||||
upq.Join();
|
||||
}
|
||||
|
|
|
@ -56,7 +56,9 @@ private:
|
|||
std::pair<double, double> FindNextSegment(void);
|
||||
void CreateNextDowntime(void);
|
||||
|
||||
static bool EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule);
|
||||
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);
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,45 @@ void Service::RegisterApplyRuleHandler(void)
|
|||
ApplyRule::RegisterType("Service", targets, &Service::EvaluateApplyRules);
|
||||
}
|
||||
|
||||
void Service::EvaluateApplyRuleOneInstance(const Host::Ptr& host, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
||||
Log(LogDebug, "Service")
|
||||
<< "Applying service '" << name << "' to host '" << host->GetName() << "' for rule " << di;
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Service");
|
||||
builder->SetName(name);
|
||||
builder->SetScope(locals);
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, name, di),
|
||||
di));
|
||||
|
||||
String zone = host->GetZone();
|
||||
|
||||
if (!zone.IsEmpty()) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "zone", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, zone, di),
|
||||
di));
|
||||
}
|
||||
|
||||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr serviceItem = builder->Compile();
|
||||
serviceItem->Register();
|
||||
DynamicObject::Ptr dobj = serviceItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
||||
bool Service::EvaluateApplyRuleOne(const Host::Ptr& host, const ApplyRule& rule)
|
||||
{
|
||||
DebugInfo di = rule.GetDebugInfo();
|
||||
|
@ -55,62 +94,46 @@ bool Service::EvaluateApplyRuleOne(const Host::Ptr& host, const ApplyRule& rule)
|
|||
if (!rule.EvaluateFilter(locals))
|
||||
return false;
|
||||
|
||||
Array::Ptr instances;
|
||||
Value vinstances;
|
||||
|
||||
if (rule.GetFTerm()) {
|
||||
Value vinstances = rule.GetFTerm()->Evaluate(locals);
|
||||
|
||||
if (!vinstances.IsObjectType<Array>())
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("for expression must be an array"));
|
||||
|
||||
instances = vinstances;
|
||||
vinstances = rule.GetFTerm()->Evaluate(locals);
|
||||
} else {
|
||||
instances = make_shared<Array>();
|
||||
Array::Ptr instances = make_shared<Array>();
|
||||
instances->Add("");
|
||||
vinstances = instances;
|
||||
}
|
||||
|
||||
ObjectLock olock(instances);
|
||||
BOOST_FOREACH(const String& instance, instances) {
|
||||
String objName = rule.GetName();
|
||||
if (vinstances.IsObjectType<Array>()) {
|
||||
if (!rule.GetFVVar().IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Array iterator requires value to be an array.") << errinfo_debuginfo(di));
|
||||
|
||||
if (!rule.GetFVar().IsEmpty()) {
|
||||
locals->Set(rule.GetFVar(), instance);
|
||||
objName += "-" + instance;
|
||||
Array::Ptr arr = vinstances;
|
||||
|
||||
ObjectLock olock(arr);
|
||||
BOOST_FOREACH(const String& instance, arr) {
|
||||
String name = rule.GetName();
|
||||
|
||||
if (!rule.GetFKVar().IsEmpty()) {
|
||||
locals->Set(rule.GetFKVar(), instance);
|
||||
name += instance;
|
||||
}
|
||||
|
||||
EvaluateApplyRuleOneInstance(host, name, locals, rule);
|
||||
}
|
||||
} else if (vinstances.IsObjectType<Dictionary>()) {
|
||||
if (rule.GetFVVar().IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Dictionary iterator requires value to be a dictionary.") << errinfo_debuginfo(di));
|
||||
|
||||
Dictionary::Ptr dict = vinstances;
|
||||
|
||||
Log(LogDebug, "Service")
|
||||
<< "Applying service '" << objName << "' to host '" << host->GetName() << "' for rule " << di;
|
||||
ObjectLock olock(dict);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
||||
locals->Set(rule.GetFKVar(), kv.first);
|
||||
locals->Set(rule.GetFVVar(), kv.second);
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Service");
|
||||
builder->SetName(objName);
|
||||
builder->SetScope(locals);
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "host_name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, host->GetName(), di),
|
||||
di));
|
||||
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "name", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, objName, di),
|
||||
di));
|
||||
|
||||
String zone = host->GetZone();
|
||||
|
||||
if (!zone.IsEmpty()) {
|
||||
builder->AddExpression(make_shared<Expression>(&Expression::OpSet,
|
||||
make_shared<Expression>(&Expression::OpLiteral, "zone", di),
|
||||
make_shared<Expression>(&Expression::OpLiteral, zone, di),
|
||||
di));
|
||||
EvaluateApplyRuleOneInstance(host, rule.GetName() + kv.first, locals, rule);
|
||||
}
|
||||
|
||||
builder->AddExpression(rule.GetExpression());
|
||||
|
||||
ConfigItem::Ptr serviceItem = builder->Compile();
|
||||
serviceItem->Register();
|
||||
DynamicObject::Ptr dobj = serviceItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -59,6 +59,7 @@ protected:
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue