]> granicus.if.org Git - icinga2/commitdiff
Implicitly set zone attribute for files includes from zones.d.
authorGunnar Beutner <gunnar.beutner@netways.de>
Tue, 13 May 2014 12:40:12 +0000 (14:40 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 13 May 2014 12:40:12 +0000 (14:40 +0200)
Refs #6191

icinga-app/icinga.cpp
lib/base/utility.cpp
lib/base/utility.h
lib/config/config_parser.yy
lib/config/configcompiler.cpp
lib/config/configcompiler.h
lib/remote/apilistener-sync.cpp

index 88e548129c44f27c6888f5d48daba691fbe26aa8..eed73d86fb18a3c46f415d3db13eefdd09d7162b 100644 (file)
@@ -65,25 +65,20 @@ static String LoadAppType(const String& typeSpec)
        return typeSpec.SubStr(index + 1);
 }
 
-static void IncludeDirRecursive(const String& path)
+static void IncludeZoneDirRecursive(const String& path)
 {
-       Utility::GlobRecursive(path, "*.conf", &ConfigCompiler::CompileFile, GlobFile);
+       String zoneName = Utility::BaseName(path);
+       Utility::GlobRecursive(path, "*.conf", boost::bind(&ConfigCompiler::CompileFile, _1, zoneName), GlobFile);
 }
 
 static void IncludeNonLocalZone(const String& zonePath)
 {
        String etcPath = Application::GetZonesDir() + "/" + Utility::BaseName(zonePath);
 
-#ifndef _WIN32
-       struct stat statbuf;
-       if (lstat(etcPath.CStr(), &statbuf) >= 0)
-#else /* _WIN32 */
-       struct _stat statbuf;
-       if (_stat(etcPath.CStr(), &statbuf) >= 0)
-#endif /* _WIN32 */
+       if (Utility::PathExists(etcPath))
                return;
 
-       IncludeDirRecursive(zonePath);
+       IncludeZoneDirRecursive(zonePath);
 }
 
 static bool LoadConfigFiles(const String& appType)
@@ -96,7 +91,9 @@ static bool LoadConfigFiles(const String& appType)
                }
        }
 
-       IncludeDirRecursive(Application::GetZonesDir());
+       String zonesDir = Application::GetZonesDir();
+
+       Utility::Glob(Application::GetZonesDir() + "/*", &IncludeZoneDirRecursive, GlobDirectory);
        Utility::Glob(Application::GetLocalStateDir() + "/lib/icinga2/api/zones/*", &IncludeNonLocalZone, GlobDirectory);
 
        /* Load cluster config files - this should probably be in libremote but
index 14eccb15d898d4f5bafaf6db7eb19ac8c441670a..45c1bc577fd92689ccebe7054de4409fa7e0652f 100644 (file)
@@ -1025,3 +1025,14 @@ tm Utility::LocalTime(time_t ts)
        return result;
 #endif /* _MSC_VER */
 }
+
+bool Utility::PathExists(const String& path)
+{
+#ifndef _WIN32
+       struct stat statbuf;
+       return (lstat(path.CStr(), &statbuf) >= 0);
+#else /* _WIN32 */
+       struct _stat statbuf;
+       return (_stat(path.CStr(), &statbuf) >= 0)
+#endif /* _WIN32 */
+}
index 34c9514956ed060e98523b10ab94a9d25f6b50b5..7217f27154d2a8f5e98d17be041145aa87a95b45 100644 (file)
@@ -123,6 +123,8 @@ public:
 
        static tm LocalTime(time_t ts);
 
+       static bool PathExists(const String& path);
+
 private:
        Utility(void);
 
index 33d50bc12d8f566f15803f39552b2346be970185..3f25ec95d30370d317e9bb3fda892815b06df476 100644 (file)
@@ -216,7 +216,6 @@ static std::stack<TypeRuleList::Ptr> m_RuleLists;
 static ConfigType::Ptr m_Type;
 
 static Dictionary::Ptr m_ModuleScope;
-static String m_Zone;
 static int m_StatementNum;
 
 static bool m_Apply;
@@ -229,7 +228,6 @@ void ConfigCompiler::Compile(void)
 {
        m_ModuleScope = make_shared<Dictionary>();
        
-       String parentZone = m_Zone;
        int parentStatementNum = m_StatementNum;
        m_StatementNum = 0;
 
@@ -242,7 +240,6 @@ void ConfigCompiler::Compile(void)
                ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
        }
 
-       m_Zone = parentZone;
        m_StatementNum = parentStatementNum;
 }
 
@@ -276,23 +273,23 @@ zone: T_ZONE rterm sep
                AExpression::Ptr aexpr = *$2;
                delete $2;
 
-               if (!m_Zone.IsEmpty())
+               if (!context->GetZone().IsEmpty())
                        BOOST_THROW_EXCEPTION(std::invalid_argument("Zone name cannot be changed once it's been set."));
 
                if (m_StatementNum != 0)
                        BOOST_THROW_EXCEPTION(std::invalid_argument("'zone' directive must be the first statement in a file."));
 
-               m_Zone = aexpr->Evaluate(m_ModuleScope);
+               context->SetZone(aexpr->Evaluate(m_ModuleScope));
        }
        | T_ZONE rterm
        {
                AExpression::Ptr aexpr = *$2;
                delete $2;
 
-               if (!m_Zone.IsEmpty())
+               if (!context->GetZone().IsEmpty())
                        BOOST_THROW_EXCEPTION(std::invalid_argument("Zone name cannot be changed once it's been set."));
 
-               m_Zone = aexpr->Evaluate(m_ModuleScope);
+               context->SetZone(aexpr->Evaluate(m_ModuleScope));
        }
        rterm_scope sep
        {
@@ -301,9 +298,9 @@ zone: T_ZONE rterm sep
 
                try {
                        ascope->Evaluate(m_ModuleScope);
-                       m_Zone = String();
+                       context->SetZone(String());
                } catch (...) {
-                       m_Zone = String();
+                       context->SetZone(String());
                }
        }
        ;
@@ -515,7 +512,7 @@ object:
 
                args->Add(filter);
 
-               args->Add(m_Zone);
+               args->Add(context->GetZone());
 
                $$ = new Value(make_shared<AExpression>(&AExpression::OpObject, args, exprl, DebugInfoRange(@2, @5)));
 
index 94ceaefc7a604d15a7a5d31af12bc5b07daba655..7f1c70dda1ec72c984c7064f576f6cd911b6dc53 100644 (file)
@@ -38,9 +38,10 @@ std::vector<String> ConfigCompiler::m_IncludeSearchDirs;
  * @param path The path of the configuration file (or another name that
  *            identifies the source of the configuration text).
  * @param input Input stream for the configuration file.
+ * @param zone The zone.
  */
-ConfigCompiler::ConfigCompiler(const String& path, std::istream *input)
-       : m_Path(path), m_Input(input)
+ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const String& zone)
+       : m_Path(path), m_Input(input), m_Zone(zone)
 {
        InitializeScanner();
 }
@@ -86,6 +87,16 @@ String ConfigCompiler::GetPath(void) const
        return m_Path;
 }
 
+void ConfigCompiler::SetZone(const String& zone)
+{
+       m_Zone = zone;
+}
+
+String ConfigCompiler::GetZone(void) const
+{
+       return m_Zone;
+}
+
 /**
  * Handles an include directive.
  *
@@ -108,13 +119,7 @@ void ConfigCompiler::HandleInclude(const String& include, bool search, const Deb
                BOOST_FOREACH(const String& dir, m_IncludeSearchDirs) {
                        String spath = dir + "/" + include;
 
-#ifndef _WIN32
-                       struct stat statbuf;
-                       if (lstat(spath.CStr(), &statbuf) >= 0) {
-#else /* _WIN32 */
-                       struct _stat statbuf;
-                       if (_stat(spath.CStr(), &statbuf) >= 0) {
-#endif /* _WIN32 */
+                       if (Utility::PathExists(spath)) {
                                includePath = spath;
                                break;
                        }
@@ -123,7 +128,7 @@ void ConfigCompiler::HandleInclude(const String& include, bool search, const Deb
 
        std::vector<ConfigItem::Ptr> items;
 
-       if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFile, _1), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
+       if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFile, _1, m_Zone), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
                std::ostringstream msgbuf;
                msgbuf << "Include file '" + include + "' does not exist: " << debuginfo;
                BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str()));
@@ -146,7 +151,7 @@ void ConfigCompiler::HandleIncludeRecursive(const String& include, const String&
        else
                path = Utility::DirName(GetPath()) + "/" + include;
 
-       Utility::GlobRecursive(path, pattern, boost::bind(&ConfigCompiler::CompileFile, _1), GlobFile);
+       Utility::GlobRecursive(path, pattern, boost::bind(&ConfigCompiler::CompileFile, _1, m_Zone), GlobFile);
 }
 
 /**
@@ -166,13 +171,13 @@ void ConfigCompiler::HandleLibrary(const String& library)
  * @param stream The input stream.
  * @returns Configuration items.
  */
-void ConfigCompiler::CompileStream(const String& path, std::istream *stream)
+void ConfigCompiler::CompileStream(const String& path, std::istream *stream, const String& zone)
 {
        CONTEXT("Compiling configuration stream with name '" + path + "'");
 
        stream->exceptions(std::istream::badbit);
 
-       ConfigCompiler ctx(path, stream);
+       ConfigCompiler ctx(path, stream, zone);
        ctx.Compile();
 }
 
@@ -182,7 +187,7 @@ void ConfigCompiler::CompileStream(const String& path, std::istream *stream)
  * @param path The path.
  * @returns Configuration items.
  */
-void ConfigCompiler::CompileFile(const String& path)
+void ConfigCompiler::CompileFile(const String& path, const String& zone)
 {
        CONTEXT("Compiling configuration file '" + path + "'");
 
@@ -197,7 +202,7 @@ void ConfigCompiler::CompileFile(const String& path)
 
        Log(LogInformation, "config", "Compiling config file: " + path);
 
-       return CompileStream(path, &stream);
+       return CompileStream(path, &stream, zone);
 }
 
 /**
@@ -207,10 +212,10 @@ void ConfigCompiler::CompileFile(const String& path)
  * @param text The text.
  * @returns Configuration items.
  */
-void ConfigCompiler::CompileText(const String& path, const String& text)
+void ConfigCompiler::CompileText(const String& path, const String& text, const String& zone)
 {
        std::stringstream stream(text);
-       return CompileStream(path, &stream);
+       return CompileStream(path, &stream, zone);
 }
 
 /**
index 59b36a9596ff0fc89b0b592fabeb7a0348b0979b..b9631dc388969752f3cb68755a3c49e3d5aec7d7 100644 (file)
@@ -40,19 +40,22 @@ namespace icinga
 class I2_CONFIG_API ConfigCompiler
 {
 public:
-       explicit ConfigCompiler(const String& path, std::istream *input);
+       explicit ConfigCompiler(const String& path, std::istream *input, const String& zone = String());
        virtual ~ConfigCompiler(void);
 
        void Compile(void);
 
-       static void CompileStream(const String& path, std::istream *stream);
-       static void CompileFile(const String& path);
-       static void CompileText(const String& path, const String& text);
+       static void CompileStream(const String& path, std::istream *stream, const String& zone = String());
+       static void CompileFile(const String& path, const String& zone = String());
+       static void CompileText(const String& path, const String& text, const String& zone = String());
 
        static void AddIncludeSearchDir(const String& dir);
 
        String GetPath(void) const;
 
+       void SetZone(const String& zone);
+       String GetZone(void) const;
+
        /* internally used methods */
        void HandleInclude(const String& include, bool search, const DebugInfo& debuginfo);
        void HandleIncludeRecursive(const String& include, const String& pattern, const DebugInfo& debuginfo);
@@ -64,6 +67,7 @@ public:
 private:
        String m_Path;
        std::istream *m_Input;
+       String m_Zone;
 
        void *m_Scanner;
 
index 6bfc9e57b30f307eb61bc238835bf6beb945b253..556d1289f35192fda81b7edd70a8950d437f854f 100644 (file)
@@ -28,14 +28,7 @@ using namespace icinga;
 bool ApiListener::IsConfigMaster(const Zone::Ptr& zone) const
 {
        String path = Application::GetZonesDir() + "/" + zone->GetName();
-
-#ifndef _WIN32
-       struct stat statbuf;
-       return (lstat(path.CStr(), &statbuf) >= 0);
-#else /* _WIN32 */
-       struct _stat statbuf;
-       return (_stat(path.CStr(), &statbuf) >= 0);
-#endif /* _WIN32 */
+       return Utility::PathExists(path);
 }
 
 void ApiListener::ConfigGlobHandler(const Dictionary::Ptr& config, const String& path, const String& file)