diff --git a/lib/config/aexpression.cpp b/lib/config/aexpression.cpp index 0f6a4fb63..74c1ed570 100644 --- a/lib/config/aexpression.cpp +++ b/lib/config/aexpression.cpp @@ -445,7 +445,7 @@ Value AExpression::OpSetDivide(const AExpression *expr, const Dictionary::Ptr& l Value AExpression::OpIndexer(const AExpression *expr, const Dictionary::Ptr& locals) { - Dictionary::Ptr dict = locals->Get(expr->m_Operand1); + Dictionary::Ptr dict = OpVariable(expr, locals); if (!dict) BOOST_THROW_EXCEPTION(ConfigError("Script variable '" + expr->m_Operand1 + "' not set in this scope.")); diff --git a/lib/config/applyrule.cpp b/lib/config/applyrule.cpp index 23247db27..c31fd2b07 100644 --- a/lib/config/applyrule.cpp +++ b/lib/config/applyrule.cpp @@ -24,8 +24,8 @@ using namespace icinga; ApplyRule::RuleMap ApplyRule::m_Rules; ApplyRule::CallbackMap ApplyRule::m_Callbacks; -ApplyRule::ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di) - : m_Template(tmpl), m_Expression(expression), m_DebugInfo(di) +ApplyRule::ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di, const Dictionary::Ptr& scope) + : m_Template(tmpl), m_Expression(expression), m_DebugInfo(di), m_Scope(scope) { } String ApplyRule::GetTemplate(void) const @@ -43,9 +43,14 @@ DebugInfo ApplyRule::GetDebugInfo(void) const return m_DebugInfo; } -void ApplyRule::AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di) +Dictionary::Ptr ApplyRule::GetScope(void) const { - m_Rules[std::make_pair(sourceType, targetType)].push_back(ApplyRule(tmpl, expression, di)); + return m_Scope; +} + +void ApplyRule::AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di, const Dictionary::Ptr& scope) +{ + m_Rules[std::make_pair(sourceType, targetType)].push_back(ApplyRule(tmpl, expression, di, scope)); } void ApplyRule::EvaluateRules(void) diff --git a/lib/config/applyrule.h b/lib/config/applyrule.h index e08ad98fb..3fba61006 100644 --- a/lib/config/applyrule.h +++ b/lib/config/applyrule.h @@ -42,8 +42,9 @@ public: String GetTemplate(void) const; AExpression::Ptr GetExpression(void) const; DebugInfo GetDebugInfo(void) const; + Dictionary::Ptr GetScope(void) const; - static void AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di); + static void AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di, const Dictionary::Ptr& scope); static void EvaluateRules(void); static void RegisterCombination(const String& sourceType, const String& targetType, const ApplyRule::Callback& callback); @@ -53,11 +54,12 @@ private: String m_Template; AExpression::Ptr m_Expression; DebugInfo m_DebugInfo; + Dictionary::Ptr m_Scope; static CallbackMap m_Callbacks; static RuleMap m_Rules; - ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di); + ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di, const Dictionary::Ptr& scope); }; } diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 68bc238bd..8d09a22f2 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -460,6 +460,8 @@ object: item->SetAbstract(m_Abstract); + item->SetScope(m_ModuleScope); + item->Compile()->Register(); item.reset(); } @@ -713,6 +715,6 @@ apply: T_APPLY optional_template identifier identifier T_TO identifier T_WHERE r AExpression::Ptr aexpr = make_shared(&AExpression::OpFunctionCall, "bool", make_shared(&AExpression::OpLiteral, arguments, @8), @8); - ApplyRule::AddRule($3, $4, $6, aexpr, DebugInfoRange(@1, @8)); + ApplyRule::AddRule($3, $4, $6, aexpr, DebugInfoRange(@1, @8), m_ModuleScope); } %% diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 609e7f3ff..fe97ab0ae 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -49,9 +49,11 @@ ConfigItem::ItemMap ConfigItem::m_Items; */ ConfigItem::ConfigItem(const String& type, const String& name, bool abstract, const AExpression::Ptr& exprl, - const std::vector& parents, const DebugInfo& debuginfo) + const std::vector& parents, const DebugInfo& debuginfo, + const Dictionary::Ptr& scope) : m_Type(type), m_Name(name), m_Abstract(abstract), m_Validated(false), - m_ExpressionList(exprl), m_ParentNames(parents), m_DebugInfo(debuginfo) + m_ExpressionList(exprl), m_ParentNames(parents), m_DebugInfo(debuginfo), + m_Scope(scope) { } @@ -95,6 +97,11 @@ DebugInfo ConfigItem::GetDebugInfo(void) const return m_DebugInfo; } +Dictionary::Ptr ConfigItem::GetScope(void) const +{ + return m_Scope; +} + /** * Retrieves the expression list for the configuration item. * @@ -145,9 +152,14 @@ Dictionary::Ptr ConfigItem::GetProperties(void) { ASSERT(OwnsLock()); - Dictionary::Ptr properties = make_shared(); - GetLinkedExpressionList()->Evaluate(properties); - return properties; + if (!m_Properties) { + m_Properties = make_shared(); + m_Properties->Set("__parent", m_Scope); + GetLinkedExpressionList()->Evaluate(m_Properties); + m_Properties->Remove("__parent"); + } + + return m_Properties; } /** diff --git a/lib/config/configitem.h b/lib/config/configitem.h index 2435d9a7c..7af2918dc 100644 --- a/lib/config/configitem.h +++ b/lib/config/configitem.h @@ -46,7 +46,7 @@ public: ConfigItem(const String& type, const String& name, bool abstract, const AExpression::Ptr& exprl, const std::vector& parents, - const DebugInfo& debuginfo); + const DebugInfo& debuginfo, const Dictionary::Ptr& scope); String GetType(void) const; String GetName(void) const; @@ -62,6 +62,8 @@ public: DebugInfo GetDebugInfo(void) const; + Dictionary::Ptr GetScope(void) const; + static ConfigItem::Ptr GetObject(const String& type, const String& name); static bool HasObject(const String& type, const String& name); @@ -80,9 +82,11 @@ private: bool m_Validated; /** Whether this object has been validated. */ AExpression::Ptr m_ExpressionList; + Dictionary::Ptr m_Properties; std::vector m_ParentNames; /**< The names of parent configuration items. */ DebugInfo m_DebugInfo; /**< Debug information. */ + Dictionary::Ptr m_Scope; /**< variable scope. */ AExpression::Ptr m_LinkedExpressionList; diff --git a/lib/config/configitembuilder.cpp b/lib/config/configitembuilder.cpp index a9f6f77e7..dbae3768e 100644 --- a/lib/config/configitembuilder.cpp +++ b/lib/config/configitembuilder.cpp @@ -55,6 +55,11 @@ void ConfigItemBuilder::SetAbstract(bool abstract) m_Abstract = abstract; } +void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope) +{ + m_Scope = scope; +} + void ConfigItemBuilder::AddParent(const String& parent) { m_Parents.push_back(parent); @@ -91,12 +96,12 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void) } Array::Ptr exprs = make_shared(); - exprs->Add(make_shared(&AExpression::OpDict, m_Expressions, true, m_DebugInfo)); exprs->Add(make_shared(&AExpression::OpSet, "__type", make_shared(&AExpression::OpLiteral, m_Type, m_DebugInfo), m_DebugInfo)); exprs->Add(make_shared(&AExpression::OpSet, "__name", make_shared(&AExpression::OpLiteral, m_Name, m_DebugInfo), m_DebugInfo)); + exprs->Add(make_shared(&AExpression::OpDict, m_Expressions, true, m_DebugInfo)); AExpression::Ptr exprl = make_shared(&AExpression::OpDict, exprs, true, m_DebugInfo); return make_shared(m_Type, m_Name, m_Abstract, exprl, - m_Parents, m_DebugInfo); + m_Parents, m_DebugInfo, m_Scope); } diff --git a/lib/config/configitembuilder.h b/lib/config/configitembuilder.h index 8a37359d4..74fa75df6 100644 --- a/lib/config/configitembuilder.h +++ b/lib/config/configitembuilder.h @@ -45,6 +45,7 @@ public: void SetType(const String& type); void SetName(const String& name); void SetAbstract(bool abstract); + void SetScope(const Dictionary::Ptr& scope); void AddParent(const String& parent); @@ -60,6 +61,7 @@ private: items. */ Array::Ptr m_Expressions; /**< Expressions for this item. */ DebugInfo m_DebugInfo; /**< Debug information. */ + Dictionary::Ptr m_Scope; /**< variable scope. */ }; } diff --git a/lib/icinga/host-apply.cpp b/lib/icinga/host-apply.cpp index 8ffe602ac..010987ba4 100644 --- a/lib/icinga/host-apply.cpp +++ b/lib/icinga/host-apply.cpp @@ -77,6 +77,7 @@ void Host::EvaluateApplyRules(const std::vector& rules) ConfigItemBuilder::Ptr builder = make_shared(rule.GetDebugInfo()); builder->SetType("Service"); builder->SetName(name); + builder->SetScope(rule.GetScope()); builder->AddExpression(make_shared(&AExpression::OpSet, "host", make_shared(&AExpression::OpLiteral, host->GetName(), rule.GetDebugInfo()), rule.GetDebugInfo())); builder->AddParent(rule.GetTemplate()); diff --git a/lib/icinga/host.cpp b/lib/icinga/host.cpp index 42d5d780d..386605473 100644 --- a/lib/icinga/host.cpp +++ b/lib/icinga/host.cpp @@ -155,6 +155,8 @@ void Host::UpdateSlaveServices(void) builder->AddExpression(make_shared(&AExpression::OpDict, svc_exprl, true, di)); + builder->SetScope(item->GetScope()); + ConfigItem::Ptr serviceItem = builder->Compile(); serviceItem->Register(); DynamicObject::Ptr dobj = serviceItem->Commit(); diff --git a/lib/icinga/service-dependency.cpp b/lib/icinga/service-dependency.cpp index 913950887..36b455bee 100644 --- a/lib/icinga/service-dependency.cpp +++ b/lib/icinga/service-dependency.cpp @@ -231,6 +231,8 @@ void Service::UpdateSlaveDependencies(void) builder->AddExpression(make_shared(&AExpression::OpDict, sd_exprl, true, di)); + builder->SetScope(item->GetScope()); + ConfigItem::Ptr dependencyItem = builder->Compile(); dependencyItem->Register(); DynamicObject::Ptr dobj = dependencyItem->Commit(); diff --git a/lib/icinga/service-downtime.cpp b/lib/icinga/service-downtime.cpp index 748b61858..d914284a4 100644 --- a/lib/icinga/service-downtime.cpp +++ b/lib/icinga/service-downtime.cpp @@ -380,6 +380,8 @@ void Service::UpdateSlaveScheduledDowntimes(void) builder->AddExpression(make_shared(&AExpression::OpDict, sd_exprl, true, di)); + builder->SetScope(item->GetScope()); + ConfigItem::Ptr scheduledDowntimeItem = builder->Compile(); scheduledDowntimeItem->Register(); DynamicObject::Ptr dobj = scheduledDowntimeItem->Commit(); diff --git a/lib/icinga/service-notification.cpp b/lib/icinga/service-notification.cpp index 344e33c0c..5fb711aa4 100644 --- a/lib/icinga/service-notification.cpp +++ b/lib/icinga/service-notification.cpp @@ -159,6 +159,8 @@ void Service::UpdateSlaveNotifications(void) builder->AddExpression(make_shared(&AExpression::OpDict, nfc_exprl, true, di)); + builder->SetScope(item->GetScope()); + ConfigItem::Ptr notificationItem = builder->Compile(); notificationItem->Register(); DynamicObject::Ptr dobj = notificationItem->Commit();