Skip to content

Commit

Permalink
Add module attribute for ConfigObject and set its origin
Browse files Browse the repository at this point in the history
fixes #9852
  • Loading branch information
Michael Friedrich committed Aug 17, 2015
1 parent 13b5ace commit 0f5287c
Show file tree
Hide file tree
Showing 18 changed files with 119 additions and 56 deletions.
1 change: 1 addition & 0 deletions lib/base/configobject.ti
Expand Up @@ -73,6 +73,7 @@ abstract class ConfigObject : ConfigObjectBase
};
[config, internal, get_protected] String type (TypeNameV);
[config] name(Zone) zone (ZoneName);
[config] String module;
[config, internal, get_protected] Array::Ptr templates;
[get_protected] bool active;
[get_protected] bool paused {
Expand Down
40 changes: 25 additions & 15 deletions lib/cli/daemonutility.cpp
Expand Up @@ -28,7 +28,7 @@

using namespace icinga;

bool ExecuteExpression(Expression *expression)
static bool ExecuteExpression(Expression *expression)
{
if (!expression)
return false;
Expand All @@ -44,28 +44,43 @@ bool ExecuteExpression(Expression *expression)
return true;
}

void IncludeZoneDirRecursive(const String& path, bool& success)
static void IncludeZoneDirRecursive(const String& path, const String& module, bool& success)
{
String zoneName = Utility::BaseName(path);

/* register this zone path for cluster config sync */
ConfigCompiler::RegisterZoneDir("_etc", path, zoneName);

std::vector<Expression *> expressions;
Utility::GlobRecursive(path, "*.conf", boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zoneName), GlobFile);
Utility::GlobRecursive(path, "*.conf", boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zoneName, module), GlobFile);
DictExpression expr(expressions);
if (!ExecuteExpression(&expr))
success = false;
}

void IncludeNonLocalZone(const String& zonePath, bool& success)
static void IncludeNonLocalZone(const String& zonePath, const String& module, bool& success)
{
String etcPath = Application::GetZonesDir() + "/" + Utility::BaseName(zonePath);

if (Utility::PathExists(etcPath) || Utility::PathExists(zonePath + "/.authoritative"))
return;

IncludeZoneDirRecursive(zonePath, success);
IncludeZoneDirRecursive(zonePath, module, success);
}

static void IncludeModule(const String& modulePath, bool& success)
{
String moduleName = Utility::BaseName(modulePath);

if (Utility::PathExists(modulePath + "/include.conf")) {
Expression *expr = ConfigCompiler::CompileFile(modulePath + "/include.conf",
true, String(), moduleName);

if (!ExecuteExpression(expr))
success = false;

delete expr;
}
}

bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs, const String& objectsFile)
Expand All @@ -76,7 +91,7 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,

if (!configs.empty()) {
BOOST_FOREACH(const String& configPath, configs) {
Expression *expression = ConfigCompiler::CompileFile(configPath);
Expression *expression = ConfigCompiler::CompileFile(configPath, true, String(), "_etc");
success = ExecuteExpression(expression);
delete expression;
if (!success)
Expand All @@ -90,26 +105,21 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,

String zonesEtcDir = Application::GetZonesDir();
if (!zonesEtcDir.IsEmpty() && Utility::PathExists(zonesEtcDir))
Utility::Glob(zonesEtcDir + "/*", boost::bind(&IncludeZoneDirRecursive, _1, boost::ref(success)), GlobDirectory);
Utility::Glob(zonesEtcDir + "/*", boost::bind(&IncludeZoneDirRecursive, _1, "_etc", boost::ref(success)), GlobDirectory);

if (!success)
return false;

String zonesVarDir = Application::GetLocalStateDir() + "/lib/icinga2/api/zones";
if (Utility::PathExists(zonesVarDir))
Utility::Glob(zonesVarDir + "/*", boost::bind(&IncludeNonLocalZone, _1, boost::ref(success)), GlobDirectory);
Utility::Glob(zonesVarDir + "/*", boost::bind(&IncludeNonLocalZone, _1, "_cluster", boost::ref(success)), GlobDirectory);

if (!success)
return false;

String modulesVarDir = Application::GetLocalStateDir() + "/lib/icinga2/api/modules";
if (Utility::PathExists(modulesVarDir)) {
std::vector<Expression *> expressions;
Utility::Glob(modulesVarDir + "/*/include.conf", boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, ""), GlobFile);
DictExpression expr(expressions);
if (!ExecuteExpression(&expr))
success = false;
}
if (Utility::PathExists(modulesVarDir))
Utility::Glob(modulesVarDir + "/*", boost::bind(&IncludeModule, _1, boost::ref(success)), GlobDirectory);

if (!success)
return false;
Expand Down
13 changes: 9 additions & 4 deletions lib/config/applyrule.cpp
Expand Up @@ -28,9 +28,9 @@ ApplyRule::RuleMap ApplyRule::m_Rules;
ApplyRule::TypeMap ApplyRule::m_Types;

ApplyRule::ApplyRule(const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm,
const boost::shared_ptr<Expression>& filter, const String& module, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm,
const DebugInfo& di, const Dictionary::Ptr& scope)
: m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_FKVar(fkvar),
: m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_Module(module), m_FKVar(fkvar),
m_FVVar(fvvar), m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope), m_HasMatches(false)
{ }

Expand All @@ -54,6 +54,11 @@ boost::shared_ptr<Expression> ApplyRule::GetFilter(void) const
return m_Filter;
}

String ApplyRule::GetModule(void) const
{
return m_Module;
}

String ApplyRule::GetFKVar(void) const
{
return m_FKVar;
Expand All @@ -80,10 +85,10 @@ Dictionary::Ptr ApplyRule::GetScope(void) const
}

void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
const boost::shared_ptr<Expression>& expression, const boost::shared_ptr<Expression>& filter, const String& fkvar,
const boost::shared_ptr<Expression>& expression, const boost::shared_ptr<Expression>& filter, const String& module, const String& fkvar,
const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Dictionary::Ptr& scope)
{
m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, fkvar, fvvar, fterm, di, scope));
m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, module, fkvar, fvvar, fterm, di, scope));
}

bool ApplyRule::EvaluateFilter(ScriptFrame& frame) const
Expand Down
6 changes: 4 additions & 2 deletions lib/config/applyrule.hpp
Expand Up @@ -41,6 +41,7 @@ class I2_CONFIG_API ApplyRule
String GetName(void) const;
boost::shared_ptr<Expression> GetExpression(void) const;
boost::shared_ptr<Expression> GetFilter(void) const;
String GetModule(void) const;
String GetFKVar(void) const;
String GetFVVar(void) const;
boost::shared_ptr<Expression> GetFTerm(void) const;
Expand All @@ -52,7 +53,7 @@ class I2_CONFIG_API ApplyRule
bool EvaluateFilter(ScriptFrame& frame) const;

static void AddRule(const String& sourceType, const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Dictionary::Ptr& scope);
const boost::shared_ptr<Expression>& filter, const String& module, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Dictionary::Ptr& scope);
static std::vector<ApplyRule>& GetRules(const String& type);

static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes);
Expand All @@ -68,6 +69,7 @@ class I2_CONFIG_API ApplyRule
String m_Name;
boost::shared_ptr<Expression> m_Expression;
boost::shared_ptr<Expression> m_Filter;
String m_Module;
String m_FKVar;
String m_FVVar;
boost::shared_ptr<Expression> m_FTerm;
Expand All @@ -79,7 +81,7 @@ class I2_CONFIG_API ApplyRule
static RuleMap m_Rules;

ApplyRule(const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm,
const boost::shared_ptr<Expression>& filter, const String& module, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm,
const DebugInfo& di, const Dictionary::Ptr& scope);
};

Expand Down
4 changes: 2 additions & 2 deletions lib/config/config_parser.yy
Expand Up @@ -384,7 +384,7 @@ object:
BOOST_THROW_EXCEPTION(ScriptError("object rule 'ignore' is missing 'assign' for type '" + type + "'", DebugInfoRange(@2, @4)));
}

$$ = new ObjectExpression(abstract, type, $4, filter, context->GetZone(), $5, $6, DebugInfoRange(@2, @5));
$$ = new ObjectExpression(abstract, type, $4, filter, context->GetZone(), context->GetModule(), $5, $6, DebugInfoRange(@2, @5));
}
;

Expand Down Expand Up @@ -1017,7 +1017,7 @@ apply:
Expression *fterm = context->m_FTerm.top();
context->m_FTerm.pop();

$$ = new ApplyExpression(type, target, $4, filter, fkvar, fvvar, fterm, $7, $8, DebugInfoRange(@2, @7));
$$ = new ApplyExpression(type, target, $4, filter, context->GetModule(), fkvar, fvvar, fterm, $7, $8, DebugInfoRange(@2, @7));
}
;

Expand Down
42 changes: 29 additions & 13 deletions lib/config/configcompiler.cpp
Expand Up @@ -40,8 +40,10 @@ std::map<String, std::vector<ZoneFragment> > ConfigCompiler::m_ZoneDirs;
* @param input Input stream for the configuration file.
* @param zone The zone.
*/
ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const String& zone)
: m_Path(path), m_Input(input), m_Zone(zone), m_Eof(false), m_OpenBraces(0), m_IgnoreNewlines(0)
ConfigCompiler::ConfigCompiler(const String& path, std::istream *input,
const String& zone, const String& module)
: m_Path(path), m_Input(input), m_Zone(zone), m_Module(module),
m_Eof(false), m_OpenBraces(0), m_IgnoreNewlines(0)
{
InitializeScanner();
}
Expand Down Expand Up @@ -98,9 +100,20 @@ String ConfigCompiler::GetZone(void) const
return m_Zone;
}

void ConfigCompiler::CollectIncludes(std::vector<Expression *>& expressions, const String& file, const String& zone)
void ConfigCompiler::SetModule(const String& module)
{
expressions.push_back(CompileFile(file, true, zone));
m_Module = module;
}

String ConfigCompiler::GetModule(void) const
{
return m_Module;
}

void ConfigCompiler::CollectIncludes(std::vector<Expression *>& expressions,
const String& file, const String& zone, const String& module)
{
expressions.push_back(CompileFile(file, true, zone, module));
}

/**
Expand Down Expand Up @@ -134,7 +147,7 @@ Expression *ConfigCompiler::HandleInclude(const String& include, bool search, co

std::vector<Expression *> expressions;

if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, m_Zone), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, m_Zone, m_Module), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
std::ostringstream msgbuf;
msgbuf << "Include file '" + include + "' does not exist";
BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debuginfo));
Expand Down Expand Up @@ -162,7 +175,7 @@ Expression *ConfigCompiler::HandleIncludeRecursive(const String& path, const Str
ppath = Utility::DirName(GetPath()) + "/" + path;

std::vector<Expression *> expressions;
Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, m_Zone), GlobFile);
Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, m_Zone, m_Module), GlobFile);
return new DictExpression(expressions);
}

Expand All @@ -179,7 +192,7 @@ void ConfigCompiler::HandleIncludeZone(const String& tag, const String& path, co

RegisterZoneDir(tag, ppath, zoneName);

Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zoneName), GlobFile);
Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zoneName, m_Module), GlobFile);
}

/**
Expand Down Expand Up @@ -232,13 +245,14 @@ void ConfigCompiler::CompileHelper(void)
* @param stream The input stream.
* @returns Configuration items.
*/
Expression *ConfigCompiler::CompileStream(const String& path, std::istream *stream, bool async, const String& zone)
Expression *ConfigCompiler::CompileStream(const String& path,
std::istream *stream, bool async, const String& zone, const String& module)
{
CONTEXT("Compiling configuration stream with name '" + path + "'");

stream->exceptions(std::istream::badbit);

ConfigCompiler* ctx = new ConfigCompiler(path, stream, zone);
ConfigCompiler* ctx = new ConfigCompiler(path, stream, zone, module);

if (async) {
boost::shared_future<boost::shared_ptr<Expression> > ftr = boost::shared_future<boost::shared_ptr<Expression> >(ctx->m_Promise.get_future());
Expand Down Expand Up @@ -266,7 +280,8 @@ Expression *ConfigCompiler::CompileStream(const String& path, std::istream *stre
* @param path The path.
* @returns Configuration items.
*/
Expression *ConfigCompiler::CompileFile(const String& path, bool async, const String& zone)
Expression *ConfigCompiler::CompileFile(const String& path, bool async,
const String& zone, const String& module)
{
CONTEXT("Compiling configuration file '" + path + "'");

Expand All @@ -282,7 +297,7 @@ Expression *ConfigCompiler::CompileFile(const String& path, bool async, const St
Log(LogInformation, "ConfigCompiler")
<< "Compiling config file: " << path;

return CompileStream(path, stream, async, zone);
return CompileStream(path, stream, async, zone, module);
}

/**
Expand All @@ -292,10 +307,11 @@ Expression *ConfigCompiler::CompileFile(const String& path, bool async, const St
* @param text The text.
* @returns Configuration items.
*/
Expression *ConfigCompiler::CompileText(const String& path, const String& text, bool async, const String& zone)
Expression *ConfigCompiler::CompileText(const String& path, const String& text,
bool async, const String& zone, const String& module)
{
std::stringstream *stream = new std::stringstream(text);
return CompileStream(path, stream, async, zone);
return CompileStream(path, stream, async, zone, module);
}

/**
Expand Down
19 changes: 14 additions & 5 deletions lib/config/configcompiler.hpp
Expand Up @@ -79,23 +79,31 @@ struct ZoneFragment
class I2_CONFIG_API ConfigCompiler
{
public:
explicit ConfigCompiler(const String& path, std::istream *input, const String& zone = String());
explicit ConfigCompiler(const String& path, std::istream *input,
const String& zone = String(), const String& module = String());
virtual ~ConfigCompiler(void);

Expression *Compile(void);

static Expression *CompileStream(const String& path, std::istream *stream, bool async = true, const String& zone = String());
static Expression *CompileFile(const String& path, bool async = true, const String& zone = String());
static Expression *CompileText(const String& path, const String& text, bool async = true, const String& zone = String());
static Expression *CompileStream(const String& path, std::istream *stream,
bool async = true, const String& zone = String(), const String& module = String());
static Expression *CompileFile(const String& path, bool async = true,
const String& zone = String(), const String& module = String());
static Expression *CompileText(const String& path, const String& text,
bool async = true, const String& zone = String(), const String& module = String());

static void AddIncludeSearchDir(const String& dir);

const char *GetPath(void) const;

void SetZone(const String& zone);
String GetZone(void) const;

void SetModule(const String& module);
String GetModule(void) const;

static void CollectIncludes(std::vector<Expression *>& expressions, const String& file, const String& zone);
static void CollectIncludes(std::vector<Expression *>& expressions,
const String& file, const String& zone, const String& module);

/* internally used methods */
Expression *HandleInclude(const String& include, bool search, const DebugInfo& debuginfo = DebugInfo());
Expand All @@ -117,6 +125,7 @@ class I2_CONFIG_API ConfigCompiler
String m_Path;
std::istream *m_Input;
String m_Zone;
String m_Module;

void *m_Scanner;

Expand Down
6 changes: 4 additions & 2 deletions lib/config/configitem.cpp
Expand Up @@ -62,10 +62,11 @@ ConfigItem::ConfigItem(const String& type, const String& name,
bool abstract, const boost::shared_ptr<Expression>& exprl,
const boost::shared_ptr<Expression>& filter,
const DebugInfo& debuginfo, const Dictionary::Ptr& scope,
const String& zone)
const String& zone, const String& module)
: m_Type(type), m_Name(name), m_Abstract(abstract),
m_Expression(exprl), m_Filter(filter),
m_DebugInfo(debuginfo), m_Scope(scope), m_Zone(zone)
m_DebugInfo(debuginfo), m_Scope(scope), m_Zone(zone),
m_Module(module)
{
}

Expand Down Expand Up @@ -170,6 +171,7 @@ ConfigObject::Ptr ConfigItem::Commit(bool discard)
dobj->SetDebugInfo(m_DebugInfo);
dobj->SetTypeNameV(m_Type);
dobj->SetZoneName(m_Zone);
dobj->SetModule(m_Module);
dobj->SetName(m_Name);

DebugHint debugHints;
Expand Down

0 comments on commit 0f5287c

Please sign in to comment.