mirror of https://github.com/Icinga/icinga2.git
Implicitly set zone attribute for files includes from zones.d.
Refs #6191
This commit is contained in:
parent
c089b7950d
commit
3a1ce23aeb
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -123,6 +123,8 @@ public:
|
|||
|
||||
static tm LocalTime(time_t ts);
|
||||
|
||||
static bool PathExists(const String& path);
|
||||
|
||||
private:
|
||||
Utility(void);
|
||||
|
||||
|
|
|
@ -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)));
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue