mirror of https://github.com/Icinga/icinga2.git
parent
00652f603c
commit
3dc2f82345
|
@ -175,13 +175,6 @@ int RepositoryObjectCommand::Run(const boost::program_options::variables_map& vm
|
|||
|
||||
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>();
|
||||
|
||||
|
@ -196,13 +189,12 @@ int RepositoryObjectCommand::Run(const boost::program_options::variables_map& vm
|
|||
|
||||
|
||||
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;
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
#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"
|
||||
|
@ -177,6 +180,15 @@ void RepositoryUtility::PrintChangeLog(std::ostream& fp)
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -191,6 +203,45 @@ bool RepositoryUtility::AddObject(const String& name, const String& type, const
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -270,8 +270,10 @@ void ConfigItem::ValidateItem(void)
|
|||
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());
|
||||
|
|
|
@ -74,33 +74,21 @@ void ConfigType::AddParentRules(std::vector<TypeRuleList::Ptr>& ruleLists, const
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -120,7 +108,8 @@ 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()) {
|
||||
|
@ -163,7 +152,7 @@ void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary,
|
|||
|
||||
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);
|
||||
|
@ -192,16 +181,17 @@ void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary,
|
|||
}
|
||||
|
||||
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()) {
|
||||
|
@ -249,7 +239,7 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
|
|||
|
||||
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);
|
||||
|
@ -267,7 +257,7 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -278,9 +268,9 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
|
|||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -310,4 +300,3 @@ ConfigTypeRegistry *ConfigTypeRegistry::GetInstance(void)
|
|||
{
|
||||
return Singleton<ConfigTypeRegistry>::GetInstance();
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,8 @@ public:
|
|||
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
|
||||
void ValidateItem(const ConfigItem::Ptr& object);
|
||||
void ValidateItem(const String& name, const Dictionary::Ptr& attrs,
|
||||
const DebugInfo& debugInfo, const TypeRuleUtilities *utils);
|
||||
|
||||
void Register(void);
|
||||
static ConfigType::Ptr GetByName(const String& name);
|
||||
|
@ -65,9 +66,11 @@ private:
|
|||
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||
|
||||
static void 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);
|
||||
static void 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);
|
||||
|
||||
static String LocationToString(const std::vector<String>& locations);
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ bool TypeRule::MatchName(const String& name) const
|
|||
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;
|
||||
|
||||
|
@ -77,21 +77,26 @@ bool TypeRule::MatchValue(const Value& value, String *hint) const
|
|||
if (!value.IsScalar())
|
||||
return false;
|
||||
|
||||
item = ConfigItem::GetObject(m_NameType, value);
|
||||
|
||||
if (!item) {
|
||||
*hint = "Object '" + value + "' of type '" + m_NameType + "' does not exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item->IsAbstract()) {
|
||||
*hint = "Object '" + value + "' of type '" + m_NameType + "' must not be a template.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return utils->ValidateName(m_NameType, value, hint);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool TypeRuleUtilities::ValidateName(const String& type, const String& name, String *hint) const
|
||||
{
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
|
||||
|
||||
if (!item) {
|
||||
*hint = "Object '" + name + "' of type '" + type + "' does not exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item->IsAbstract()) {
|
||||
*hint = "Object '" + name + "' of type '" + type + "' must not be a template.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,17 @@
|
|||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* Utilities for type rules.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
class TypeRuleUtilities
|
||||
{
|
||||
public:
|
||||
virtual bool ValidateName(const String& type, const String& name, String *hint) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* The allowed type for a type rule.
|
||||
*
|
||||
|
@ -58,7 +69,7 @@ public:
|
|||
TypeRuleList::Ptr GetSubRules(void) const;
|
||||
|
||||
bool MatchName(const String& name) const;
|
||||
bool MatchValue(const Value& value, String *hint) const;
|
||||
bool MatchValue(const Value& value, String *hint, const TypeRuleUtilities *utils) const;
|
||||
|
||||
private:
|
||||
TypeSpecifier m_Type;
|
||||
|
|
|
@ -117,7 +117,8 @@ size_t TypeRuleList::GetLength(void) const
|
|||
* @returns The validation result.
|
||||
*/
|
||||
TypeValidationResult TypeRuleList::ValidateAttribute(const String& name,
|
||||
const Value& value, TypeRuleList::Ptr *subRules, String *hint) const
|
||||
const Value& value, TypeRuleList::Ptr *subRules, String *hint,
|
||||
const TypeRuleUtilities *utils) const
|
||||
{
|
||||
bool foundField = false;
|
||||
BOOST_FOREACH(const TypeRule& rule, m_Rules) {
|
||||
|
@ -126,7 +127,7 @@ TypeValidationResult TypeRuleList::ValidateAttribute(const String& name,
|
|||
|
||||
foundField = true;
|
||||
|
||||
if (rule.MatchValue(value, hint)) {
|
||||
if (rule.MatchValue(value, hint, utils)) {
|
||||
*subRules = rule.GetSubRules();
|
||||
return ValidationOK;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace icinga
|
|||
{
|
||||
|
||||
struct TypeRule;
|
||||
class TypeRuleUtilities;
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
|
@ -59,7 +60,8 @@ public:
|
|||
void AddRule(const TypeRule& rule);
|
||||
void AddRules(const TypeRuleList::Ptr& ruleList);
|
||||
|
||||
TypeValidationResult ValidateAttribute(const String& name, const Value& value, TypeRuleList::Ptr *subRules, String *hint) const;
|
||||
TypeValidationResult ValidateAttribute(const String& name, const Value& value,
|
||||
TypeRuleList::Ptr *subRules, String *hint, const TypeRuleUtilities *utils) const;
|
||||
|
||||
size_t GetLength(void) const;
|
||||
|
||||
|
|
Loading…
Reference in New Issue