mirror of https://github.com/Icinga/icinga2.git
parent
8568b4b701
commit
a7e25beb06
|
@ -577,7 +577,7 @@ void CompatLog::ValidateRotationMethod(const String& location, const Dictionary:
|
|||
|
||||
if (!rotation_method.IsEmpty() && rotation_method != "HOURLY" && rotation_method != "DAILY" &&
|
||||
rotation_method != "WEEKLY" && rotation_method != "MONTHLY" && rotation_method != "NONE") {
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, "Validation failed for " +
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||
location + ": Rotation method '" + rotation_method + "' is invalid.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,50 +58,23 @@ static bool LoadConfigFiles(bool validateOnly)
|
|||
ConfigCompiler::CompileText(name, fragment);
|
||||
}
|
||||
|
||||
bool hasError = false;
|
||||
|
||||
BOOST_FOREACH(const ConfigCompilerError& error, ConfigCompilerContext::GetInstance()->GetErrors()) {
|
||||
if (!error.Warning) {
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't link or validate if we have already encountered at least one error. */
|
||||
if (!hasError) {
|
||||
ConfigItem::LinkItems();
|
||||
ConfigItem::ValidateItems();
|
||||
}
|
||||
|
||||
hasError = false;
|
||||
|
||||
BOOST_FOREACH(const ConfigCompilerError& error, ConfigCompilerContext::GetInstance()->GetErrors()) {
|
||||
if (error.Warning) {
|
||||
Log(LogWarning, "icinga-app", "Config warning: " + error.Message);
|
||||
} else {
|
||||
hasError = true;
|
||||
Log(LogCritical, "icinga-app", "Config error: " + error.Message);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasError)
|
||||
return false;
|
||||
|
||||
if (validateOnly)
|
||||
return true;
|
||||
|
||||
if (Application::GetInstance()) {
|
||||
Log(LogCritical, "icinga-app", "You must not manually create an Application object.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>();
|
||||
builder->SetType(Application::GetApplicationType());
|
||||
builder->SetName("application");
|
||||
ConfigItem::Ptr item = builder->Compile();
|
||||
item->Register();
|
||||
|
||||
ConfigItem::ActivateItems();
|
||||
bool result = ConfigItem::ActivateItems(validateOnly);
|
||||
|
||||
BOOST_FOREACH(const ConfigCompilerMessage& message, ConfigCompilerContext::GetInstance()->GetMessages()) {
|
||||
if (message.Error)
|
||||
Log(LogCritical, "config", "Config error: " + message.Text);
|
||||
else
|
||||
Log(LogWarning, "config", "Config warning: " + message.Text);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
ConfigItem::DiscardItems();
|
||||
ConfigType::DiscardTypes();
|
||||
|
|
|
@ -1061,7 +1061,7 @@ YY_RULE_SETUP
|
|||
{
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Unterminated string found: " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, msgbuf.str());
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
YY_BREAK
|
||||
|
@ -1078,7 +1078,7 @@ YY_RULE_SETUP
|
|||
/* error, constant is out-of-bounds */
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Constant is out-of-bounds: " << yytext << " " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, msgbuf.str());
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
}
|
||||
|
||||
lb_append_char(&string_buf, result);
|
||||
|
@ -1093,7 +1093,7 @@ YY_RULE_SETUP
|
|||
*/
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Bad escape sequence found: " << yytext << " " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, msgbuf.str());
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
}
|
||||
YY_BREAK
|
||||
case 6:
|
||||
|
|
|
@ -116,7 +116,7 @@ static char *lb_steal(lex_buf *lb)
|
|||
<STRING>\n {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Unterminated string found: " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, msgbuf.str());
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ static char *lb_steal(lex_buf *lb)
|
|||
/* error, constant is out-of-bounds */
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Constant is out-of-bounds: " << yytext << " " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, msgbuf.str());
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
}
|
||||
|
||||
lb_append_char(&string_buf, result);
|
||||
|
@ -142,7 +142,7 @@ static char *lb_steal(lex_buf *lb)
|
|||
*/
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Bad escape sequence found: " << yytext << " " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, msgbuf.str());
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
}
|
||||
|
||||
<STRING>\\n { lb_append_char(&string_buf, '\n'); }
|
||||
|
|
|
@ -267,7 +267,7 @@ void yyerror(YYLTYPE *locp, ConfigCompiler *, const char *err)
|
|||
{
|
||||
std::ostringstream message;
|
||||
message << *locp << ": " << err;
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, message.str());
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, message.str());
|
||||
}
|
||||
|
||||
int yyparse(ConfigCompiler *context);
|
||||
|
@ -283,7 +283,7 @@ void ConfigCompiler::Compile(void)
|
|||
try {
|
||||
yyparse(this);
|
||||
} catch (const std::exception& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, boost::diagnostic_information(ex));
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, boost::diagnostic_information(ex));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ void yyerror(YYLTYPE *locp, ConfigCompiler *, const char *err)
|
|||
{
|
||||
std::ostringstream message;
|
||||
message << *locp << ": " << err;
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, message.str());
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, message.str());
|
||||
}
|
||||
|
||||
int yyparse(ConfigCompiler *context);
|
||||
|
@ -140,7 +140,7 @@ void ConfigCompiler::Compile(void)
|
|||
try {
|
||||
yyparse(this);
|
||||
} catch (const std::exception& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, boost::diagnostic_information(ex));
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, boost::diagnostic_information(ex));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,19 +25,29 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
void ConfigCompilerContext::AddError(bool warning, const String& message)
|
||||
void ConfigCompilerContext::AddMessage(bool error, const String& message)
|
||||
{
|
||||
m_Errors.push_back(ConfigCompilerError(warning, message));
|
||||
m_Messages.push_back(ConfigCompilerMessage(error, message));
|
||||
}
|
||||
|
||||
std::vector<ConfigCompilerError> ConfigCompilerContext::GetErrors(void) const
|
||||
std::vector<ConfigCompilerMessage> ConfigCompilerContext::GetMessages(void) const
|
||||
{
|
||||
return m_Errors;
|
||||
return m_Messages;
|
||||
}
|
||||
|
||||
bool ConfigCompilerContext::HasErrors(void) const
|
||||
{
|
||||
BOOST_FOREACH(const ConfigCompilerMessage& message, m_Messages) {
|
||||
if (message.Error)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConfigCompilerContext::Reset(void)
|
||||
{
|
||||
m_Errors.clear();
|
||||
m_Messages.clear();
|
||||
}
|
||||
|
||||
ConfigCompilerContext *ConfigCompilerContext::GetInstance(void)
|
||||
|
|
|
@ -27,13 +27,13 @@
|
|||
namespace icinga
|
||||
{
|
||||
|
||||
struct I2_CONFIG_API ConfigCompilerError
|
||||
struct I2_CONFIG_API ConfigCompilerMessage
|
||||
{
|
||||
bool Warning;
|
||||
String Message;
|
||||
bool Error;
|
||||
String Text;
|
||||
|
||||
ConfigCompilerError(bool warning, const String& message)
|
||||
: Warning(warning), Message(message)
|
||||
ConfigCompilerMessage(bool error, const String& text)
|
||||
: Error(error), Text(text)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -43,15 +43,16 @@ struct I2_CONFIG_API ConfigCompilerError
|
|||
class I2_CONFIG_API ConfigCompilerContext
|
||||
{
|
||||
public:
|
||||
void AddError(bool warning, const String& message);
|
||||
std::vector<ConfigCompilerError> GetErrors(void) const;
|
||||
void AddMessage(bool error, const String& message);
|
||||
std::vector<ConfigCompilerMessage> GetMessages(void) const;
|
||||
bool HasErrors(void) const;
|
||||
|
||||
void Reset(void);
|
||||
|
||||
static ConfigCompilerContext *GetInstance(void);
|
||||
|
||||
private:
|
||||
std::vector<ConfigCompilerError> m_Errors;
|
||||
std::vector<ConfigCompilerMessage> m_Messages;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -116,13 +116,13 @@ void ConfigItem::Link(void)
|
|||
std::ostringstream message;
|
||||
message << "Parent object '" << name << "' does not"
|
||||
" exist (" << m_DebugInfo << ")";
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument(message.str()));
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, message.str());
|
||||
} else {
|
||||
parent->Link();
|
||||
|
||||
ExpressionList::Ptr pexprl = parent->GetLinkedExpressionList();
|
||||
m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, pexprl, m_DebugInfo));
|
||||
}
|
||||
|
||||
parent->Link();
|
||||
|
||||
ExpressionList::Ptr pexprl = parent->GetLinkedExpressionList();
|
||||
m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, pexprl, m_DebugInfo));
|
||||
}
|
||||
|
||||
m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, m_ExpressionList, m_DebugInfo));
|
||||
|
@ -233,41 +233,38 @@ ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
|||
return ConfigItem::Ptr();
|
||||
}
|
||||
|
||||
void ConfigItem::LinkItems(void)
|
||||
void ConfigItem::ValidateItem(void)
|
||||
{
|
||||
ConfigType::Ptr ctype = ConfigType::GetByName(GetType());
|
||||
|
||||
if (!ctype) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(false, "No validation type found for object '" + GetName() + "' of type '" + GetType() + "'");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ctype->ValidateItem(GetSelf());
|
||||
}
|
||||
|
||||
bool ConfigItem::ActivateItems(bool validateOnly)
|
||||
{
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
return false;
|
||||
|
||||
Log(LogInformation, "config", "Linking config items...");
|
||||
|
||||
ConfigItem::Ptr item;
|
||||
BOOST_FOREACH(boost::tie(boost::tuples::ignore, item), m_Items) {
|
||||
item->Link();
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigItem::ValidateItems(void)
|
||||
{
|
||||
Log(LogInformation, "config", "Validating config items...");
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
return false;
|
||||
|
||||
ConfigItem::Ptr item;
|
||||
BOOST_FOREACH(boost::tie(boost::tuples::ignore, item), m_Items) {
|
||||
ConfigType::Ptr ctype = ConfigType::GetByName(item->GetType());
|
||||
|
||||
if (!ctype) {
|
||||
ConfigCompilerContext::GetInstance()->AddError(true, "No validation type found for object '" + item->GetName() + "' of type '" + item->GetType() + "'");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ctype->ValidateItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigItem::ActivateItems(void)
|
||||
{
|
||||
Log(LogInformation, "config", "Activating config items");
|
||||
|
||||
std::vector<DynamicObject::Ptr> objects;
|
||||
|
||||
ConfigItem::Ptr item;
|
||||
BOOST_FOREACH(boost::tie(boost::tuples::ignore, item), m_Items) {
|
||||
DynamicObject::Ptr object = item->Commit();
|
||||
|
||||
|
@ -279,6 +276,16 @@ void ConfigItem::ActivateItems(void)
|
|||
object->OnConfigLoaded();
|
||||
}
|
||||
|
||||
BOOST_FOREACH(boost::tie(boost::tuples::ignore, item), m_Items) {
|
||||
item->ValidateItem();
|
||||
}
|
||||
|
||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||
return false;
|
||||
|
||||
if (validateOnly)
|
||||
return true;
|
||||
|
||||
/* restore the previous program state */
|
||||
DynamicObject::RestoreObjects(Application::GetStatePath());
|
||||
|
||||
|
@ -293,6 +300,8 @@ void ConfigItem::ActivateItems(void)
|
|||
ASSERT(object->IsActive());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConfigItem::DiscardItems(void)
|
||||
|
|
|
@ -62,9 +62,9 @@ public:
|
|||
static ConfigItem::Ptr GetObject(const String& type,
|
||||
const String& name);
|
||||
|
||||
static void LinkItems(void);
|
||||
static void ValidateItems(void);
|
||||
static void ActivateItems(void);
|
||||
void ValidateItem(void);
|
||||
|
||||
static bool ActivateItems(bool validateOnly);
|
||||
static void DiscardItems(void);
|
||||
|
||||
private:
|
||||
|
|
|
@ -121,7 +121,7 @@ void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary,
|
|||
Value value = dictionary->Get(require);
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
ConfigCompilerContext::GetInstance()->AddError(false,
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true,
|
||||
"Required attribute is missing: " + LocationToString(locations));
|
||||
}
|
||||
|
||||
|
@ -175,14 +175,14 @@ void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary,
|
|||
}
|
||||
|
||||
if (overallResult == ValidationUnknownField)
|
||||
ConfigCompilerContext::GetInstance()->AddError(true, "Unknown attribute: " + LocationToString(locations));
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(false, "Unknown attribute: " + LocationToString(locations));
|
||||
else if (overallResult == ValidationInvalidType) {
|
||||
String message = "Invalid value for attribute: " + LocationToString(locations);
|
||||
|
||||
if (!hint.IsEmpty())
|
||||
message += ": " + hint;
|
||||
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, message);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, message);
|
||||
}
|
||||
|
||||
if (!subRuleLists.empty() && value.IsObjectType<Dictionary>())
|
||||
|
@ -204,7 +204,7 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
|
|||
locations.push_back("Attribute '" + require + "'");
|
||||
|
||||
if (array->GetLength() < index) {
|
||||
ConfigCompilerContext::GetInstance()->AddError(false,
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true,
|
||||
"Required array index is missing: " + LocationToString(locations));
|
||||
}
|
||||
|
||||
|
@ -261,14 +261,14 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
|
|||
}
|
||||
|
||||
if (overallResult == ValidationUnknownField)
|
||||
ConfigCompilerContext::GetInstance()->AddError(true, "Unknown attribute: " + LocationToString(locations));
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(false, "Unknown attribute: " + LocationToString(locations));
|
||||
else if (overallResult == ValidationInvalidType) {
|
||||
String message = "Invalid value for array index: " + LocationToString(locations);
|
||||
|
||||
if (!hint.IsEmpty())
|
||||
message += ": " + hint;
|
||||
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, message);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, message);
|
||||
}
|
||||
|
||||
if (!subRuleLists.empty() && value.IsObjectType<Dictionary>())
|
||||
|
|
|
@ -58,6 +58,11 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
|
|||
Array::Ptr array;
|
||||
|
||||
switch (m_Operator) {
|
||||
case OperatorNop:
|
||||
/* Nothing to do here. */
|
||||
|
||||
return;
|
||||
|
||||
case OperatorExecute:
|
||||
if (!valueExprl)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Operand for OperatorExecute must be an ExpressionList."));
|
||||
|
@ -165,3 +170,41 @@ void Expression::ExtractFiltered(const std::set<String, string_iless>& keys, con
|
|||
exprl->ExtractFiltered(keys, result);
|
||||
}
|
||||
}
|
||||
|
||||
void Expression::ErasePath(const std::vector<String>& path)
|
||||
{
|
||||
ASSERT(!path.empty());
|
||||
|
||||
if (path[0] == m_Key) {
|
||||
if (path.size() == 1) {
|
||||
m_Operator = OperatorNop;
|
||||
} else if (m_Value.IsObjectType<ExpressionList>()) {
|
||||
ExpressionList::Ptr exprl = m_Value;
|
||||
|
||||
std::vector<String> sub_path(path.begin() + 1, path.end());
|
||||
exprl->ErasePath(sub_path);
|
||||
}
|
||||
} else if (m_Operator == OperatorExecute) {
|
||||
ExpressionList::Ptr exprl = m_Value;
|
||||
exprl->ErasePath(path);
|
||||
}
|
||||
}
|
||||
|
||||
void Expression::FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const
|
||||
{
|
||||
ASSERT(!path.empty());
|
||||
|
||||
if (path[0] == m_Key) {
|
||||
if (path.size() == 1) {
|
||||
result = m_DebugInfo;
|
||||
} else if (m_Value.IsObjectType<ExpressionList>()) {
|
||||
ExpressionList::Ptr exprl = m_Value;
|
||||
|
||||
std::vector<String> sub_path(path.begin() + 1, path.end());
|
||||
exprl->FindDebugInfoPath(sub_path, result);
|
||||
}
|
||||
} else if (m_Operator == OperatorExecute) {
|
||||
ExpressionList::Ptr exprl = m_Value;
|
||||
exprl->FindDebugInfoPath(path, result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace icinga
|
|||
*/
|
||||
enum ExpressionOperator
|
||||
{
|
||||
OperatorNop,
|
||||
OperatorExecute,
|
||||
OperatorSet,
|
||||
OperatorPlus,
|
||||
|
@ -63,6 +64,10 @@ public:
|
|||
void ExtractPath(const std::vector<String>& path, const shared_ptr<ExpressionList>& result) const;
|
||||
void ExtractFiltered(const std::set<String, string_iless>& keys, const shared_ptr<ExpressionList>& result) const;
|
||||
|
||||
void ErasePath(const std::vector<String>& path);
|
||||
|
||||
void FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const;
|
||||
|
||||
private:
|
||||
String m_Key;
|
||||
ExpressionOperator m_Operator;
|
||||
|
|
|
@ -68,3 +68,17 @@ void ExpressionList::ExtractFiltered(const std::set<String, string_iless>& keys,
|
|||
expression.ExtractFiltered(keys, result);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionList::ErasePath(const std::vector<String>& path)
|
||||
{
|
||||
BOOST_FOREACH(Expression& expression, m_Expressions) {
|
||||
expression.ErasePath(path);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionList::FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const
|
||||
{
|
||||
BOOST_FOREACH(const Expression& expression, m_Expressions) {
|
||||
expression.FindDebugInfoPath(path, result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,10 @@ public:
|
|||
void ExtractPath(const std::vector<String>& path, const ExpressionList::Ptr& result) const;
|
||||
void ExtractFiltered(const std::set<String, string_iless>& keys, const ExpressionList::Ptr& result) const;
|
||||
|
||||
void ErasePath(const std::vector<String>& path);
|
||||
|
||||
void FindDebugInfoPath(const std::vector<String>& path, DebugInfo& result) const;
|
||||
|
||||
private:
|
||||
std::vector<Expression> m_Expressions;
|
||||
};
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_SCRIPTFUNCTION(ValidateServiceDictionary, &Host::ValidateServiceDictionary);
|
||||
|
||||
REGISTER_TYPE(Host);
|
||||
|
||||
void Host::Start(void)
|
||||
|
@ -197,7 +195,17 @@ void Host::UpdateSlaveServices(void)
|
|||
namebuf << GetName() << ":" << svcname;
|
||||
String name = namebuf.str();
|
||||
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(item->GetDebugInfo());
|
||||
std::vector<String> path;
|
||||
path.push_back("services");
|
||||
path.push_back(svcname);
|
||||
|
||||
DebugInfo di;
|
||||
item->GetLinkedExpressionList()->FindDebugInfoPath(path, di);
|
||||
|
||||
if (di.Path.IsEmpty())
|
||||
di = item->GetDebugInfo();
|
||||
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Service");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host_name", OperatorSet, GetName());
|
||||
|
@ -238,12 +246,13 @@ void Host::UpdateSlaveServices(void)
|
|||
builder->AddExpressionList(host_exprl);
|
||||
|
||||
/* Clone attributes from the service expression list. */
|
||||
std::vector<String> path;
|
||||
path.push_back("services");
|
||||
path.push_back(svcname);
|
||||
|
||||
ExpressionList::Ptr svc_exprl = boost::make_shared<ExpressionList>();
|
||||
item->GetLinkedExpressionList()->ExtractPath(path, svc_exprl);
|
||||
|
||||
std::vector<String> dpath;
|
||||
dpath.push_back("templates");
|
||||
svc_exprl->ErasePath(dpath);
|
||||
|
||||
builder->AddExpressionList(svc_exprl);
|
||||
|
||||
ConfigItem::Ptr serviceItem = builder->Compile();
|
||||
|
@ -290,42 +299,6 @@ int Host::GetTotalServices(void) const
|
|||
return GetServices().size();
|
||||
}
|
||||
|
||||
Value Host::ValidateServiceDictionary(const String& location, const Dictionary::Ptr& attrs)
|
||||
{
|
||||
ObjectLock olock(attrs);
|
||||
|
||||
String key;
|
||||
Value value;
|
||||
BOOST_FOREACH(boost::tie(key, value), attrs) {
|
||||
std::vector<String> templates;
|
||||
|
||||
if (!value.IsObjectType<Dictionary>())
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Service description must be a dictionary."));
|
||||
|
||||
Dictionary::Ptr serviceDesc = value;
|
||||
|
||||
Array::Ptr templatesArray = serviceDesc->Get("templates");
|
||||
|
||||
if (templatesArray) {
|
||||
ObjectLock tlock(templatesArray);
|
||||
|
||||
BOOST_FOREACH(const Value& tmpl, templatesArray) {
|
||||
templates.push_back(tmpl);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const String& name, templates) {
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject("Service", name);
|
||||
|
||||
if (!item)
|
||||
ConfigCompilerContext::GetInstance()->AddError(false, "Validation failed for " +
|
||||
location + ": Template '" + name + "' not found.");
|
||||
}
|
||||
}
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
||||
Service::Ptr Host::GetServiceByShortName(const Value& name) const
|
||||
{
|
||||
if (name.IsScalar()) {
|
||||
|
|
|
@ -104,8 +104,6 @@ public:
|
|||
|
||||
int GetTotalServices(void) const;
|
||||
|
||||
static Value ValidateServiceDictionary(const String& location, const Dictionary::Ptr& attrs);
|
||||
|
||||
static HostState CalculateState(ServiceState state, bool reachable);
|
||||
|
||||
HostState GetState(void) const;
|
||||
|
|
|
@ -36,14 +36,12 @@ type Host {
|
|||
}
|
||||
},
|
||||
%attribute dictionary "services" {
|
||||
%validator "ValidateServiceDictionary",
|
||||
|
||||
%attribute dictionary "*" {
|
||||
%attribute array "templates" {
|
||||
%attribute name(Service) "*"
|
||||
},
|
||||
|
||||
%attribute string "short_name",
|
||||
/* %attribute string "short_name",
|
||||
%attribute string "display_name",
|
||||
|
||||
%attribute dictionary "macros" {
|
||||
|
@ -112,11 +110,11 @@ type Host {
|
|||
%attribute number "notification_state_filter",
|
||||
%attribute name(TimePeriod) "notification_period"
|
||||
}
|
||||
},
|
||||
},*/
|
||||
}
|
||||
},
|
||||
|
||||
%attribute dictionary "notifications" {
|
||||
/* %attribute dictionary "notifications" {
|
||||
%attribute dictionary "*" {
|
||||
%attribute array "templates" {
|
||||
%attribute name(Notification) "*"
|
||||
|
@ -142,7 +140,7 @@ type Host {
|
|||
%attribute number "notification_state_filter",
|
||||
%attribute name(TimePeriod) "notification_period"
|
||||
}
|
||||
},
|
||||
},*/
|
||||
|
||||
/* service attributes */
|
||||
%attribute number "max_check_attempts",
|
||||
|
@ -244,7 +242,7 @@ type Service {
|
|||
%attribute name(Notification) "*"
|
||||
},
|
||||
|
||||
%attribute dictionary "macros" {
|
||||
/* %attribute dictionary "macros" {
|
||||
%attribute string "*"
|
||||
},
|
||||
|
||||
|
@ -262,7 +260,7 @@ type Service {
|
|||
|
||||
%attribute number "notification_type_filter",
|
||||
%attribute number "notification_state_filter",
|
||||
%attribute name(TimePeriod) "notification_period"
|
||||
%attribute name(TimePeriod) "notification_period"*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,17 @@ void Service::UpdateSlaveNotifications(void)
|
|||
namebuf << GetName() << ":" << nfcname;
|
||||
String name = namebuf.str();
|
||||
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(item->GetDebugInfo());
|
||||
std::vector<String> path;
|
||||
path.push_back("notifications");
|
||||
path.push_back(nfcname);
|
||||
|
||||
DebugInfo di;
|
||||
item->GetLinkedExpressionList()->FindDebugInfoPath(path, di);
|
||||
|
||||
if (di.Path.IsEmpty())
|
||||
di = item->GetDebugInfo();
|
||||
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("Notification");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host_name", OperatorSet, host->GetName());
|
||||
|
@ -183,12 +193,13 @@ void Service::UpdateSlaveNotifications(void)
|
|||
builder->AddExpressionList(svc_exprl);
|
||||
|
||||
/* Clone attributes from the notification expression list. */
|
||||
std::vector<String> path;
|
||||
path.push_back("notifications");
|
||||
path.push_back(nfcname);
|
||||
|
||||
ExpressionList::Ptr nfc_exprl = boost::make_shared<ExpressionList>();
|
||||
item->GetLinkedExpressionList()->ExtractPath(path, nfc_exprl);
|
||||
|
||||
std::vector<String> dpath;
|
||||
dpath.push_back("templates");
|
||||
nfc_exprl->ErasePath(dpath);
|
||||
|
||||
builder->AddExpressionList(nfc_exprl);
|
||||
|
||||
ConfigItem::Ptr notificationItem = builder->Compile();
|
||||
|
|
Loading…
Reference in New Issue