Allow using more than one %validator rule for the same type

fixes #8829
This commit is contained in:
Gunnar Beutner 2015-03-20 15:49:55 +01:00
parent ae204092cc
commit e8cee8d5e2
5 changed files with 224 additions and 228 deletions

View File

@ -372,9 +372,9 @@ type: T_TYPE identifier
context->m_Type->GetRuleList()->AddRules(ruleList); context->m_Type->GetRuleList()->AddRules(ruleList);
context->m_Type->GetRuleList()->AddRequires(ruleList); context->m_Type->GetRuleList()->AddRequires(ruleList);
String validator = ruleList->GetValidator(); BOOST_FOREACH(const String& validator, ruleList->GetValidators()) {
if (!validator.IsEmpty()) context->m_Type->GetRuleList()->AddValidator(validator);
context->m_Type->GetRuleList()->SetValidator(validator); }
} }
; ;
@ -407,7 +407,7 @@ typerule: T_REQUIRE T_STRING
} }
| T_VALIDATOR T_STRING | T_VALIDATOR T_STRING
{ {
context->m_RuleLists.top()->SetValidator($2); context->m_RuleLists.top()->AddValidator($2);
free($2); free($2);
} }
| T_ATTRIBUTE type T_STRING | T_ATTRIBUTE type T_STRING

View File

@ -169,9 +169,7 @@ void ConfigType::ValidateObject(const Object::Ptr& object,
locations.pop_back(); locations.pop_back();
} }
String validator = ruleList->GetValidator(); BOOST_FOREACH(const String& validator, ruleList->GetValidators()) {
if (!validator.IsEmpty()) {
Function::Ptr func = ScriptGlobal::Get(validator, &Empty); Function::Ptr func = ScriptGlobal::Get(validator, &Empty);
if (!func) if (!func)
@ -226,9 +224,7 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
locations.pop_back(); locations.pop_back();
} }
String validator = ruleList->GetValidator(); BOOST_FOREACH(const String& validator, ruleList->GetValidators()) {
if (!validator.IsEmpty()) {
Function::Ptr func = ScriptGlobal::Get(validator, &Empty); Function::Ptr func = ScriptGlobal::Get(validator, &Empty);
if (!func) if (!func)

View File

@ -1,140 +1,140 @@
/****************************************************************************** /******************************************************************************
* Icinga 2 * * Icinga 2 *
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) * * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License * * modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 * * as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. * * of the License, or (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include "config/typerulelist.hpp" #include "config/typerulelist.hpp"
#include "config/typerule.hpp" #include "config/typerule.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
using namespace icinga; using namespace icinga;
/** /**
* Sets the validator method for a rule list. * Adds a validator method for a rule list.
* *
* @param validator The validator. * @param validator The validator.
*/ */
void TypeRuleList::SetValidator(const String& validator) void TypeRuleList::AddValidator(const String& validator)
{ {
m_Validator = validator; m_Validators.push_back(validator);
} }
/** /**
* Retrieves the validator method. * Retrieves the validator methods.
* *
* @returns The validator method. * @returns The validator methods.
*/ */
String TypeRuleList::GetValidator(void) const std::vector<String> TypeRuleList::GetValidators(void) const
{ {
return m_Validator; return m_Validators;
} }
/** /**
* Adds an attribute to the list of required attributes. * Adds an attribute to the list of required attributes.
* *
* @param attr The new required attribute. * @param attr The new required attribute.
*/ */
void TypeRuleList::AddRequire(const String& attr) void TypeRuleList::AddRequire(const String& attr)
{ {
m_Requires.push_back(attr); m_Requires.push_back(attr);
} }
/** /**
* Retrieves the list of required attributes. * Retrieves the list of required attributes.
* *
* @returns The list of required attributes. * @returns The list of required attributes.
*/ */
std::vector<String> TypeRuleList::GetRequires(void) const std::vector<String> TypeRuleList::GetRequires(void) const
{ {
return m_Requires; return m_Requires;
} }
/** /**
* Adds all requires from the specified rule list. * Adds all requires from the specified rule list.
* *
* @param ruleList The rule list to copy requires from. * @param ruleList The rule list to copy requires from.
*/ */
void TypeRuleList::AddRequires(const TypeRuleList::Ptr& ruleList) void TypeRuleList::AddRequires(const TypeRuleList::Ptr& ruleList)
{ {
BOOST_FOREACH(const String& require, ruleList->m_Requires) { BOOST_FOREACH(const String& require, ruleList->m_Requires) {
AddRequire(require); AddRequire(require);
} }
} }
/** /**
* Adds a rule to a rule list. * Adds a rule to a rule list.
* *
* @param rule The rule that should be added. * @param rule The rule that should be added.
*/ */
void TypeRuleList::AddRule(const TypeRule& rule) void TypeRuleList::AddRule(const TypeRule& rule)
{ {
m_Rules.push_back(rule); m_Rules.push_back(rule);
} }
/** /**
* Adds all rules from the specified rule list. * Adds all rules from the specified rule list.
* *
* @param ruleList The rule list to copy rules from. * @param ruleList The rule list to copy rules from.
*/ */
void TypeRuleList::AddRules(const TypeRuleList::Ptr& ruleList) void TypeRuleList::AddRules(const TypeRuleList::Ptr& ruleList)
{ {
BOOST_FOREACH(const TypeRule& rule, ruleList->m_Rules) { BOOST_FOREACH(const TypeRule& rule, ruleList->m_Rules) {
AddRule(rule); AddRule(rule);
} }
} }
/** /**
* Returns the number of rules currently contained in the list. * Returns the number of rules currently contained in the list.
* *
* @returns The length of the list. * @returns The length of the list.
*/ */
size_t TypeRuleList::GetLength(void) const size_t TypeRuleList::GetLength(void) const
{ {
return m_Rules.size(); return m_Rules.size();
} }
/** /**
* Validates a field. * Validates a field.
* *
* @param name The name of the attribute. * @param name The name of the attribute.
* @param value The value of the attribute. * @param value The value of the attribute.
* @param[out] subRules The list of sub-rules for the matching rule. * @param[out] subRules The list of sub-rules for the matching rule.
* @param[out] hint A hint describing the validation failure. * @param[out] hint A hint describing the validation failure.
* @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 Value& value, TypeRuleList::Ptr *subRules, String *hint,
const TypeRuleUtilities *utils) const const TypeRuleUtilities *utils) const
{ {
bool foundField = false; bool foundField = false;
BOOST_FOREACH(const TypeRule& rule, m_Rules) { BOOST_FOREACH(const TypeRule& rule, m_Rules) {
if (!rule.MatchName(name)) if (!rule.MatchName(name))
continue; continue;
foundField = true; foundField = true;
if (rule.MatchValue(value, hint, utils)) { if (rule.MatchValue(value, hint, utils)) {
*subRules = rule.GetSubRules(); *subRules = rule.GetSubRules();
return ValidationOK; return ValidationOK;
} }
} }
if (foundField) if (foundField)
return ValidationInvalidType; return ValidationInvalidType;
else else
return ValidationUnknownField; return ValidationUnknownField;
} }

View File

@ -1,76 +1,76 @@
/****************************************************************************** /******************************************************************************
* Icinga 2 * * Icinga 2 *
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) * * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License * * modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 * * as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. * * of the License, or (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef TYPERULELIST_H #ifndef TYPERULELIST_H
#define TYPERULELIST_H #define TYPERULELIST_H
#include "config/i2-config.hpp" #include "config/i2-config.hpp"
#include "base/value.hpp" #include "base/value.hpp"
#include <vector> #include <vector>
namespace icinga namespace icinga
{ {
struct TypeRule; struct TypeRule;
class TypeRuleUtilities; class TypeRuleUtilities;
/** /**
* @ingroup config * @ingroup config
*/ */
enum TypeValidationResult enum TypeValidationResult
{ {
ValidationOK, ValidationOK,
ValidationInvalidType, ValidationInvalidType,
ValidationUnknownField ValidationUnknownField
}; };
/** /**
* A list of configuration type rules. * A list of configuration type rules.
* *
* @ingroup config * @ingroup config
*/ */
class I2_CONFIG_API TypeRuleList : public Object class I2_CONFIG_API TypeRuleList : public Object
{ {
public: public:
DECLARE_PTR_TYPEDEFS(TypeRuleList); DECLARE_PTR_TYPEDEFS(TypeRuleList);
void SetValidator(const String& validator); void AddValidator(const String& validator);
String GetValidator(void) const; std::vector<String> GetValidators(void) const;
void AddRequire(const String& attr); void AddRequire(const String& attr);
void AddRequires(const TypeRuleList::Ptr& ruleList); void AddRequires(const TypeRuleList::Ptr& ruleList);
std::vector<String> GetRequires(void) const; std::vector<String> GetRequires(void) const;
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, TypeValidationResult ValidateAttribute(const String& name, const Value& value,
TypeRuleList::Ptr *subRules, String *hint, const TypeRuleUtilities *utils) const; TypeRuleList::Ptr *subRules, String *hint, const TypeRuleUtilities *utils) const;
size_t GetLength(void) const; size_t GetLength(void) const;
private: private:
String m_Validator; std::vector<String> m_Validators;
std::vector<String> m_Requires; std::vector<String> m_Requires;
std::vector<TypeRule> m_Rules; std::vector<TypeRule> m_Rules;
}; };
} }
#endif /* TYPERULELIST_H */ #endif /* TYPERULELIST_H */

View File

@ -82,7 +82,7 @@ void Command::ValidateArguments(const String& location, const Command::Ptr& obje
String argstr = argval; String argstr = argval;
if(!MacroProcessor::ValidateMacroString(argstr)) { if (!MacroProcessor::ValidateMacroString(argstr)) {
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " + BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
location + ": Closing $ not found in macro format string '" + argstr + "'.", object->GetDebugInfo())); location + ": Closing $ not found in macro format string '" + argstr + "'.", object->GetDebugInfo()));
} }
@ -103,7 +103,7 @@ void Command::ValidateEnvironmentVariables(const String& location, const Command
if (!envval.IsString() || envval.IsEmpty()) if (!envval.IsString() || envval.IsEmpty())
continue; continue;
if(!MacroProcessor::ValidateMacroString(envval)) { if (!MacroProcessor::ValidateMacroString(envval)) {
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " + BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
location + ": Closing $ not found in macro format string '" + envval + "'.", object->GetDebugInfo())); location + ": Closing $ not found in macro format string '" + envval + "'.", object->GetDebugInfo()));
} }