String name = attrs->Get("name");
- if (m_Type == "Service") {
- if (!attrs->Contains("host_name")) {
- Log(LogCritical, "cli", "Service objects require the 'host_name' attribute.");
- return 1;
- }
- }
-
if (vm.count("import")) {
Array::Ptr imports = make_shared<Array>();
if (m_Command == RepositoryCommandAdd) {
+ Utility::LoadExtensionLibrary("icinga");
RepositoryUtility::AddObject(name, m_Type, attrs);
- }
- else if (m_Command == RepositoryCommandRemove) {
+ } else if (m_Command == RepositoryCommandRemove) {
/* pass attrs for service->host_name requirement */
RepositoryUtility::RemoveObject(name, m_Type, attrs);
- }
- else if (m_Command == RepositoryCommandSet) {
+ } else if (m_Command == RepositoryCommandSet) {
Log(LogWarning, "cli")
<< "Not supported yet. Please check the roadmap at https://dev.icinga.org\n";
return 1;
#include "cli/repositoryutility.hpp"
#include "cli/clicommand.hpp"
+#include "config/configtype.hpp"
+#include "config/configcompilercontext.hpp"
+#include "config/configcompiler.hpp"
#include "base/logger.hpp"
#include "base/application.hpp"
#include "base/convert.hpp"
}
}
+class RepositoryTypeRuleUtilities : public TypeRuleUtilities
+{
+public:
+ virtual bool ValidateName(const String& type, const String& name, String *hint) const
+ {
+ return true;
+ }
+};
+
/* modify objects and write changelog */
bool RepositoryUtility::AddObject(const String& name, const String& type, const Dictionary::Ptr& attrs)
{
change->Set("command", "add");
change->Set("attrs", attrs);
+ ConfigCompilerContext::GetInstance()->Reset();
+
+ String fname, fragment;
+ BOOST_FOREACH(boost::tie(fname, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) {
+ ConfigCompiler::CompileText(fname, fragment);
+ }
+
+ ConfigType::Ptr ctype = ConfigType::GetByName(type);
+
+ if (!ctype)
+ Log(LogCritical, "cli")
+ << "No validation type available for '" << type << "'.";
+ else {
+ Dictionary::Ptr vattrs = attrs->ShallowClone();
+ vattrs->Set("__name", vattrs->Get("name"));
+ vattrs->Remove("name");
+ vattrs->Set("type", type);
+
+ RepositoryTypeRuleUtilities utils;
+ ctype->ValidateItem(name, vattrs, DebugInfo(), &utils);
+
+ int warnings = 0, errors = 0;
+
+ BOOST_FOREACH(const ConfigCompilerMessage& message, ConfigCompilerContext::GetInstance()->GetMessages()) {
+ String logmsg = String("Config ") + (message.Error ? "error" : "warning") + ": " + message.Text;
+
+ if (message.Error) {
+ Log(LogCritical, "config", logmsg);
+ errors++;
+ } else {
+ Log(LogWarning, "config", logmsg);
+ warnings++;
+ }
+ }
+
+ if (errors > 0)
+ return false;
+ }
+
return WriteObjectToRepositoryChangeLog(path, change);
}
return;
}
+ TypeRuleUtilities utils;
+
try {
- ctype->ValidateItem(GetSelf());
+ ctype->ValidateItem(GetName(), GetProperties(), GetDebugInfo(), &utils);
} catch (const ConfigError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
}
}
-void ConfigType::ValidateItem(const ConfigItem::Ptr& item)
+void ConfigType::ValidateItem(const String& name, const Dictionary::Ptr& attrs, const DebugInfo& debugInfo, const TypeRuleUtilities *utils)
{
- /* Don't validate abstract items. */
- if (item->IsAbstract())
- return;
-
- Dictionary::Ptr attrs;
- DebugInfo debugInfo;
- String type, name;
-
- {
- ObjectLock olock(item);
-
- attrs = item->GetProperties();
- debugInfo = item->GetDebugInfo();
- type = item->GetType();
- name = item->GetName();
- }
+ String location = "Object '" + name + "' (Type: '" + GetName() + "')";
+ if (!debugInfo.Path.IsEmpty())
+ location += " at " + debugInfo.Path + ":" + Convert::ToString(debugInfo.FirstLine);
+
std::vector<String> locations;
- locations.push_back("Object '" + name + "' (Type: '" + type + "') at " + debugInfo.Path + ":" + Convert::ToString(debugInfo.FirstLine));
+ locations.push_back(location);
std::vector<TypeRuleList::Ptr> ruleLists;
AddParentRules(ruleLists, GetSelf());
ruleLists.push_back(m_RuleList);
- ValidateDictionary(attrs, ruleLists, locations);
+ ValidateDictionary(attrs, ruleLists, locations, utils);
}
String ConfigType::LocationToString(const std::vector<String>& locations)
}
void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary,
- const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations)
+ const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations,
+ const TypeRuleUtilities *utils)
{
BOOST_FOREACH(const TypeRuleList::Ptr& ruleList, ruleLists) {
BOOST_FOREACH(const String& require, ruleList->GetRequires()) {
BOOST_FOREACH(const TypeRuleList::Ptr& ruleList, ruleLists) {
TypeRuleList::Ptr subRuleList;
- TypeValidationResult result = ruleList->ValidateAttribute(kv.first, kv.second, &subRuleList, &hint);
+ TypeValidationResult result = ruleList->ValidateAttribute(kv.first, kv.second, &subRuleList, &hint, utils);
if (subRuleList)
subRuleLists.push_back(subRuleList);
}
if (!subRuleLists.empty() && kv.second.IsObjectType<Dictionary>())
- ValidateDictionary(kv.second, subRuleLists, locations);
+ ValidateDictionary(kv.second, subRuleLists, locations, utils);
else if (!subRuleLists.empty() && kv.second.IsObjectType<Array>())
- ValidateArray(kv.second, subRuleLists, locations);
+ ValidateArray(kv.second, subRuleLists, locations, utils);
locations.pop_back();
}
}
void ConfigType::ValidateArray(const Array::Ptr& array,
- const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations)
+ const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations,
+ const TypeRuleUtilities *utils)
{
BOOST_FOREACH(const TypeRuleList::Ptr& ruleList, ruleLists) {
BOOST_FOREACH(const String& require, ruleList->GetRequires()) {
BOOST_FOREACH(const TypeRuleList::Ptr& ruleList, ruleLists) {
TypeRuleList::Ptr subRuleList;
- TypeValidationResult result = ruleList->ValidateAttribute(key, value, &subRuleList, &hint);
+ TypeValidationResult result = ruleList->ValidateAttribute(key, value, &subRuleList, &hint, utils);
if (subRuleList)
subRuleLists.push_back(subRuleList);
}
if (overallResult == ValidationUnknownField)
- ConfigCompilerContext::GetInstance()->AddMessage(false, "Unknown attribute: " + LocationToString(locations));
+ ConfigCompilerContext::GetInstance()->AddMessage(true, "Unknown attribute: " + LocationToString(locations));
else if (overallResult == ValidationInvalidType) {
String message = "Invalid value for array index: " + LocationToString(locations);
}
if (!subRuleLists.empty() && value.IsObjectType<Dictionary>())
- ValidateDictionary(value, subRuleLists, locations);
+ ValidateDictionary(value, subRuleLists, locations, utils);
else if (!subRuleLists.empty() && value.IsObjectType<Array>())
- ValidateArray(value, subRuleLists, locations);
+ ValidateArray(value, subRuleLists, locations, utils);
locations.pop_back();
}
{
return Singleton<ConfigTypeRegistry>::GetInstance();
}
-
\r
DebugInfo GetDebugInfo(void) const;\r
\r
- void ValidateItem(const ConfigItem::Ptr& object);\r
+ void ValidateItem(const String& name, const Dictionary::Ptr& attrs,\r
+ const DebugInfo& debugInfo, const TypeRuleUtilities *utils);\r
\r
void Register(void);\r
static ConfigType::Ptr GetByName(const String& name);\r
DebugInfo m_DebugInfo; /**< Debug information. */\r
\r
static void ValidateDictionary(const Dictionary::Ptr& dictionary,\r
- const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations);\r
+ const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations,\r
+ const TypeRuleUtilities *utils);\r
static void ValidateArray(const Array::Ptr& array,\r
- const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations);\r
+ const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations,\r
+ const TypeRuleUtilities *utils);\r
\r
static String LocationToString(const std::vector<String>& locations);\r
\r
return (Utility::Match(m_NamePattern, name));
}
-bool TypeRule::MatchValue(const Value& value, String *hint) const
+bool TypeRule::MatchValue(const Value& value, String *hint, const TypeRuleUtilities *utils) const
{
ConfigItem::Ptr item;
if (!value.IsScalar())
return false;
- item = ConfigItem::GetObject(m_NameType, value);
+ return utils->ValidateName(m_NameType, value, hint);
- if (!item) {
- *hint = "Object '" + value + "' of type '" + m_NameType + "' does not exist.";
- return false;
- }
+ default:
+ return false;
+ }
+}
- if (item->IsAbstract()) {
- *hint = "Object '" + value + "' of type '" + m_NameType + "' must not be a template.";
- return false;
- }
+bool TypeRuleUtilities::ValidateName(const String& type, const String& name, String *hint) const
+{
+ ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
- return true;
+ if (!item) {
+ *hint = "Object '" + name + "' of type '" + type + "' does not exist.";
+ return false;
+ }
- default:
- return false;
+ if (item->IsAbstract()) {
+ *hint = "Object '" + name + "' of type '" + type + "' must not be a template.";
+ return false;
}
+
+ return true;
}
namespace icinga\r
{\r
\r
+/**\r
+ * Utilities for type rules.\r
+ *\r
+ * @ingroup config\r
+ */\r
+class TypeRuleUtilities\r
+{\r
+public:\r
+ virtual bool ValidateName(const String& type, const String& name, String *hint) const;\r
+};\r
+\r
/**\r
* The allowed type for a type rule.\r
*\r
TypeRuleList::Ptr GetSubRules(void) const;\r
\r
bool MatchName(const String& name) const;\r
- bool MatchValue(const Value& value, String *hint) const;\r
+ bool MatchValue(const Value& value, String *hint, const TypeRuleUtilities *utils) const;\r
\r
private:\r
TypeSpecifier m_Type;\r
* @returns The validation result.\r
*/\r
TypeValidationResult TypeRuleList::ValidateAttribute(const String& name,\r
- const Value& value, TypeRuleList::Ptr *subRules, String *hint) const\r
+ const Value& value, TypeRuleList::Ptr *subRules, String *hint,\r
+ const TypeRuleUtilities *utils) const\r
{\r
bool foundField = false;\r
BOOST_FOREACH(const TypeRule& rule, m_Rules) {\r
\r
foundField = true;\r
\r
- if (rule.MatchValue(value, hint)) {\r
+ if (rule.MatchValue(value, hint, utils)) {\r
*subRules = rule.GetSubRules();\r
return ValidationOK;\r
}\r
{\r
\r
struct TypeRule;\r
+class TypeRuleUtilities;\r
\r
/**\r
* @ingroup config\r
void AddRule(const TypeRule& rule);\r
void AddRules(const TypeRuleList::Ptr& ruleList);\r
\r
- TypeValidationResult ValidateAttribute(const String& name, const Value& value, TypeRuleList::Ptr *subRules, String *hint) const;\r
+ TypeValidationResult ValidateAttribute(const String& name, const Value& value,\r
+ TypeRuleList::Ptr *subRules, String *hint, const TypeRuleUtilities *utils) const;\r
\r
size_t GetLength(void) const;\r
\r