mirror of
https://github.com/Icinga/icinga2.git
synced 2025-04-08 17:05:25 +02:00
parent
00652f603c
commit
3dc2f82345
@ -175,13 +175,6 @@ int RepositoryObjectCommand::Run(const boost::program_options::variables_map& vm
|
|||||||
|
|
||||||
String name = attrs->Get("name");
|
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")) {
|
if (vm.count("import")) {
|
||||||
Array::Ptr imports = make_shared<Array>();
|
Array::Ptr imports = make_shared<Array>();
|
||||||
|
|
||||||
@ -196,13 +189,12 @@ int RepositoryObjectCommand::Run(const boost::program_options::variables_map& vm
|
|||||||
|
|
||||||
|
|
||||||
if (m_Command == RepositoryCommandAdd) {
|
if (m_Command == RepositoryCommandAdd) {
|
||||||
|
Utility::LoadExtensionLibrary("icinga");
|
||||||
RepositoryUtility::AddObject(name, m_Type, attrs);
|
RepositoryUtility::AddObject(name, m_Type, attrs);
|
||||||
}
|
} else if (m_Command == RepositoryCommandRemove) {
|
||||||
else if (m_Command == RepositoryCommandRemove) {
|
|
||||||
/* pass attrs for service->host_name requirement */
|
/* pass attrs for service->host_name requirement */
|
||||||
RepositoryUtility::RemoveObject(name, m_Type, attrs);
|
RepositoryUtility::RemoveObject(name, m_Type, attrs);
|
||||||
}
|
} else if (m_Command == RepositoryCommandSet) {
|
||||||
else if (m_Command == RepositoryCommandSet) {
|
|
||||||
Log(LogWarning, "cli")
|
Log(LogWarning, "cli")
|
||||||
<< "Not supported yet. Please check the roadmap at https://dev.icinga.org\n";
|
<< "Not supported yet. Please check the roadmap at https://dev.icinga.org\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -19,6 +19,9 @@
|
|||||||
|
|
||||||
#include "cli/repositoryutility.hpp"
|
#include "cli/repositoryutility.hpp"
|
||||||
#include "cli/clicommand.hpp"
|
#include "cli/clicommand.hpp"
|
||||||
|
#include "config/configtype.hpp"
|
||||||
|
#include "config/configcompilercontext.hpp"
|
||||||
|
#include "config/configcompiler.hpp"
|
||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/application.hpp"
|
#include "base/application.hpp"
|
||||||
#include "base/convert.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 */
|
/* modify objects and write changelog */
|
||||||
bool RepositoryUtility::AddObject(const String& name, const String& type, const Dictionary::Ptr& attrs)
|
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("command", "add");
|
||||||
change->Set("attrs", attrs);
|
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 WriteObjectToRepositoryChangeLog(path, change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,8 +270,10 @@ void ConfigItem::ValidateItem(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeRuleUtilities utils;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ctype->ValidateItem(GetSelf());
|
ctype->ValidateItem(GetName(), GetProperties(), GetDebugInfo(), &utils);
|
||||||
} catch (const ConfigError& ex) {
|
} catch (const ConfigError& ex) {
|
||||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
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. */
|
String location = "Object '" + name + "' (Type: '" + GetName() + "')";
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!debugInfo.Path.IsEmpty())
|
||||||
|
location += " at " + debugInfo.Path + ":" + Convert::ToString(debugInfo.FirstLine);
|
||||||
|
|
||||||
std::vector<String> locations;
|
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;
|
std::vector<TypeRuleList::Ptr> ruleLists;
|
||||||
AddParentRules(ruleLists, GetSelf());
|
AddParentRules(ruleLists, GetSelf());
|
||||||
ruleLists.push_back(m_RuleList);
|
ruleLists.push_back(m_RuleList);
|
||||||
|
|
||||||
ValidateDictionary(attrs, ruleLists, locations);
|
ValidateDictionary(attrs, ruleLists, locations, utils);
|
||||||
}
|
}
|
||||||
|
|
||||||
String ConfigType::LocationToString(const std::vector<String>& locations)
|
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,
|
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 TypeRuleList::Ptr& ruleList, ruleLists) {
|
||||||
BOOST_FOREACH(const String& require, ruleList->GetRequires()) {
|
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) {
|
BOOST_FOREACH(const TypeRuleList::Ptr& ruleList, ruleLists) {
|
||||||
TypeRuleList::Ptr subRuleList;
|
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)
|
if (subRuleList)
|
||||||
subRuleLists.push_back(subRuleList);
|
subRuleLists.push_back(subRuleList);
|
||||||
@ -192,16 +181,17 @@ void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!subRuleLists.empty() && kv.second.IsObjectType<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>())
|
else if (!subRuleLists.empty() && kv.second.IsObjectType<Array>())
|
||||||
ValidateArray(kv.second, subRuleLists, locations);
|
ValidateArray(kv.second, subRuleLists, locations, utils);
|
||||||
|
|
||||||
locations.pop_back();
|
locations.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigType::ValidateArray(const Array::Ptr& array,
|
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 TypeRuleList::Ptr& ruleList, ruleLists) {
|
||||||
BOOST_FOREACH(const String& require, ruleList->GetRequires()) {
|
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) {
|
BOOST_FOREACH(const TypeRuleList::Ptr& ruleList, ruleLists) {
|
||||||
TypeRuleList::Ptr subRuleList;
|
TypeRuleList::Ptr subRuleList;
|
||||||
TypeValidationResult result = ruleList->ValidateAttribute(key, value, &subRuleList, &hint);
|
TypeValidationResult result = ruleList->ValidateAttribute(key, value, &subRuleList, &hint, utils);
|
||||||
|
|
||||||
if (subRuleList)
|
if (subRuleList)
|
||||||
subRuleLists.push_back(subRuleList);
|
subRuleLists.push_back(subRuleList);
|
||||||
@ -267,7 +257,7 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (overallResult == ValidationUnknownField)
|
if (overallResult == ValidationUnknownField)
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(false, "Unknown attribute: " + LocationToString(locations));
|
ConfigCompilerContext::GetInstance()->AddMessage(true, "Unknown attribute: " + LocationToString(locations));
|
||||||
else if (overallResult == ValidationInvalidType) {
|
else if (overallResult == ValidationInvalidType) {
|
||||||
String message = "Invalid value for array index: " + LocationToString(locations);
|
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>())
|
if (!subRuleLists.empty() && value.IsObjectType<Dictionary>())
|
||||||
ValidateDictionary(value, subRuleLists, locations);
|
ValidateDictionary(value, subRuleLists, locations, utils);
|
||||||
else if (!subRuleLists.empty() && value.IsObjectType<Array>())
|
else if (!subRuleLists.empty() && value.IsObjectType<Array>())
|
||||||
ValidateArray(value, subRuleLists, locations);
|
ValidateArray(value, subRuleLists, locations, utils);
|
||||||
|
|
||||||
locations.pop_back();
|
locations.pop_back();
|
||||||
}
|
}
|
||||||
@ -310,4 +300,3 @@ ConfigTypeRegistry *ConfigTypeRegistry::GetInstance(void)
|
|||||||
{
|
{
|
||||||
return Singleton<ConfigTypeRegistry>::GetInstance();
|
return Singleton<ConfigTypeRegistry>::GetInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,8 @@ public:
|
|||||||
|
|
||||||
DebugInfo GetDebugInfo(void) const;
|
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);
|
void Register(void);
|
||||||
static ConfigType::Ptr GetByName(const String& name);
|
static ConfigType::Ptr GetByName(const String& name);
|
||||||
@ -65,9 +66,11 @@ private:
|
|||||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||||
|
|
||||||
static void ValidateDictionary(const Dictionary::Ptr& dictionary,
|
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,
|
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);
|
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));
|
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;
|
ConfigItem::Ptr item;
|
||||||
|
|
||||||
@ -77,21 +77,26 @@ bool TypeRule::MatchValue(const Value& value, String *hint) const
|
|||||||
if (!value.IsScalar())
|
if (!value.IsScalar())
|
||||||
return false;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item->IsAbstract()) {
|
|
||||||
*hint = "Object '" + value + "' of type '" + m_NameType + "' must not be a template.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
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
|
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.
|
* The allowed type for a type rule.
|
||||||
*
|
*
|
||||||
@ -58,7 +69,7 @@ public:
|
|||||||
TypeRuleList::Ptr GetSubRules(void) const;
|
TypeRuleList::Ptr GetSubRules(void) const;
|
||||||
|
|
||||||
bool MatchName(const String& name) 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:
|
private:
|
||||||
TypeSpecifier m_Type;
|
TypeSpecifier m_Type;
|
||||||
|
@ -117,7 +117,8 @@ size_t TypeRuleList::GetLength(void) const
|
|||||||
* @returns The validation result.
|
* @returns The validation result.
|
||||||
*/
|
*/
|
||||||
TypeValidationResult TypeRuleList::ValidateAttribute(const String& name,
|
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;
|
bool foundField = false;
|
||||||
BOOST_FOREACH(const TypeRule& rule, m_Rules) {
|
BOOST_FOREACH(const TypeRule& rule, m_Rules) {
|
||||||
@ -126,7 +127,7 @@ TypeValidationResult TypeRuleList::ValidateAttribute(const String& name,
|
|||||||
|
|
||||||
foundField = true;
|
foundField = true;
|
||||||
|
|
||||||
if (rule.MatchValue(value, hint)) {
|
if (rule.MatchValue(value, hint, utils)) {
|
||||||
*subRules = rule.GetSubRules();
|
*subRules = rule.GetSubRules();
|
||||||
return ValidationOK;
|
return ValidationOK;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ namespace icinga
|
|||||||
{
|
{
|
||||||
|
|
||||||
struct TypeRule;
|
struct TypeRule;
|
||||||
|
class TypeRuleUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup config
|
* @ingroup config
|
||||||
@ -59,7 +60,8 @@ public:
|
|||||||
void AddRule(const TypeRule& rule);
|
void AddRule(const TypeRule& rule);
|
||||||
void AddRules(const TypeRuleList::Ptr& ruleList);
|
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;
|
size_t GetLength(void) const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user