]> granicus.if.org Git - icinga2/commitdiff
Fix scoping rules for object definitions.
authorGunnar Beutner <gunnar.beutner@netways.de>
Mon, 24 Mar 2014 10:23:47 +0000 (11:23 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Mon, 24 Mar 2014 10:23:47 +0000 (11:23 +0100)
Refs #5846

13 files changed:
lib/config/aexpression.cpp
lib/config/applyrule.cpp
lib/config/applyrule.h
lib/config/config_parser.yy
lib/config/configitem.cpp
lib/config/configitem.h
lib/config/configitembuilder.cpp
lib/config/configitembuilder.h
lib/icinga/host-apply.cpp
lib/icinga/host.cpp
lib/icinga/service-dependency.cpp
lib/icinga/service-downtime.cpp
lib/icinga/service-notification.cpp

index 0f6a4fb63bd7103fb580244caec9909a26ecf27a..74c1ed57027b466b196310eda2dc2f7dbca741c6 100644 (file)
@@ -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."));
index 23247db27186a413fb333ddfbfa31038746dc25f..c31fd2b0721f44b0aaac8b262fbf60b65e0b69d3 100644 (file)
@@ -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)
index e08ad98fbca30e50a6af15da6b12873291bcacba..3fba6100648c9456dd1a80af4c01bda01014ca8b 100644 (file)
@@ -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);
 };
 
 }
index 68bc238bd130012dab2015841b351b43d8c66b4e..8d09a22f2b6b64340aef1d45c6aa94cfc3707138 100644 (file)
@@ -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>(&AExpression::OpFunctionCall, "bool", make_shared<AExpression>(&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);
        }
 %%
index 609e7f3ff1100e2e81af7014f36a7ef9b9a73740..fe97ab0ae08971a70bd2fb69150a08e2f2a901ac 100644 (file)
@@ -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<String>& parents, const DebugInfo& debuginfo)
+    const std::vector<String>& 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<Dictionary>();
-       GetLinkedExpressionList()->Evaluate(properties);
-       return properties;
+       if (!m_Properties) {
+               m_Properties = make_shared<Dictionary>();
+               m_Properties->Set("__parent", m_Scope);
+               GetLinkedExpressionList()->Evaluate(m_Properties);
+               m_Properties->Remove("__parent");
+       }
+
+       return m_Properties;
 }
 
 /**
index 2435d9a7c1302e14ffae2de33b4fd4323616d1e5..7af2918dc0716133c778c7817e9ef7fa2bb70272 100644 (file)
@@ -46,7 +46,7 @@ public:
 
        ConfigItem(const String& type, const String& name, bool abstract,
            const AExpression::Ptr& exprl, const std::vector<String>& 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<String> m_ParentNames; /**< The names of parent configuration
                                       items. */
        DebugInfo m_DebugInfo; /**< Debug information. */
+       Dictionary::Ptr m_Scope; /**< variable scope. */
 
        AExpression::Ptr m_LinkedExpressionList;
 
index a9f6f77e79172c45b073711b188ff10ee549ad76..dbae3768e7d69488703d469d45b5747b41c00de4 100644 (file)
@@ -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<Array>();
-       exprs->Add(make_shared<AExpression>(&AExpression::OpDict, m_Expressions, true, m_DebugInfo));
        exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__type", make_shared<AExpression>(&AExpression::OpLiteral, m_Type, m_DebugInfo), m_DebugInfo));
        exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__name", make_shared<AExpression>(&AExpression::OpLiteral, m_Name, m_DebugInfo), m_DebugInfo));
+       exprs->Add(make_shared<AExpression>(&AExpression::OpDict, m_Expressions, true, m_DebugInfo));
        
        AExpression::Ptr exprl = make_shared<AExpression>(&AExpression::OpDict, exprs, true, m_DebugInfo);
 
        return make_shared<ConfigItem>(m_Type, m_Name, m_Abstract, exprl,
-           m_Parents, m_DebugInfo);
+           m_Parents, m_DebugInfo, m_Scope);
 }
index 8a37359d4641901f4b330dfc12bba015a6abaa6f..74fa75df63059816b7196561a01e263945990efe 100644 (file)
@@ -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. */
 };
 
 }
index 8ffe602ac0918e51deea5fca1c9edd4bae6e89ea..010987ba48809cfb139d6da0dec600c7bc9e095c 100644 (file)
@@ -77,6 +77,7 @@ void Host::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
                        ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(rule.GetDebugInfo());
                        builder->SetType("Service");
                        builder->SetName(name);
+                       builder->SetScope(rule.GetScope());
                        builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), rule.GetDebugInfo()), rule.GetDebugInfo()));
 
                        builder->AddParent(rule.GetTemplate());
index 42d5d780dc3324d3dde58c454f53e2e1ad7ad2d6..3866054731c1dafa41cf02b44159d421503b2ebc 100644 (file)
@@ -155,6 +155,8 @@ void Host::UpdateSlaveServices(void)
 
                builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, svc_exprl, true, di));
 
+               builder->SetScope(item->GetScope());
+
                ConfigItem::Ptr serviceItem = builder->Compile();
                serviceItem->Register();
                DynamicObject::Ptr dobj = serviceItem->Commit();
index 91395088768f7809171a30c3bdcc191279e43b5d..36b455beeb6ad7c4815e8702e90aa627dd2aed76 100644 (file)
@@ -231,6 +231,8 @@ void Service::UpdateSlaveDependencies(void)
 
                        builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, sd_exprl, true, di));
 
+                       builder->SetScope(item->GetScope());
+
                        ConfigItem::Ptr dependencyItem = builder->Compile();
                        dependencyItem->Register();
                        DynamicObject::Ptr dobj = dependencyItem->Commit();
index 748b618587d8cc3fd7a72f646c9df8539b4025bc..d914284a4a2c255683564f60c5279dbf0d6a19ad 100644 (file)
@@ -380,6 +380,8 @@ void Service::UpdateSlaveScheduledDowntimes(void)
 
                builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, sd_exprl, true, di));
 
+               builder->SetScope(item->GetScope());
+
                ConfigItem::Ptr scheduledDowntimeItem = builder->Compile();
                scheduledDowntimeItem->Register();
                DynamicObject::Ptr dobj = scheduledDowntimeItem->Commit();
index 344e33c0c8705587ff5400fce4e403541cfd397a..5fb711aa4c7fa078b409f5391d9925b09acea88a 100644 (file)
@@ -159,6 +159,8 @@ void Service::UpdateSlaveNotifications(void)
 
                builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, nfc_exprl, true, di));
 
+               builder->SetScope(item->GetScope());
+
                ConfigItem::Ptr notificationItem = builder->Compile();
                notificationItem->Register();
                DynamicObject::Ptr dobj = notificationItem->Commit();