mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-24 14:14:45 +02:00
parent
a7a0eca8b2
commit
ec7224e3ed
@ -56,16 +56,6 @@ DynamicType::Ptr DynamicObject::GetType(void) const
|
||||
return DynamicType::GetByName(GetTypeNameV());
|
||||
}
|
||||
|
||||
DebugInfo DynamicObject::GetDebugInfo(void) const
|
||||
{
|
||||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
void DynamicObject::SetDebugInfo(const DebugInfo& di)
|
||||
{
|
||||
m_DebugInfo = di;
|
||||
}
|
||||
|
||||
bool DynamicObject::IsActive(void) const
|
||||
{
|
||||
return GetActive();
|
||||
|
@ -52,9 +52,6 @@ public:
|
||||
|
||||
intrusive_ptr<DynamicType> GetType(void) const;
|
||||
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
void SetDebugInfo(const DebugInfo& di);
|
||||
|
||||
bool IsActive(void) const;
|
||||
bool IsPaused(void) const;
|
||||
|
||||
@ -97,8 +94,6 @@ protected:
|
||||
private:
|
||||
static DynamicObject::Ptr GetObject(const String& type, const String& name);
|
||||
static void RestoreObject(const String& message, int attributeTypes);
|
||||
|
||||
DebugInfo m_DebugInfo;
|
||||
};
|
||||
|
||||
#define DECLARE_OBJECTNAME(klass) \
|
||||
|
@ -33,10 +33,32 @@ public:
|
||||
};
|
||||
}}}
|
||||
|
||||
abstract class DynamicObject
|
||||
abstract class DynamicObjectBase
|
||||
{ };
|
||||
|
||||
code {{{
|
||||
class I2_BASE_API DynamicObjectBase : public ObjectImpl<DynamicObjectBase>
|
||||
{
|
||||
public:
|
||||
inline DebugInfo GetDebugInfo(void) const
|
||||
{
|
||||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
void SetDebugInfo(const DebugInfo& di)
|
||||
{
|
||||
m_DebugInfo = di;
|
||||
}
|
||||
|
||||
private:
|
||||
DebugInfo m_DebugInfo;
|
||||
};
|
||||
}}}
|
||||
|
||||
abstract class DynamicObject : DynamicObjectBase
|
||||
{
|
||||
[config, internal] String __name (Name);
|
||||
[config] String name (ShortName) {
|
||||
[config] String "name" (ShortName) {
|
||||
get {{{
|
||||
if (m_ShortName.IsEmpty())
|
||||
return GetName();
|
||||
@ -45,7 +67,7 @@ abstract class DynamicObject
|
||||
}}}
|
||||
};
|
||||
[config, internal, get_protected] String type (TypeNameV);
|
||||
[config] String zone (ZoneName);
|
||||
[config] name(Zone) zone (ZoneName);
|
||||
[config, internal, get_protected] Array::Ptr templates;
|
||||
[get_protected] bool active;
|
||||
[get_protected] bool paused {
|
||||
|
@ -18,6 +18,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "base/exception.hpp"
|
||||
#include "base/dynamicobject.hpp"
|
||||
#include <boost/thread/tss.hpp>
|
||||
|
||||
#ifdef HAVE_CXXABI_H
|
||||
@ -136,6 +137,8 @@ String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, Sta
|
||||
|
||||
String message = ex.what();
|
||||
|
||||
const ValidationError *vex = dynamic_cast<const ValidationError *>(&ex);
|
||||
|
||||
if (message.IsEmpty())
|
||||
result << boost::diagnostic_information(ex);
|
||||
else
|
||||
@ -148,6 +151,46 @@ String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, Sta
|
||||
ShowCodeFragment(result, dex->GetDebugInfo());
|
||||
}
|
||||
|
||||
if (vex) {
|
||||
DebugInfo di;
|
||||
|
||||
DynamicObject::Ptr dobj = dynamic_pointer_cast<DynamicObject>(vex->GetObject());
|
||||
if (dobj)
|
||||
di = dobj->GetDebugInfo();
|
||||
|
||||
Dictionary::Ptr currentHint = vex->GetDebugHint();
|
||||
Array::Ptr messages;
|
||||
|
||||
BOOST_FOREACH(const String& attr, vex->GetAttributePath()) {
|
||||
Dictionary::Ptr props = currentHint->Get("properties");
|
||||
|
||||
if (!props)
|
||||
break;
|
||||
|
||||
currentHint = props->Get(attr);
|
||||
|
||||
if (!currentHint)
|
||||
break;
|
||||
|
||||
messages = currentHint->Get("messages");
|
||||
}
|
||||
|
||||
if (messages && messages->GetLength() > 0) {
|
||||
Array::Ptr message = messages->Get(messages->GetLength() - 1);
|
||||
|
||||
di.Path = message->Get(1);
|
||||
di.FirstLine = message->Get(2);
|
||||
di.FirstColumn = message->Get(3);
|
||||
di.LastLine = message->Get(4);
|
||||
di.LastColumn = message->Get(5);
|
||||
}
|
||||
|
||||
if (!di.Path.IsEmpty()) {
|
||||
result << "\nLocation:\n";
|
||||
ShowCodeFragment(result, di);
|
||||
}
|
||||
}
|
||||
|
||||
const user_error *uex = dynamic_cast<const user_error *>(&ex);
|
||||
const posix_error *pex = dynamic_cast<const posix_error *>(&ex);
|
||||
|
||||
@ -270,3 +313,57 @@ const char *posix_error::what(void) const throw()
|
||||
return m_Message;
|
||||
}
|
||||
|
||||
ValidationError::ValidationError(const intrusive_ptr<ObjectImpl<DynamicObject> >& object, const std::vector<String>& attributePath, const String& message)
|
||||
: m_Object(object), m_AttributePath(attributePath), m_Message(message)
|
||||
{
|
||||
String path;
|
||||
|
||||
BOOST_FOREACH(const String& attribute, attributePath) {
|
||||
if (!path.IsEmpty())
|
||||
path += " -> ";
|
||||
|
||||
path += "'" + attribute + "'";
|
||||
}
|
||||
|
||||
Type::Ptr type = object->GetReflectionType();
|
||||
m_What = "Validation failed for object '" + object->GetName() + "' of type '" + type->GetName() + "'";
|
||||
|
||||
if (!path.IsEmpty())
|
||||
m_What += "; Attribute " + path;
|
||||
|
||||
m_What += ": " + message;
|
||||
}
|
||||
|
||||
ValidationError::~ValidationError(void) throw()
|
||||
{ }
|
||||
|
||||
const char *ValidationError::what(void) const throw()
|
||||
{
|
||||
return m_What.CStr();
|
||||
}
|
||||
|
||||
intrusive_ptr<ObjectImpl<DynamicObject> > ValidationError::GetObject(void) const
|
||||
{
|
||||
return m_Object;
|
||||
}
|
||||
|
||||
std::vector<String> ValidationError::GetAttributePath(void) const
|
||||
{
|
||||
return m_AttributePath;
|
||||
}
|
||||
|
||||
String ValidationError::GetMessage(void) const
|
||||
{
|
||||
return m_Message;
|
||||
}
|
||||
|
||||
void ValidationError::SetDebugHint(const Dictionary::Ptr& dhint)
|
||||
{
|
||||
m_DebugHint = dhint;
|
||||
}
|
||||
|
||||
Dictionary::Ptr ValidationError::GetDebugHint(void) const
|
||||
{
|
||||
return m_DebugHint;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "base/context.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include "base/debuginfo.hpp"
|
||||
#include "base/dictionary.hpp"
|
||||
#include <sstream>
|
||||
#include <boost/exception/errinfo_api_function.hpp>
|
||||
#include <boost/exception/errinfo_errno.hpp>
|
||||
@ -64,6 +65,35 @@ private:
|
||||
bool m_IncompleteExpr;
|
||||
};
|
||||
|
||||
class DynamicObject;
|
||||
template<> class ObjectImpl<DynamicObject>;
|
||||
|
||||
/*
|
||||
* @ingroup base
|
||||
*/
|
||||
class I2_BASE_API ValidationError : virtual public user_error
|
||||
{
|
||||
public:
|
||||
ValidationError(const intrusive_ptr<ObjectImpl<DynamicObject> >& object, const std::vector<String>& attributePath, const String& message);
|
||||
~ValidationError(void) throw();
|
||||
|
||||
virtual const char *what(void) const throw();
|
||||
|
||||
intrusive_ptr<ObjectImpl<DynamicObject> > GetObject(void) const;
|
||||
std::vector<String> GetAttributePath(void) const;
|
||||
String GetMessage(void) const;
|
||||
|
||||
void SetDebugHint(const Dictionary::Ptr& dhint);
|
||||
Dictionary::Ptr GetDebugHint(void) const;
|
||||
|
||||
private:
|
||||
intrusive_ptr<ObjectImpl<DynamicObject> > m_Object;
|
||||
std::vector<String> m_AttributePath;
|
||||
String m_Message;
|
||||
String m_What;
|
||||
Dictionary::Ptr m_DebugHint;
|
||||
};
|
||||
|
||||
I2_BASE_API StackTrace *GetLastExceptionStack(void);
|
||||
I2_BASE_API void SetLastExceptionStack(const StackTrace& trace);
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace icinga
|
||||
|
||||
class FileLogger : StreamLogger
|
||||
{
|
||||
[config] String path;
|
||||
[config, required] String path;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/dynamictype.hpp"
|
||||
#include "base/application.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <algorithm>
|
||||
|
@ -137,7 +137,7 @@ int TypeType::GetFieldId(const String& name) const
|
||||
Field TypeType::GetFieldInfo(int id) const
|
||||
{
|
||||
if (id == 0)
|
||||
return Field(0, "Object", "prototype", 0);
|
||||
return Field(0, "Object", "prototype", NULL, 0);
|
||||
|
||||
throw std::runtime_error("Invalid field ID.");
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ enum FieldAttribute
|
||||
FAConfig = 2,
|
||||
FAState = 4,
|
||||
FAInternal = 64,
|
||||
FARequired = 512
|
||||
};
|
||||
|
||||
class Type;
|
||||
@ -46,10 +47,11 @@ struct Field
|
||||
int ID;
|
||||
const char *TypeName;
|
||||
const char *Name;
|
||||
const char *RefTypeName;
|
||||
int Attributes;
|
||||
|
||||
Field(int id, const char *type, const char *name, int attributes)
|
||||
: ID(id), TypeName(type), Name(name), Attributes(attributes)
|
||||
Field(int id, const char *type, const char *name, const char *reftype, int attributes)
|
||||
: ID(id), TypeName(type), Name(name), RefTypeName(reftype), Attributes(attributes)
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -58,6 +60,12 @@ enum TypeAttribute
|
||||
TAAbstract = 1
|
||||
};
|
||||
|
||||
class ValidationUtils
|
||||
{
|
||||
public:
|
||||
virtual bool ValidateName(const String& type, const String& name) const = 0;
|
||||
};
|
||||
|
||||
class I2_BASE_API Type : public Object
|
||||
{
|
||||
public:
|
||||
|
@ -17,10 +17,8 @@
|
||||
|
||||
mkclass_target(checkercomponent.ti checkercomponent.thpp)
|
||||
|
||||
mkembedconfig_target(checker-type.conf checker-type.cpp)
|
||||
|
||||
set(checker_SOURCES
|
||||
checkercomponent.cpp checkercomponent.thpp checker-type.cpp
|
||||
checkercomponent.cpp checkercomponent.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -1,21 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type CheckerComponent {
|
||||
}
|
@ -26,6 +26,7 @@
|
||||
#include "base/unixsocket.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include "base/networkstream.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <iostream>
|
||||
#ifdef HAVE_EDITLINE
|
||||
#include "cli/editline.hpp"
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
#include "cli/repositoryutility.hpp"
|
||||
#include "cli/clicommand.hpp"
|
||||
#include "config/configtype.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/application.hpp"
|
||||
#include "base/convert.hpp"
|
||||
@ -189,10 +187,10 @@ void RepositoryUtility::PrintChangeLog(std::ostream& fp)
|
||||
}
|
||||
}
|
||||
|
||||
class RepositoryTypeRuleUtilities : public TypeRuleUtilities
|
||||
class RepositoryValidationUtils : public ValidationUtils
|
||||
{
|
||||
public:
|
||||
virtual bool ValidateName(const String& type, const String& name, String *hint) const
|
||||
virtual bool ValidateName(const String& type, const String& name) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -228,31 +226,19 @@ bool RepositoryUtility::AddObject(const std::vector<String>& object_paths, const
|
||||
change->Set("command", "add");
|
||||
change->Set("attrs", attrs);
|
||||
|
||||
Type::Ptr utype = Type::GetByName(type);
|
||||
ASSERT(utype);
|
||||
|
||||
if (check_config) {
|
||||
ConfigType::Ptr ctype = ConfigType::GetByName(type);
|
||||
try {
|
||||
Object::Ptr object = utype->Instantiate();
|
||||
Deserialize(object, attrs, false, FAConfig);
|
||||
|
||||
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->Remove("import");
|
||||
vattrs->Set("type", type);
|
||||
|
||||
Type::Ptr dtype = Type::GetByName(type);
|
||||
|
||||
Object::Ptr object = dtype->Instantiate();
|
||||
Deserialize(object, vattrs, false, FAConfig);
|
||||
|
||||
try {
|
||||
RepositoryTypeRuleUtilities utils;
|
||||
ctype->ValidateItem(name, object, DebugInfo(), &utils);
|
||||
} catch (const ScriptError& ex) {
|
||||
Log(LogCritical, "config", DiagnosticInformation(ex));
|
||||
return false;
|
||||
}
|
||||
RepositoryValidationUtils utils;
|
||||
static_pointer_cast<DynamicObject>(object)->Validate(FAConfig, utils);
|
||||
} catch (const ScriptError& ex) {
|
||||
Log(LogCritical, "config", DiagnosticInformation(ex));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,10 @@ mkclass_target(compatlogger.ti compatlogger.thpp)
|
||||
mkclass_target(externalcommandlistener.ti externalcommandlistener.thpp)
|
||||
mkclass_target(statusdatawriter.ti statusdatawriter.thpp)
|
||||
|
||||
mkembedconfig_target(compat-type.conf compat-type.cpp)
|
||||
|
||||
set(compat_SOURCES
|
||||
checkresultreader.cpp checkresultreader.thpp compatlogger.cpp
|
||||
compatlogger.thpp externalcommandlistener.cpp externalcommandlistener.thpp
|
||||
statusdatawriter.cpp statusdatawriter.thpp compat-type.cpp
|
||||
statusdatawriter.cpp statusdatawriter.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -1,39 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type StatusDataWriter {
|
||||
%attribute %string "status_path",
|
||||
%attribute %string "objects_path",
|
||||
%attribute %number "update_interval"
|
||||
}
|
||||
|
||||
%type ExternalCommandListener {
|
||||
%attribute %string "command_path"
|
||||
}
|
||||
|
||||
%type CompatLogger {
|
||||
%validator "ValidateRotationMethod",
|
||||
|
||||
%attribute %string "log_dir",
|
||||
%attribute %string "rotation_method"
|
||||
}
|
||||
|
||||
%type CheckResultReader {
|
||||
%attribute %string "spool_dir"
|
||||
}
|
@ -32,7 +32,6 @@
|
||||
#include "base/convert.hpp"
|
||||
#include "base/application.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include "base/function.hpp"
|
||||
#include "base/statsfunction.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@ -40,7 +39,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(CompatLogger);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateRotationMethod, &CompatLogger::ValidateRotationMethod);
|
||||
|
||||
REGISTER_STATSFUNCTION(CompatLoggerStats, &CompatLogger::StatsFunc);
|
||||
|
||||
@ -561,14 +559,12 @@ void CompatLogger::RotationTimerHandler(void)
|
||||
ScheduleNextRotation();
|
||||
}
|
||||
|
||||
void CompatLogger::ValidateRotationMethod(const String& location, const CompatLogger::Ptr& object)
|
||||
void CompatLogger::ValidateRotationMethod(const String& value, const ValidationUtils& utils)
|
||||
{
|
||||
String rotation_method = object->GetRotationMethod();
|
||||
ObjectImpl<CompatLogger>::ValidateRotationMethod(value, utils);
|
||||
|
||||
if (rotation_method != "HOURLY" && rotation_method != "DAILY" &&
|
||||
rotation_method != "WEEKLY" && rotation_method != "MONTHLY" && rotation_method != "NONE") {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Rotation method '" + rotation_method + "' is invalid.", object->GetDebugInfo()));
|
||||
if (value != "HOURLY" && value != "DAILY" &&
|
||||
value != "WEEKLY" && value != "MONTHLY" && value != "NONE") {
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("rotation_method"), "Rotation method '" + value + "' is invalid."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
|
||||
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
|
||||
|
||||
static void ValidateRotationMethod(const String& location, const CompatLogger::Ptr& object);
|
||||
virtual void ValidateRotationMethod(const String& value, const ValidationUtils& utils) override;
|
||||
|
||||
protected:
|
||||
virtual void Start(void);
|
||||
|
@ -31,15 +31,13 @@ endif()
|
||||
|
||||
add_flex_bison_dependency(config_lexer config_parser)
|
||||
|
||||
mkembedconfig_target(base-type.conf base-type.cpp)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(config_SOURCES
|
||||
applyrule.cpp base-type.conf base-type.cpp
|
||||
applyrule.cpp
|
||||
configcompilercontext.cpp configcompiler.cpp configitembuilder.cpp
|
||||
configitem.cpp ${FLEX_config_lexer_OUTPUTS} ${BISON_config_parser_OUTPUTS}
|
||||
configtype.cpp expression.cpp objectrule.cpp typerule.cpp typerulelist.cpp
|
||||
expression.cpp objectrule.cpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -1,46 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type DynamicObject {
|
||||
%require "__name",
|
||||
%attribute %string "__name",
|
||||
|
||||
%attribute %string "name",
|
||||
|
||||
%require "type",
|
||||
%attribute %string "type",
|
||||
|
||||
%attribute %name(Zone) "zone",
|
||||
|
||||
%attribute %array "templates" {
|
||||
%attribute %string "*"
|
||||
},
|
||||
}
|
||||
|
||||
%type Logger {
|
||||
%attribute %string "severity"
|
||||
}
|
||||
|
||||
%type FileLogger %inherits Logger {
|
||||
%require "path",
|
||||
%attribute %string "path"
|
||||
}
|
||||
|
||||
%type SyslogLogger %inherits Logger {
|
||||
}
|
@ -19,8 +19,8 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "config/typerule.hpp"
|
||||
#include "config/expression.hpp"
|
||||
#include "base/exception.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
@ -167,19 +167,6 @@ do { \
|
||||
[ \t] /* ignore whitespace */
|
||||
|
||||
<INITIAL>{
|
||||
%type return T_TYPE;
|
||||
%dictionary { yylval->type = TypeDictionary; return T_TYPE_DICTIONARY; }
|
||||
%array { yylval->type = TypeArray; return T_TYPE_ARRAY; }
|
||||
%number { yylval->type = TypeNumber; return T_TYPE_NUMBER; }
|
||||
%string { yylval->type = TypeString; return T_TYPE_STRING; }
|
||||
%scalar { yylval->type = TypeScalar; return T_TYPE_SCALAR; }
|
||||
%any { yylval->type = TypeAny; return T_TYPE_ANY; }
|
||||
%function { yylval->type = TypeFunction; return T_TYPE_FUNCTION; }
|
||||
%name { yylval->type = TypeName; return T_TYPE_NAME; }
|
||||
%validator { return T_VALIDATOR; }
|
||||
%require { return T_REQUIRE; }
|
||||
%attribute { return T_ATTRIBUTE; }
|
||||
%inherits return T_INHERITS;
|
||||
object return T_OBJECT;
|
||||
template return T_TEMPLATE;
|
||||
include return T_INCLUDE;
|
||||
|
@ -23,8 +23,6 @@
|
||||
#include "config/i2-config.hpp"
|
||||
#include "config/configitembuilder.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "config/typerule.hpp"
|
||||
#include "config/typerulelist.hpp"
|
||||
#include "config/expression.hpp"
|
||||
#include "config/applyrule.hpp"
|
||||
#include "config/objectrule.hpp"
|
||||
@ -92,9 +90,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
|
||||
bool boolean;
|
||||
icinga::Expression *expr;
|
||||
icinga::DictExpression *dexpr;
|
||||
icinga::Value *variant;
|
||||
CombinedSetOp csop;
|
||||
icinga::TypeSpecifier type;
|
||||
std::vector<String> *slist;
|
||||
std::vector<std::pair<Expression *, EItemInfo> > *llist;
|
||||
std::vector<Expression *> *elist;
|
||||
@ -149,18 +145,6 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
|
||||
%token T_LOCALS "locals (T_LOCALS)"
|
||||
%token T_CONST "const (T_CONST)"
|
||||
%token T_USE "use (T_USE)"
|
||||
%token <type> T_TYPE_DICTIONARY "dictionary (T_TYPE_DICTIONARY)"
|
||||
%token <type> T_TYPE_ARRAY "array (T_TYPE_ARRAY)"
|
||||
%token <type> T_TYPE_NUMBER "number (T_TYPE_NUMBER)"
|
||||
%token <type> T_TYPE_STRING "string (T_TYPE_STRING)"
|
||||
%token <type> T_TYPE_SCALAR "scalar (T_TYPE_SCALAR)"
|
||||
%token <type> T_TYPE_ANY "any (T_TYPE_ANY)"
|
||||
%token <type> T_TYPE_FUNCTION "function (T_TYPE_FUNCTION)"
|
||||
%token <type> T_TYPE_NAME "name (T_TYPE_NAME)"
|
||||
%token T_VALIDATOR "%validator (T_VALIDATOR)"
|
||||
%token T_REQUIRE "%require (T_REQUIRE)"
|
||||
%token T_ATTRIBUTE "%attribute (T_ATTRIBUTE)"
|
||||
%token T_TYPE "type (T_TYPE)"
|
||||
%token T_OBJECT "object (T_OBJECT)"
|
||||
%token T_TEMPLATE "template (T_TEMPLATE)"
|
||||
%token T_INCLUDE "include (T_INCLUDE)"
|
||||
@ -190,9 +174,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
|
||||
%type <elist> rterm_items_inner
|
||||
%type <slist> identifier_items
|
||||
%type <slist> identifier_items_inner
|
||||
%type <variant> typerulelist
|
||||
%type <csop> combined_set_op
|
||||
%type <type> type
|
||||
%type <llist> statements
|
||||
%type <llist> lterm_items
|
||||
%type <llist> lterm_items_inner
|
||||
@ -352,106 +334,6 @@ identifier: T_IDENTIFIER
|
||||
| T_STRING
|
||||
;
|
||||
|
||||
type: T_TYPE identifier
|
||||
{
|
||||
String name = String($2);
|
||||
free($2);
|
||||
|
||||
context->m_Type = ConfigType::GetByName(name);
|
||||
|
||||
if (!context->m_Type) {
|
||||
context->m_Type = new ConfigType(name, @$);
|
||||
context->m_Type->Register();
|
||||
}
|
||||
}
|
||||
type_inherits_specifier typerulelist
|
||||
{
|
||||
TypeRuleList::Ptr ruleList = *$5;
|
||||
delete $5;
|
||||
|
||||
context->m_Type->GetRuleList()->AddRules(ruleList);
|
||||
context->m_Type->GetRuleList()->AddRequires(ruleList);
|
||||
|
||||
BOOST_FOREACH(const String& validator, ruleList->GetValidators()) {
|
||||
context->m_Type->GetRuleList()->AddValidator(validator);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
typerulelist: '{'
|
||||
{
|
||||
context->m_OpenBraces++;
|
||||
context->m_RuleLists.push(new TypeRuleList());
|
||||
}
|
||||
typerules
|
||||
'}'
|
||||
{
|
||||
context->m_OpenBraces--;
|
||||
$$ = new Value(context->m_RuleLists.top());
|
||||
context->m_RuleLists.pop();
|
||||
}
|
||||
;
|
||||
|
||||
typerules: typerules_inner
|
||||
| typerules_inner sep
|
||||
|
||||
typerules_inner: /* empty */
|
||||
| typerule
|
||||
| typerules_inner sep typerule
|
||||
;
|
||||
|
||||
typerule: T_REQUIRE T_STRING
|
||||
{
|
||||
context->m_RuleLists.top()->AddRequire($2);
|
||||
free($2);
|
||||
}
|
||||
| T_VALIDATOR T_STRING
|
||||
{
|
||||
context->m_RuleLists.top()->AddValidator($2);
|
||||
free($2);
|
||||
}
|
||||
| T_ATTRIBUTE type T_STRING
|
||||
{
|
||||
TypeRule rule($2, String(), $3, TypeRuleList::Ptr(), @$);
|
||||
free($3);
|
||||
|
||||
context->m_RuleLists.top()->AddRule(rule);
|
||||
}
|
||||
| T_ATTRIBUTE T_TYPE_NAME '(' identifier ')' T_STRING
|
||||
{
|
||||
TypeRule rule($2, $4, $6, TypeRuleList::Ptr(), @$);
|
||||
free($4);
|
||||
free($6);
|
||||
|
||||
context->m_RuleLists.top()->AddRule(rule);
|
||||
}
|
||||
| T_ATTRIBUTE type T_STRING typerulelist
|
||||
{
|
||||
TypeRule rule($2, String(), $3, *$4, @$);
|
||||
free($3);
|
||||
delete $4;
|
||||
context->m_RuleLists.top()->AddRule(rule);
|
||||
}
|
||||
;
|
||||
|
||||
type_inherits_specifier: /* empty */
|
||||
| T_INHERITS identifier
|
||||
{
|
||||
context->m_Type->SetParent($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
|
||||
type: T_TYPE_DICTIONARY
|
||||
| T_TYPE_ARRAY
|
||||
| T_TYPE_NUMBER
|
||||
| T_TYPE_STRING
|
||||
| T_TYPE_SCALAR
|
||||
| T_TYPE_ANY
|
||||
| T_TYPE_FUNCTION
|
||||
| T_TYPE_NAME
|
||||
;
|
||||
|
||||
object:
|
||||
{
|
||||
context->m_ObjectAssign.push(true);
|
||||
@ -483,7 +365,7 @@ object:
|
||||
|
||||
if (seen_assign) {
|
||||
if (!ObjectRule::IsValidSourceType(type))
|
||||
BOOST_THROW_EXCEPTION(ScriptError("object rule 'assign' cannot be used for type '" + type + "'", DebugInfoRange(@2, @3)));
|
||||
BOOST_THROW_EXCEPTION(ScriptError("object rule 'assign' cannot be used for type '" + type + "'", DebugInfoRange(@2, @4)));
|
||||
|
||||
if (ignore) {
|
||||
Expression *rex = new LogicalNegateExpression(ignore, DebugInfoRange(@2, @5));
|
||||
@ -544,11 +426,7 @@ combined_set_op: T_SET
|
||||
| T_SET_BINARY_OR
|
||||
;
|
||||
|
||||
lterm: type
|
||||
{
|
||||
$$ = MakeLiteral(); // ASTify this
|
||||
}
|
||||
| library
|
||||
lterm: library
|
||||
{
|
||||
$$ = MakeLiteral(); // ASTify this
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#include "config/i2-config.hpp"
|
||||
#include "config/expression.hpp"
|
||||
#include "config/configtype.hpp"
|
||||
#include "base/debuginfo.hpp"
|
||||
#include "base/registry.hpp"
|
||||
#include "base/initialize.hpp"
|
||||
@ -124,9 +123,6 @@ public:
|
||||
std::ostringstream m_LexBuffer;
|
||||
CompilerDebugInfo m_LocationBegin;
|
||||
|
||||
std::stack<TypeRuleList::Ptr> m_RuleLists;
|
||||
ConfigType::Ptr m_Type;
|
||||
|
||||
std::stack<bool> m_Apply;
|
||||
std::stack<bool> m_ObjectAssign;
|
||||
std::stack<bool> m_SeenAssign;
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "config/configcompilercontext.hpp"
|
||||
#include "config/applyrule.hpp"
|
||||
#include "config/objectrule.hpp"
|
||||
#include "config/configtype.hpp"
|
||||
#include "base/application.hpp"
|
||||
#include "base/dynamictype.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
@ -135,6 +134,15 @@ boost::shared_ptr<Expression> ConfigItem::GetFilter(void) const
|
||||
return m_Filter;
|
||||
}
|
||||
|
||||
class DefaultValidationUtils : public ValidationUtils
|
||||
{
|
||||
public:
|
||||
virtual bool ValidateName(const String& type, const String& name) const override
|
||||
{
|
||||
return ConfigItem::GetObject(type, name) != ConfigItem::Ptr();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Commits the configuration item by creating a DynamicObject
|
||||
* object.
|
||||
@ -210,7 +218,9 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
|
||||
persistentItem->Set("type", GetType());
|
||||
persistentItem->Set("name", GetName());
|
||||
persistentItem->Set("properties", Serialize(dobj, FAConfig));
|
||||
persistentItem->Set("debug_hints", debugHints.ToDictionary());
|
||||
|
||||
Dictionary::Ptr dhint = debugHints.ToDictionary();
|
||||
persistentItem->Set("debug_hints", dhint);
|
||||
|
||||
Array::Ptr di = new Array();
|
||||
di->Add(m_DebugInfo.Path);
|
||||
@ -223,13 +233,16 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
|
||||
ConfigCompilerContext::GetInstance()->WriteObject(persistentItem);
|
||||
persistentItem.reset();
|
||||
|
||||
ConfigType::Ptr ctype = ConfigType::GetByName(GetType());
|
||||
|
||||
if (ctype) {
|
||||
TypeRuleUtilities utils;
|
||||
ctype->ValidateItem(GetName(), dobj, GetDebugInfo(), &utils);
|
||||
try {
|
||||
DefaultValidationUtils utils;
|
||||
dobj->Validate(FAConfig, utils);
|
||||
} catch (ValidationError& ex) {
|
||||
ex.SetDebugHint(dhint);
|
||||
throw;
|
||||
}
|
||||
|
||||
dhint.reset();
|
||||
|
||||
dobj->Register();
|
||||
|
||||
m_Object = dobj;
|
||||
|
@ -1,271 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "config/configtype.hpp"
|
||||
#include "config/vmops.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include "base/singleton.hpp"
|
||||
#include "base/function.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
ConfigType::ConfigType(const String& name, const DebugInfo& debuginfo)
|
||||
: m_Name(name), m_RuleList(new TypeRuleList()), m_DebugInfo(debuginfo)
|
||||
{ }
|
||||
|
||||
String ConfigType::GetName(void) const
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
String ConfigType::GetParent(void) const
|
||||
{
|
||||
return m_Parent;
|
||||
}
|
||||
|
||||
void ConfigType::SetParent(const String& parent)
|
||||
{
|
||||
m_Parent = parent;
|
||||
}
|
||||
|
||||
TypeRuleList::Ptr ConfigType::GetRuleList(void) const
|
||||
{
|
||||
return m_RuleList;
|
||||
}
|
||||
|
||||
DebugInfo ConfigType::GetDebugInfo(void) const
|
||||
{
|
||||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
void ConfigType::AddParentRules(std::vector<TypeRuleList::Ptr>& ruleLists, const ConfigType::Ptr& item)
|
||||
{
|
||||
ConfigType::Ptr parent;
|
||||
if (item->m_Parent.IsEmpty()) {
|
||||
if (item->GetName() != "DynamicObject")
|
||||
parent = ConfigType::GetByName("DynamicObject");
|
||||
} else {
|
||||
parent = ConfigType::GetByName(item->m_Parent);
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
AddParentRules(ruleLists, parent);
|
||||
ruleLists.push_back(parent->m_RuleList);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigType::ValidateItem(const String& name, const Object::Ptr& object, const DebugInfo& debugInfo, const TypeRuleUtilities *utils)
|
||||
{
|
||||
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(location);
|
||||
|
||||
std::vector<TypeRuleList::Ptr> ruleLists;
|
||||
AddParentRules(ruleLists, this);
|
||||
ruleLists.push_back(m_RuleList);
|
||||
|
||||
ValidateObject(object, ruleLists, locations, utils);
|
||||
}
|
||||
|
||||
String ConfigType::LocationToString(const std::vector<String>& locations)
|
||||
{
|
||||
bool first = true;
|
||||
String stack;
|
||||
BOOST_FOREACH(const String& location, locations) {
|
||||
if (!first)
|
||||
stack += " -> ";
|
||||
else
|
||||
first = false;
|
||||
|
||||
stack += location;
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
void ConfigType::ValidateAttribute(const String& key, const Value& value,
|
||||
const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations,
|
||||
const TypeRuleUtilities *utils)
|
||||
{
|
||||
TypeValidationResult overallResult = ValidationUnknownField;
|
||||
std::vector<TypeRuleList::Ptr> subRuleLists;
|
||||
String hint;
|
||||
|
||||
locations.push_back("Key " + key);
|
||||
|
||||
BOOST_FOREACH(const TypeRuleList::Ptr& ruleList, ruleLists) {
|
||||
TypeRuleList::Ptr subRuleList;
|
||||
TypeValidationResult result = ruleList->ValidateAttribute(key, value, &subRuleList, &hint, utils);
|
||||
|
||||
if (subRuleList)
|
||||
subRuleLists.push_back(subRuleList);
|
||||
|
||||
if (overallResult == ValidationOK)
|
||||
continue;
|
||||
|
||||
if (result == ValidationOK) {
|
||||
overallResult = result;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result == ValidationInvalidType)
|
||||
overallResult = result;
|
||||
}
|
||||
|
||||
if (overallResult == ValidationUnknownField)
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Unknown attribute: " + LocationToString(locations)));
|
||||
else if (overallResult == ValidationInvalidType) {
|
||||
String message = "Invalid value: " + LocationToString(locations);
|
||||
|
||||
if (!hint.IsEmpty())
|
||||
message += ": " + hint;
|
||||
|
||||
BOOST_THROW_EXCEPTION(ScriptError(message));
|
||||
}
|
||||
|
||||
if (!subRuleLists.empty() && value.IsObject() && !value.IsObjectType<Array>())
|
||||
ValidateObject(value, subRuleLists, locations, utils);
|
||||
else if (!subRuleLists.empty() && value.IsObjectType<Array>())
|
||||
ValidateArray(value, subRuleLists, locations, utils);
|
||||
|
||||
locations.pop_back();
|
||||
}
|
||||
|
||||
void ConfigType::ValidateObject(const Object::Ptr& object,
|
||||
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()) {
|
||||
locations.push_back("Attribute '" + require + "'");
|
||||
|
||||
Value value = VMOps::GetField(object, require);
|
||||
|
||||
if (value.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Required attribute is missing: " + LocationToString(locations)));
|
||||
|
||||
locations.pop_back();
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const String& validator, ruleList->GetValidators()) {
|
||||
Function::Ptr func = ScriptGlobal::Get(validator, &Empty);
|
||||
|
||||
if (!func)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Validator function '" + validator + "' does not exist."));
|
||||
|
||||
std::vector<Value> arguments;
|
||||
arguments.push_back(LocationToString(locations));
|
||||
arguments.push_back(object);
|
||||
|
||||
func->Invoke(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary::Ptr dictionary = dynamic_pointer_cast<Dictionary>(object);
|
||||
|
||||
if (dictionary) {
|
||||
ObjectLock olock(dictionary);
|
||||
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, dictionary) {
|
||||
ValidateAttribute(kv.first, kv.second, ruleLists, locations, utils);
|
||||
}
|
||||
} else {
|
||||
Type::Ptr type = object->GetReflectionType();
|
||||
|
||||
if (!type)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < type->GetFieldCount(); i++) {
|
||||
Field field = type->GetFieldInfo(i);
|
||||
|
||||
if (!(field.Attributes & FAConfig))
|
||||
continue;
|
||||
|
||||
ValidateAttribute(field.Name, object->GetField(i), ruleLists, locations, utils);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigType::ValidateArray(const Array::Ptr& array,
|
||||
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()) {
|
||||
size_t index = Convert::ToLong(require);
|
||||
|
||||
locations.push_back("Attribute '" + require + "'");
|
||||
|
||||
if (array->GetLength() < index)
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Required array index is missing: " + LocationToString(locations)));
|
||||
|
||||
locations.pop_back();
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const String& validator, ruleList->GetValidators()) {
|
||||
Function::Ptr func = ScriptGlobal::Get(validator, &Empty);
|
||||
|
||||
if (!func)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Validator function '" + validator + "' does not exist."));
|
||||
|
||||
std::vector<Value> arguments;
|
||||
arguments.push_back(LocationToString(locations));
|
||||
arguments.push_back(array);
|
||||
|
||||
func->Invoke(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectLock olock(array);
|
||||
|
||||
int index = 0;
|
||||
String key;
|
||||
BOOST_FOREACH(const Value& value, array) {
|
||||
key = Convert::ToString(index);
|
||||
index++;
|
||||
|
||||
ValidateAttribute(key, value, ruleLists, locations, utils);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigType::Register(void)
|
||||
{
|
||||
ConfigTypeRegistry::GetInstance()->Register(GetName(), this);
|
||||
}
|
||||
|
||||
ConfigType::Ptr ConfigType::GetByName(const String& name)
|
||||
{
|
||||
return ConfigTypeRegistry::GetInstance()->GetItem(name);
|
||||
}
|
||||
|
||||
ConfigTypeRegistry::ItemMap ConfigType::GetTypes(void)
|
||||
{
|
||||
return ConfigTypeRegistry::GetInstance()->GetItems();
|
||||
}
|
||||
|
||||
ConfigTypeRegistry *ConfigTypeRegistry::GetInstance(void)
|
||||
{
|
||||
return Singleton<ConfigTypeRegistry>::GetInstance();
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef CONFIGTYPE_H
|
||||
#define CONFIGTYPE_H
|
||||
|
||||
#include "config/i2-config.hpp"
|
||||
#include "config/typerulelist.hpp"
|
||||
#include "config/typerule.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "base/array.hpp"
|
||||
#include "base/registry.hpp"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* A configuration type. Used to validate config objects.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
class I2_CONFIG_API ConfigType : public Object {
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(ConfigType);
|
||||
|
||||
ConfigType(const String& name, const DebugInfo& debuginfo);
|
||||
|
||||
String GetName(void) const;
|
||||
|
||||
String GetParent(void) const;
|
||||
void SetParent(const String& parent);
|
||||
|
||||
TypeRuleList::Ptr GetRuleList(void) const;
|
||||
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
|
||||
void ValidateItem(const String& name, const Object::Ptr& object,
|
||||
const DebugInfo& debugInfo, const TypeRuleUtilities *utils);
|
||||
|
||||
void Register(void);
|
||||
static ConfigType::Ptr GetByName(const String& name);
|
||||
static Registry<ConfigType, ConfigType::Ptr>::ItemMap GetTypes(void);
|
||||
|
||||
private:
|
||||
String m_Name; /**< The type name. */
|
||||
String m_Parent; /**< The parent type. */
|
||||
|
||||
TypeRuleList::Ptr m_RuleList;
|
||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||
|
||||
static void ValidateAttribute(const String& key, const Value& value,
|
||||
const std::vector<TypeRuleList::Ptr>& ruleLists, std::vector<String>& locations,
|
||||
const TypeRuleUtilities *utils);
|
||||
static void ValidateObject(const Object::Ptr& object,
|
||||
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 TypeRuleUtilities *utils);
|
||||
|
||||
static String LocationToString(const std::vector<String>& locations);
|
||||
|
||||
static void AddParentRules(std::vector<TypeRuleList::Ptr>& ruleLists, const ConfigType::Ptr& item);
|
||||
};
|
||||
|
||||
class I2_CONFIG_API ConfigTypeRegistry : public Registry<ConfigTypeRegistry, ConfigType::Ptr>
|
||||
{
|
||||
public:
|
||||
static ConfigTypeRegistry *GetInstance(void);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* CONFIGTYPE_H */
|
@ -1,108 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "config/typerule.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include "base/dictionary.hpp"
|
||||
#include "base/array.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
TypeRule::TypeRule(TypeSpecifier type, const String& nameType,
|
||||
const String& namePattern, const TypeRuleList::Ptr& subRules,
|
||||
const DebugInfo& debuginfo)
|
||||
: m_Type(type), m_NameType(nameType), m_NamePattern(namePattern), m_SubRules(subRules), m_DebugInfo(debuginfo)
|
||||
{ }
|
||||
|
||||
TypeRuleList::Ptr TypeRule::GetSubRules(void) const
|
||||
{
|
||||
return m_SubRules;
|
||||
}
|
||||
|
||||
bool TypeRule::MatchName(const String& name) const
|
||||
{
|
||||
return (Utility::Match(m_NamePattern, name));
|
||||
}
|
||||
|
||||
bool TypeRule::MatchValue(const Value& value, String *hint, const TypeRuleUtilities *utils) const
|
||||
{
|
||||
ConfigItem::Ptr item;
|
||||
|
||||
if (value.IsEmpty())
|
||||
return true;
|
||||
|
||||
switch (m_Type) {
|
||||
case TypeAny:
|
||||
return true;
|
||||
|
||||
case TypeString:
|
||||
/* fall through; any scalar can be converted to a string */
|
||||
case TypeScalar:
|
||||
return value.IsScalar();
|
||||
|
||||
case TypeNumber:
|
||||
try {
|
||||
Convert::ToDouble(value);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
case TypeDictionary:
|
||||
return value.IsObjectType<Dictionary>();
|
||||
|
||||
case TypeArray:
|
||||
return value.IsObjectType<Array>();
|
||||
|
||||
case TypeFunction:
|
||||
return value.IsObjectType<Function>();
|
||||
|
||||
case TypeName:
|
||||
if (!value.IsScalar())
|
||||
return false;
|
||||
|
||||
return utils->ValidateName(m_NameType, value, hint);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool TypeRuleUtilities::ValidateName(const String& type, const String& name, String *hint) const
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
return true;
|
||||
|
||||
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;
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef TYPERULE_H
|
||||
#define TYPERULE_H
|
||||
|
||||
#include "config/i2-config.hpp"
|
||||
#include "config/typerulelist.hpp"
|
||||
#include "base/debuginfo.hpp"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* Utilities for type rules.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
class I2_CONFIG_API TypeRuleUtilities
|
||||
{
|
||||
public:
|
||||
virtual bool ValidateName(const String& type, const String& name, String *hint) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* The allowed type for a type rule.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
enum TypeSpecifier
|
||||
{
|
||||
TypeAny,
|
||||
TypeScalar,
|
||||
TypeNumber,
|
||||
TypeString,
|
||||
TypeDictionary,
|
||||
TypeArray,
|
||||
TypeFunction,
|
||||
TypeName
|
||||
};
|
||||
|
||||
/**
|
||||
* A configuration type rule.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct I2_CONFIG_API TypeRule
|
||||
{
|
||||
public:
|
||||
TypeRule(TypeSpecifier type, const String& nameType,
|
||||
const String& namePattern, const TypeRuleList::Ptr& subRules,
|
||||
const DebugInfo& debuginfo);
|
||||
|
||||
TypeRuleList::Ptr GetSubRules(void) const;
|
||||
|
||||
bool MatchName(const String& name) const;
|
||||
bool MatchValue(const Value& value, String *hint, const TypeRuleUtilities *utils) const;
|
||||
|
||||
private:
|
||||
TypeSpecifier m_Type;
|
||||
String m_NameType;
|
||||
String m_NamePattern;
|
||||
TypeRuleList::Ptr m_SubRules;
|
||||
DebugInfo m_DebugInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* TYPERULE_H */
|
@ -1,140 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "config/typerulelist.hpp"
|
||||
#include "config/typerule.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
/**
|
||||
* Adds a validator method for a rule list.
|
||||
*
|
||||
* @param validator The validator.
|
||||
*/
|
||||
void TypeRuleList::AddValidator(const String& validator)
|
||||
{
|
||||
m_Validators.push_back(validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the validator methods.
|
||||
*
|
||||
* @returns The validator methods.
|
||||
*/
|
||||
std::vector<String> TypeRuleList::GetValidators(void) const
|
||||
{
|
||||
return m_Validators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an attribute to the list of required attributes.
|
||||
*
|
||||
* @param attr The new required attribute.
|
||||
*/
|
||||
void TypeRuleList::AddRequire(const String& attr)
|
||||
{
|
||||
m_Requires.push_back(attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of required attributes.
|
||||
*
|
||||
* @returns The list of required attributes.
|
||||
*/
|
||||
std::vector<String> TypeRuleList::GetRequires(void) const
|
||||
{
|
||||
return m_Requires;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all requires from the specified rule list.
|
||||
*
|
||||
* @param ruleList The rule list to copy requires from.
|
||||
*/
|
||||
void TypeRuleList::AddRequires(const TypeRuleList::Ptr& ruleList)
|
||||
{
|
||||
BOOST_FOREACH(const String& require, ruleList->m_Requires) {
|
||||
AddRequire(require);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a rule to a rule list.
|
||||
*
|
||||
* @param rule The rule that should be added.
|
||||
*/
|
||||
void TypeRuleList::AddRule(const TypeRule& rule)
|
||||
{
|
||||
m_Rules.push_back(rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all rules from the specified rule list.
|
||||
*
|
||||
* @param ruleList The rule list to copy rules from.
|
||||
*/
|
||||
void TypeRuleList::AddRules(const TypeRuleList::Ptr& ruleList)
|
||||
{
|
||||
BOOST_FOREACH(const TypeRule& rule, ruleList->m_Rules) {
|
||||
AddRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rules currently contained in the list.
|
||||
*
|
||||
* @returns The length of the list.
|
||||
*/
|
||||
size_t TypeRuleList::GetLength(void) const
|
||||
{
|
||||
return m_Rules.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a field.
|
||||
*
|
||||
* @param name The name of the attribute.
|
||||
* @param value The value of the attribute.
|
||||
* @param[out] subRules The list of sub-rules for the matching rule.
|
||||
* @param[out] hint A hint describing the validation failure.
|
||||
* @returns The validation result.
|
||||
*/
|
||||
TypeValidationResult TypeRuleList::ValidateAttribute(const String& name,
|
||||
const Value& value, TypeRuleList::Ptr *subRules, String *hint,
|
||||
const TypeRuleUtilities *utils) const
|
||||
{
|
||||
bool foundField = false;
|
||||
BOOST_FOREACH(const TypeRule& rule, m_Rules) {
|
||||
if (!rule.MatchName(name))
|
||||
continue;
|
||||
|
||||
foundField = true;
|
||||
|
||||
if (rule.MatchValue(value, hint, utils)) {
|
||||
*subRules = rule.GetSubRules();
|
||||
return ValidationOK;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundField)
|
||||
return ValidationInvalidType;
|
||||
else
|
||||
return ValidationUnknownField;
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef TYPERULELIST_H
|
||||
#define TYPERULELIST_H
|
||||
|
||||
#include "config/i2-config.hpp"
|
||||
#include "base/value.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
struct TypeRule;
|
||||
class TypeRuleUtilities;
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*/
|
||||
enum TypeValidationResult
|
||||
{
|
||||
ValidationOK,
|
||||
ValidationInvalidType,
|
||||
ValidationUnknownField
|
||||
};
|
||||
|
||||
/**
|
||||
* A list of configuration type rules.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
class I2_CONFIG_API TypeRuleList : public Object
|
||||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(TypeRuleList);
|
||||
|
||||
void AddValidator(const String& validator);
|
||||
std::vector<String> GetValidators(void) const;
|
||||
|
||||
void AddRequire(const String& attr);
|
||||
void AddRequires(const TypeRuleList::Ptr& ruleList);
|
||||
std::vector<String> GetRequires(void) const;
|
||||
|
||||
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 TypeRuleUtilities *utils) const;
|
||||
|
||||
size_t GetLength(void) const;
|
||||
|
||||
private:
|
||||
std::vector<String> m_Validators;
|
||||
std::vector<String> m_Requires;
|
||||
std::vector<TypeRule> m_Rules;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* TYPERULELIST_H */
|
@ -317,9 +317,13 @@ public:
|
||||
try {
|
||||
context->SetField(fid, value);
|
||||
} catch (const boost::bad_lexical_cast&) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'", debugInfo));
|
||||
Field fieldInfo = type->GetFieldInfo(fid);
|
||||
Type::Ptr ftype = Type::GetByName(fieldInfo.TypeName);
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "', expected '" + ftype->GetName() + "'", debugInfo));
|
||||
} catch (const std::bad_cast&) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'", debugInfo));
|
||||
Field fieldInfo = type->GetFieldInfo(fid);
|
||||
Type::Ptr ftype = Type::GetByName(fieldInfo.TypeName);
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "', expected '" + ftype->GetName() + "'", debugInfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,11 @@
|
||||
|
||||
mkclass_target(dbconnection.ti dbconnection.thpp)
|
||||
|
||||
mkembedconfig_target(db_ido-type.conf db_ido-type.cpp)
|
||||
mkembedconfig_target(db_ido-itl.conf db_ido-itl.cpp)
|
||||
|
||||
set(db_ido_SOURCES
|
||||
commanddbobject.cpp dbconnection.cpp dbconnection.thpp dbconnection.thpp
|
||||
db_ido-type.cpp db_ido-itl.cpp dbevents.cpp dbobject.cpp dbquery.cpp
|
||||
db_ido-itl.cpp dbevents.cpp dbobject.cpp dbquery.cpp
|
||||
dbreference.cpp dbtype.cpp dbvalue.cpp endpointdbobject.cpp hostdbobject.cpp
|
||||
hostgroupdbobject.cpp idochecktask.cpp servicedbobject.cpp
|
||||
servicegroupdbobject.cpp timeperioddbobject.cpp userdbobject.cpp
|
||||
|
@ -1,48 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type DbConnection {
|
||||
%validator "ValidateFailoverTimeout"
|
||||
|
||||
%attribute %string "table_prefix",
|
||||
|
||||
%attribute %dictionary "cleanup" {
|
||||
%attribute %number "acknowledgements_age",
|
||||
%attribute %number "commenthistory_age",
|
||||
%attribute %number "contactnotifications_age",
|
||||
%attribute %number "contactnotificationmethods_age",
|
||||
%attribute %number "downtimehistory_age",
|
||||
%attribute %number "eventhandlers_age",
|
||||
%attribute %number "externalcommands_age",
|
||||
%attribute %number "flappinghistory_age",
|
||||
%attribute %number "hostchecks_age",
|
||||
%attribute %number "logentries_age",
|
||||
%attribute %number "notifications_age",
|
||||
%attribute %number "processevents_age",
|
||||
%attribute %number "statehistory_age",
|
||||
%attribute %number "servicechecks_age",
|
||||
%attribute %number "systemcommands_age",
|
||||
},
|
||||
|
||||
%attribute %number "categories",
|
||||
|
||||
%attribute %number "enable_ha",
|
||||
|
||||
%attribute %number "failover_timeout",
|
||||
}
|
@ -27,14 +27,12 @@
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/function.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(DbConnection);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateFailoverTimeout, &DbConnection::ValidateFailoverTimeout);
|
||||
|
||||
Timer::Ptr DbConnection::m_ProgramStatusTimer;
|
||||
boost::once_flag DbConnection::m_OnceFlag = BOOST_ONCE_INIT;
|
||||
@ -440,12 +438,12 @@ void DbConnection::PrepareDatabase(void)
|
||||
}
|
||||
}
|
||||
|
||||
void DbConnection::ValidateFailoverTimeout(const String& location, const DbConnection::Ptr& object)
|
||||
void DbConnection::ValidateFailoverTimeout(double value, const ValidationUtils& utils)
|
||||
{
|
||||
if (object->GetFailoverTimeout() < 60) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Failover timeout minimum is 60s.", object->GetDebugInfo()));
|
||||
}
|
||||
ObjectImpl<DbConnection>::ValidateFailoverTimeout(value, utils);
|
||||
|
||||
if (value < 60)
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("failover_timeout"), "Failover timeout minimum is 60s."));
|
||||
}
|
||||
|
||||
void DbConnection::IncreaseQueryCount(void)
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
int GetQueryCount(RingBuffer::SizeType span) const;
|
||||
virtual int GetPendingQueryCount(void) const = 0;
|
||||
|
||||
static void ValidateFailoverTimeout(const String& location, const DbConnection::Ptr& object);
|
||||
virtual void ValidateFailoverTimeout(double value, const ValidationUtils& utils) override;
|
||||
|
||||
protected:
|
||||
virtual void OnConfigLoaded(void);
|
||||
|
@ -56,4 +56,25 @@ abstract class DbConnection : DynamicObject
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
validator DbConnection {
|
||||
Dictionary cleanup {
|
||||
Number acknowledgements_age;
|
||||
Number commenthistory_age;
|
||||
Number contactnotifications_age;
|
||||
Number contactnotificationmethods_age;
|
||||
Number downtimehistory_age;
|
||||
Number eventhandlers_age;
|
||||
Number externalcommands_age;
|
||||
Number flappinghistory_age;
|
||||
Number hostchecks_age;
|
||||
Number logentries_age;
|
||||
Number notifications_age;
|
||||
Number processevents_age;
|
||||
Number statehistory_age;
|
||||
Number servicechecks_age;
|
||||
Number systemcommands_age;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -20,10 +20,8 @@ find_package(MySQL)
|
||||
if(MYSQL_FOUND)
|
||||
mkclass_target(idomysqlconnection.ti idomysqlconnection.thpp)
|
||||
|
||||
mkembedconfig_target(db_ido_mysql-type.conf db_ido_mysql-type.cpp)
|
||||
|
||||
set(db_ido_mysql_SOURCES
|
||||
idomysqlconnection.cpp idomysqlconnection.thpp db_ido_mysql-type.cpp
|
||||
idomysqlconnection.cpp idomysqlconnection.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -1,33 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type IdoMysqlConnection %inherits DbConnection {
|
||||
%attribute %string "host",
|
||||
%attribute %number "port",
|
||||
|
||||
%attribute %string "socket_path",
|
||||
|
||||
%attribute %string "user",
|
||||
%attribute %string "password",
|
||||
|
||||
%attribute %string "database",
|
||||
|
||||
%attribute %string "instance_name",
|
||||
%attribute %string "instance_description"
|
||||
}
|
@ -20,13 +20,11 @@ find_package(PostgreSQL)
|
||||
if(PostgreSQL_FOUND)
|
||||
mkclass_target(idopgsqlconnection.ti idopgsqlconnection.thpp)
|
||||
|
||||
mkembedconfig_target(db_ido_pgsql-type.conf db_ido_pgsql-type.cpp)
|
||||
|
||||
link_directories(${PostgreSQL_LIBRARY_DIRS})
|
||||
include_directories(${PostgreSQL_INCLUDE_DIRS})
|
||||
|
||||
set(db_ido_pgsql_SOURCES
|
||||
idopgsqlconnection.cpp idopgsqlconnection.thpp db_ido_pgsql-type.cpp
|
||||
idopgsqlconnection.cpp idopgsqlconnection.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -1,31 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type IdoPgsqlConnection %inherits DbConnection {
|
||||
%attribute %string "host",
|
||||
%attribute %number "port",
|
||||
|
||||
%attribute %string "user",
|
||||
%attribute %string "password",
|
||||
|
||||
%attribute %string "database",
|
||||
|
||||
%attribute %string "instance_name",
|
||||
%attribute %string "instance_description"
|
||||
}
|
@ -17,10 +17,8 @@
|
||||
|
||||
mkclass_target(demo.ti demo.thpp)
|
||||
|
||||
mkembedconfig_target(demo-type.conf demo-type.cpp)
|
||||
|
||||
set(demo_SOURCES
|
||||
demo.cpp demo.thpp demo-type.cpp
|
||||
demo.cpp demo.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -1,21 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type Demo {
|
||||
}
|
@ -17,11 +17,10 @@
|
||||
|
||||
mkclass_target(hello.ti hello.thpp)
|
||||
|
||||
mkembedconfig_target(hello-type.conf hello-type.cpp)
|
||||
mkembedconfig_target(hello-app.conf hello-app.cpp)
|
||||
|
||||
set(hello_SOURCES
|
||||
hello.cpp hello.thpp hello-type.cpp hello-app.cpp
|
||||
hello.cpp hello.thpp hello-app.cpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -1,21 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type Hello {
|
||||
}
|
@ -38,7 +38,6 @@ mkclass_target(timeperiod.ti timeperiod.thpp)
|
||||
mkclass_target(usergroup.ti usergroup.thpp)
|
||||
mkclass_target(user.ti user.thpp)
|
||||
|
||||
mkembedconfig_target(icinga-type.conf icinga-type.cpp)
|
||||
mkembedconfig_target(icinga-app.conf icinga-app.cpp)
|
||||
|
||||
set(icinga_SOURCES
|
||||
@ -52,7 +51,7 @@ set(icinga_SOURCES
|
||||
notification.thpp notification-apply.cpp objectutils.cpp perfdatavalue.cpp perfdatavalue.thpp pluginutility.cpp scheduleddowntime.cpp
|
||||
scheduleddowntime.thpp scheduleddowntime-apply.cpp service-apply.cpp checkable-check.cpp checkable-comment.cpp
|
||||
service.cpp service.thpp servicegroup.cpp servicegroup.thpp checkable-notification.cpp timeperiod.cpp timeperiod.thpp
|
||||
user.cpp user.thpp usergroup.cpp usergroup.thpp icinga-type.cpp icinga-app.cpp
|
||||
user.cpp user.thpp usergroup.cpp usergroup.thpp icinga-app.cpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "icinga/checkable.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include "base/function.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/bind/apply.hpp>
|
||||
@ -28,7 +27,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(Checkable);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateCheckableCheckInterval, &Checkable::ValidateCheckInterval);
|
||||
|
||||
boost::signals2::signal<void (const Checkable::Ptr&, bool, const MessageOrigin&)> Checkable::OnEnablePerfdataChanged;
|
||||
boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType, bool, double, const MessageOrigin&)> Checkable::OnAcknowledgementSet;
|
||||
@ -263,10 +261,10 @@ Endpoint::Ptr Checkable::GetCommandEndpoint(void) const
|
||||
return Endpoint::GetByName(GetCommandEndpointRaw());
|
||||
}
|
||||
|
||||
void Checkable::ValidateCheckInterval(const String& location, const Checkable::Ptr& object)
|
||||
void Checkable::ValidateCheckIntervalRaw(double value, const ValidationUtils& utils)
|
||||
{
|
||||
if (object->GetCheckInterval() <= 0) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": check_interval must be greater than 0.", object->GetDebugInfo()));
|
||||
}
|
||||
ObjectImpl<Checkable>::ValidateCheckIntervalRaw(value, utils);
|
||||
|
||||
if (value <= 0)
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("check_interval"), "Interval must be greater than 0."));
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ public:
|
||||
void RemoveReverseDependency(const intrusive_ptr<Dependency>& dep);
|
||||
std::set<intrusive_ptr<Dependency> > GetReverseDependencies(void) const;
|
||||
|
||||
static void ValidateCheckInterval(const String& location, const Checkable::Ptr& object);
|
||||
virtual void ValidateCheckIntervalRaw(double value, const ValidationUtils& utils) override;
|
||||
|
||||
protected:
|
||||
virtual void Start(void);
|
||||
|
@ -43,18 +43,18 @@ abstract class Checkable : CustomVarObject
|
||||
[config] Array::Ptr groups {
|
||||
default {{{ return new Array(); }}}
|
||||
};
|
||||
[config, protected] String check_command (CheckCommandRaw);
|
||||
[config, protected, required] name(CheckCommand) check_command (CheckCommandRaw);
|
||||
[config] int max_check_attempts (MaxCheckAttemptsRaw) {
|
||||
default {{{ return 3; }}}
|
||||
};
|
||||
[config, protected] String check_period (CheckPeriodRaw);
|
||||
[config, protected] name(TimePeriod) check_period (CheckPeriodRaw);
|
||||
[config] double check_interval (CheckIntervalRaw) {
|
||||
default {{{ return 5 * 60; }}}
|
||||
};
|
||||
[config] double retry_interval (RetryIntervalRaw) {
|
||||
default {{{ return 60; }}}
|
||||
};
|
||||
[config] String event_command (EventCommandRaw);
|
||||
[config] name(EventCommand) event_command (EventCommandRaw);
|
||||
[config] bool volatile;
|
||||
[config] double flapping_threshold {
|
||||
default {{{ return 30; }}}
|
||||
@ -147,7 +147,7 @@ abstract class Checkable : CustomVarObject
|
||||
[state] Value override_max_check_attempts;
|
||||
[state] Value override_check_period;
|
||||
|
||||
[config] String command_endpoint (CommandEndpointRaw);
|
||||
[config] name(Endpoint) command_endpoint (CommandEndpointRaw);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include "icinga/command.hpp"
|
||||
#include "icinga/macroprocessor.hpp"
|
||||
#include "base/function.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
@ -27,9 +26,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(Command);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateCommandAttributes, &Command::ValidateAttributes);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateCommandArguments, &Command::ValidateArguments);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateEnvironmentVariables, &Command::ValidateEnvironmentVariables);
|
||||
|
||||
int Command::GetModifiedAttributes(void) const
|
||||
{
|
||||
@ -49,81 +45,68 @@ void Command::SetModifiedAttributes(int flags, const MessageOrigin& origin)
|
||||
}
|
||||
}
|
||||
|
||||
void Command::ValidateAttributes(const String& location, const Command::Ptr& object)
|
||||
void Command::Validate(int types, const ValidationUtils& utils)
|
||||
{
|
||||
if (object->GetArguments() != Empty && !object->GetCommandLine().IsObjectType<Array>()) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Attribute 'command' must be an array if the 'arguments' attribute is set.", object->GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
ObjectImpl<Command>::Validate(types, utils);
|
||||
|
||||
void Command::ValidateArguments(const String& location, const Command::Ptr& object)
|
||||
{
|
||||
Dictionary::Ptr arguments = object->GetArguments();
|
||||
Dictionary::Ptr arguments = GetArguments();
|
||||
|
||||
if (!arguments)
|
||||
if (!(types & FAConfig))
|
||||
return;
|
||||
|
||||
ObjectLock olock(arguments);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, arguments) {
|
||||
const Value& arginfo = kv.second;
|
||||
Value argval;
|
||||
if (arguments) {
|
||||
if (!GetCommandLine().IsObjectType<Array>())
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("command"), "Attribute 'command' must be an array if the 'arguments' attribute is set."));
|
||||
|
||||
if (arginfo.IsObjectType<Dictionary>()) {
|
||||
Dictionary::Ptr argdict = arginfo;
|
||||
ObjectLock olock(arguments);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, arguments) {
|
||||
const Value& arginfo = kv.second;
|
||||
Value argval;
|
||||
|
||||
if (argdict->Contains("value")) {
|
||||
String argvalue = argdict->Get("value");
|
||||
if (arginfo.IsObjectType<Dictionary>()) {
|
||||
Dictionary::Ptr argdict = arginfo;
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(argvalue)) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + argvalue + "'.", object->GetDebugInfo()));
|
||||
if (argdict->Contains("value")) {
|
||||
String argvalue = argdict->Get("value");
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(argvalue))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of<String>("arguments")(kv.first)("value"), "Validation failed: Closing $ not found in macro format string '" + argvalue + "'."));
|
||||
}
|
||||
}
|
||||
|
||||
if (argdict->Contains("set_if")) {
|
||||
String argsetif = argdict->Get("set_if");
|
||||
if (argdict->Contains("set_if")) {
|
||||
String argsetif = argdict->Get("set_if");
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(argsetif)) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + argsetif + "'.", object->GetDebugInfo()));
|
||||
if (!MacroProcessor::ValidateMacroString(argsetif))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of<String>("arguments")(kv.first)("set_if"), "Closing $ not found in macro format string '" + argsetif + "'."));
|
||||
}
|
||||
}
|
||||
} else if (arginfo.IsObjectType<Function>()) {
|
||||
continue; /* we cannot evaluate macros in functions */
|
||||
} else {
|
||||
argval = arginfo;
|
||||
} else if (arginfo.IsObjectType<Function>()) {
|
||||
continue; /* we cannot evaluate macros in functions */
|
||||
} else {
|
||||
argval = arginfo;
|
||||
|
||||
if (argval.IsEmpty())
|
||||
if (argval.IsEmpty())
|
||||
continue;
|
||||
|
||||
String argstr = argval;
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(argstr))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of<String>("arguments")(kv.first), "Closing $ not found in macro format string '" + argstr + "'."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary::Ptr env = GetEnv();
|
||||
|
||||
if (env) {
|
||||
ObjectLock olock(env);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, env) {
|
||||
const Value& envval = kv.second;
|
||||
|
||||
if (!envval.IsString() || envval.IsEmpty())
|
||||
continue;
|
||||
|
||||
String argstr = argval;
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(argstr)) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + argstr + "'.", object->GetDebugInfo()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Command::ValidateEnvironmentVariables(const String& location, const Command::Ptr& object)
|
||||
{
|
||||
Dictionary::Ptr env = object->GetEnv();
|
||||
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
ObjectLock olock(env);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, env) {
|
||||
const Value& envval = kv.second;
|
||||
|
||||
if (!envval.IsString() || envval.IsEmpty())
|
||||
continue;
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(envval)) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + envval + "'.", object->GetDebugInfo()));
|
||||
if (!MacroProcessor::ValidateMacroString(envval))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of<String>("env")(kv.first), "Closing $ not found in macro format string '" + envval + "'."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,9 +39,7 @@ public:
|
||||
|
||||
//virtual Dictionary::Ptr Execute(const Object::Ptr& context) = 0;
|
||||
|
||||
static void ValidateAttributes(const String& location, const Command::Ptr& object);
|
||||
static void ValidateArguments(const String& location, const Command::Ptr& object);
|
||||
static void ValidateEnvironmentVariables(const String& location, const Command::Ptr& object);
|
||||
virtual void Validate(int types, const ValidationUtils& utils) override;
|
||||
|
||||
int GetModifiedAttributes(void) const;
|
||||
void SetModifiedAttributes(int flags, const MessageOrigin& origin = MessageOrigin());
|
||||
|
@ -27,11 +27,41 @@ abstract class Command : CustomVarObject
|
||||
{
|
||||
[config] Value command (CommandLine);
|
||||
[config] Value arguments;
|
||||
[config] Value timeout {
|
||||
[config] int timeout {
|
||||
default {{{ return 60; }}}
|
||||
};
|
||||
[config] Dictionary::Ptr env;
|
||||
[config] Function::Ptr execute;
|
||||
[config, required] Function::Ptr execute;
|
||||
};
|
||||
|
||||
validator Command {
|
||||
String command;
|
||||
Function command;
|
||||
Array command {
|
||||
String "*";
|
||||
Function "*";
|
||||
};
|
||||
|
||||
Dictionary arguments {
|
||||
String "*";
|
||||
Dictionary "*" {
|
||||
String key;
|
||||
String value;
|
||||
Function value;
|
||||
String description;
|
||||
Number "required";
|
||||
Number skip_key;
|
||||
Number repeat_key;
|
||||
String set_if;
|
||||
Function set_if;
|
||||
Number order;
|
||||
};
|
||||
};
|
||||
|
||||
Dictionary env {
|
||||
String "*";
|
||||
Function "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(CustomVarObject);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateCustomAttributes, &CustomVarObject::ValidateCustomAttributes);
|
||||
|
||||
boost::signals2::signal<void (const CustomVarObject::Ptr&, const Dictionary::Ptr& vars, const MessageOrigin&)> CustomVarObject::OnVarsChanged;
|
||||
|
||||
@ -68,16 +67,14 @@ bool CustomVarObject::IsVarOverridden(const String& name) const
|
||||
return vars_override->Contains(name);
|
||||
}
|
||||
|
||||
void CustomVarObject::ValidateCustomAttributes(const String& location, const CustomVarObject::Ptr& object)
|
||||
void CustomVarObject::ValidateVarsRaw(const Dictionary::Ptr& value, const ValidationUtils& utils)
|
||||
{
|
||||
Dictionary::Ptr vars = object->GetVars();
|
||||
|
||||
if (!vars)
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
/* string, array, dictionary */
|
||||
ObjectLock olock(vars);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, vars) {
|
||||
ObjectLock olock(value);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, value) {
|
||||
const Value& varval = kv.second;
|
||||
|
||||
if (varval.IsObjectType<Dictionary>()) {
|
||||
@ -89,10 +86,8 @@ void CustomVarObject::ValidateCustomAttributes(const String& location, const Cus
|
||||
if (kv_var.second.IsEmpty())
|
||||
continue;
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(kv_var.second)) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + kv_var.second + "'.", object->GetDebugInfo()));
|
||||
}
|
||||
if (!MacroProcessor::ValidateMacroString(kv_var.second))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of<String>("vars")(kv.first)(kv_var.first), "Closing $ not found in macro format string '" + kv_var.second + "'."));
|
||||
}
|
||||
} else if (varval.IsObjectType<Array>()) {
|
||||
/* check all array entries */
|
||||
@ -104,8 +99,7 @@ void CustomVarObject::ValidateCustomAttributes(const String& location, const Cus
|
||||
continue;
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(arrval)) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + arrval + "'.", object->GetDebugInfo()));
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of<String>("vars")(kv.first), "Closing $ not found in macro format string '" + arrval + "'."));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -114,10 +108,8 @@ void CustomVarObject::ValidateCustomAttributes(const String& location, const Cus
|
||||
|
||||
String varstr = varval;
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(varstr)) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + varstr + "'.", object->GetDebugInfo()));
|
||||
}
|
||||
if (!MacroProcessor::ValidateMacroString(varstr))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of<String>("vars")(kv.first), "Closing $ not found in macro format string '" + varstr + "'."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
|
||||
static boost::signals2::signal<void (const CustomVarObject::Ptr&, const Dictionary::Ptr& vars, const MessageOrigin&)> OnVarsChanged;
|
||||
|
||||
static void ValidateCustomAttributes(const String& location, const CustomVarObject::Ptr& object);
|
||||
virtual void ValidateVarsRaw(const Dictionary::Ptr& value, const ValidationUtils& utils) override;
|
||||
|
||||
Dictionary::Ptr GetVars(void) const;
|
||||
void SetVars(const Dictionary::Ptr& vars, const MessageOrigin& origin = MessageOrigin());
|
||||
|
@ -20,14 +20,12 @@
|
||||
#include "icinga/dependency.hpp"
|
||||
#include "icinga/service.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/function.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(Dependency);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateDependencyFilters, &Dependency::ValidateFilters);
|
||||
|
||||
String DependencyNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
|
||||
{
|
||||
@ -198,17 +196,15 @@ TimePeriod::Ptr Dependency::GetPeriod(void) const
|
||||
return TimePeriod::GetByName(GetPeriodRaw());
|
||||
}
|
||||
|
||||
void Dependency::ValidateFilters(const String& location, const Dependency::Ptr& object)
|
||||
void Dependency::ValidateStates(const Array::Ptr& value, const ValidationUtils& utils)
|
||||
{
|
||||
int sfilter = FilterArrayToInt(object->GetStates(), 0);
|
||||
ObjectImpl<Dependency>::ValidateStates(value, utils);
|
||||
|
||||
if (object->GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid for host dependency.", object->GetDebugInfo()));
|
||||
}
|
||||
int sfilter = FilterArrayToInt(value, 0);
|
||||
|
||||
if (!object->GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid for service dependency.", object->GetDebugInfo()));
|
||||
}
|
||||
if (GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0)
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("states"), "State filter is invalid for host dependency."));
|
||||
|
||||
if (!GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0)
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("states"), "State filter is invalid for service dependency."));
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
|
||||
static void RegisterApplyRuleHandler(void);
|
||||
|
||||
static void ValidateFilters(const String& location, const Dependency::Ptr& object);
|
||||
virtual void ValidateStates(const Array::Ptr& value, const ValidationUtils& utils) override;
|
||||
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);
|
||||
|
@ -36,13 +36,13 @@ class Dependency : CustomVarObject < DependencyNameComposer
|
||||
load_after Host;
|
||||
load_after Service;
|
||||
|
||||
[config] String child_host_name;
|
||||
[config, required] name(Host) child_host_name;
|
||||
[config] String child_service_name;
|
||||
|
||||
[config] String parent_host_name;
|
||||
[config, required] name(Host) parent_host_name;
|
||||
[config] String parent_service_name;
|
||||
|
||||
[config] String period (PeriodRaw);
|
||||
[config] name(TimePeriod) period (PeriodRaw);
|
||||
|
||||
[config] Array::Ptr states;
|
||||
int state_filter_real (StateFilter);
|
||||
@ -57,4 +57,10 @@ class Dependency : CustomVarObject < DependencyNameComposer
|
||||
};
|
||||
};
|
||||
|
||||
validator Dependency {
|
||||
Array states {
|
||||
Number "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "icinga/hostgroup.hpp"
|
||||
#include "icinga/pluginutility.hpp"
|
||||
#include "icinga/scheduleddowntime.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include "base/utility.hpp"
|
||||
|
@ -49,4 +49,10 @@ class Host : Checkable
|
||||
|
||||
};
|
||||
|
||||
validator Host {
|
||||
Array groups {
|
||||
name(HostGroup) "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -39,4 +39,10 @@ class HostGroup : CustomVarObject
|
||||
[config] String action_url;
|
||||
};
|
||||
|
||||
validator HostGroup {
|
||||
Array groups {
|
||||
name(HostGroup) "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,293 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type IcingaApplication {
|
||||
}
|
||||
|
||||
%type IcingaStatusWriter {
|
||||
%attribute %string "status_path",
|
||||
%attribute %number "update_interval"
|
||||
}
|
||||
|
||||
%type CustomVarObject {
|
||||
%validator "ValidateCustomAttributes",
|
||||
%attribute %dictionary "vars",
|
||||
}
|
||||
|
||||
%type Checkable %inherits CustomVarObject {
|
||||
%validator "ValidateCheckableCheckInterval",
|
||||
|
||||
%attribute %string "display_name",
|
||||
|
||||
%require "check_command",
|
||||
%attribute %name(CheckCommand) "check_command",
|
||||
%attribute %number "max_check_attempts",
|
||||
%attribute %name(TimePeriod) "check_period",
|
||||
%attribute %number "check_interval",
|
||||
%attribute %number "retry_interval",
|
||||
|
||||
%attribute %number "enable_notifications",
|
||||
%attribute %number "enable_active_checks",
|
||||
%attribute %number "enable_passive_checks",
|
||||
%attribute %number "enable_event_handler",
|
||||
|
||||
%attribute %name(EventCommand) "event_command",
|
||||
|
||||
%attribute %number "enable_flapping",
|
||||
%attribute %number "flapping_threshold",
|
||||
|
||||
%attribute %number "enable_perfdata",
|
||||
|
||||
%attribute %number "volatile",
|
||||
|
||||
%attribute %string "notes",
|
||||
%attribute %string "notes_url",
|
||||
%attribute %string "action_url",
|
||||
%attribute %string "icon_image",
|
||||
%attribute %string "icon_image_alt",
|
||||
|
||||
%attribute %name(Endpoint) "command_endpoint",
|
||||
}
|
||||
|
||||
%type Host %inherits Checkable {
|
||||
%attribute %string "display_name",
|
||||
%attribute %array "groups" {
|
||||
%attribute %name(HostGroup) "*"
|
||||
},
|
||||
|
||||
%attribute %string "address",
|
||||
%attribute %string "address6",
|
||||
}
|
||||
|
||||
%type HostGroup %inherits CustomVarObject {
|
||||
%attribute %string "display_name"
|
||||
|
||||
%attribute %array "groups" {
|
||||
%attribute %name(HostGroup) "*"
|
||||
},
|
||||
|
||||
%attribute %string "notes",
|
||||
%attribute %string "notes_url",
|
||||
%attribute %string "action_url",
|
||||
}
|
||||
|
||||
%type Service %inherits Checkable {
|
||||
%require "host_name",
|
||||
%attribute %name(Host) "host_name",
|
||||
|
||||
%attribute %string "name",
|
||||
|
||||
%attribute %array "groups" {
|
||||
%attribute %name(ServiceGroup) "*"
|
||||
},
|
||||
}
|
||||
|
||||
%type ServiceGroup %inherits CustomVarObject {
|
||||
%attribute %string "display_name"
|
||||
|
||||
%attribute %array "groups" {
|
||||
%attribute %name(ServiceGroup) "*"
|
||||
},
|
||||
|
||||
%attribute %string "notes",
|
||||
%attribute %string "notes_url",
|
||||
%attribute %string "action_url",
|
||||
}
|
||||
|
||||
%type Notification %inherits CustomVarObject {
|
||||
%validator "ValidateNotificationFilters"
|
||||
%validator "ValidateNotificationUsers"
|
||||
|
||||
%require "host_name",
|
||||
%attribute %name(Host) "host_name",
|
||||
%attribute %string "service_name",
|
||||
|
||||
%attribute %string "name",
|
||||
|
||||
%attribute %array "users" {
|
||||
%attribute %name(User) "*"
|
||||
},
|
||||
%attribute %array "user_groups" {
|
||||
%attribute %name(UserGroup) "*"
|
||||
},
|
||||
|
||||
%attribute %dictionary "times" {
|
||||
%attribute %number "begin",
|
||||
%attribute %number "end",
|
||||
},
|
||||
|
||||
%require "command",
|
||||
%attribute %name(NotificationCommand) "command",
|
||||
|
||||
%attribute %number "interval",
|
||||
%attribute %name(TimePeriod) "period",
|
||||
|
||||
%attribute %array "types" {
|
||||
%attribute %number "*"
|
||||
},
|
||||
%attribute %array "states" {
|
||||
%attribute %number "*"
|
||||
},
|
||||
|
||||
%attribute %name(Endpoint) "command_endpoint",
|
||||
}
|
||||
|
||||
%type User %inherits CustomVarObject {
|
||||
%validator "ValidateUserFilters"
|
||||
|
||||
%attribute %string "display_name",
|
||||
|
||||
%attribute %array "groups" {
|
||||
%attribute %name(UserGroup) "*"
|
||||
},
|
||||
|
||||
%attribute %number "enable_notifications",
|
||||
%attribute %array "types" {
|
||||
%attribute %number "*"
|
||||
},
|
||||
%attribute %array "states" {
|
||||
%attribute %number "*"
|
||||
},
|
||||
%attribute %name(TimePeriod) "period",
|
||||
|
||||
%attribute %string "email",
|
||||
%attribute %string "pager",
|
||||
}
|
||||
|
||||
%type UserGroup %inherits CustomVarObject {
|
||||
%attribute %string "display_name",
|
||||
|
||||
%attribute %array "groups" {
|
||||
%attribute %name(UserGroup) "*"
|
||||
},
|
||||
}
|
||||
|
||||
%type TimePeriod %inherits CustomVarObject {
|
||||
%validator "ValidateTimePeriodRanges",
|
||||
|
||||
%attribute %string "display_name",
|
||||
|
||||
%require "update",
|
||||
%attribute %function "update",
|
||||
|
||||
/* %if (methods.update == "LegacyTimePeriod") { */
|
||||
// %require "ranges",
|
||||
%attribute %dictionary "ranges" {
|
||||
%attribute %string "*"
|
||||
}
|
||||
/* } */
|
||||
}
|
||||
|
||||
%type Command %inherits CustomVarObject {
|
||||
%validator "ValidateCommandAttributes",
|
||||
%validator "ValidateCommandArguments",
|
||||
%validator "ValidateEnvironmentVariables",
|
||||
|
||||
%require "execute",
|
||||
%attribute %function "execute",
|
||||
|
||||
/* %if (methods.execute == "PluginNotification" || methods.execute == "PluginCheck" || methods.execute == "PluginEvent") { */
|
||||
// %require "command",
|
||||
%attribute %string "command",
|
||||
%attribute %function "command",
|
||||
%attribute %array "command" {
|
||||
%attribute %string "*"
|
||||
%attribute %function "*",
|
||||
},
|
||||
%attribute %dictionary "arguments" {
|
||||
%attribute %string "*",
|
||||
%attribute %dictionary "*" {
|
||||
%attribute %string "key"
|
||||
%attribute %string "value"
|
||||
%attribute %function "value"
|
||||
%attribute %string "description"
|
||||
%attribute %number "required"
|
||||
%attribute %number "skip_key"
|
||||
%attribute %number "repeat_key"
|
||||
%attribute %string "set_if"
|
||||
%attribute %function "set_if"
|
||||
%attribute %number "order"
|
||||
}
|
||||
},
|
||||
%attribute %dictionary "env" {
|
||||
%attribute %string "*"
|
||||
%attribute %function "*"
|
||||
},
|
||||
%attribute %number "timeout"
|
||||
/* } */
|
||||
}
|
||||
|
||||
%type CheckCommand %inherits Command {
|
||||
|
||||
}
|
||||
|
||||
%type NotificationCommand %inherits Command {
|
||||
|
||||
}
|
||||
|
||||
%type EventCommand %inherits Command {
|
||||
|
||||
}
|
||||
|
||||
%type ScheduledDowntime %inherits CustomVarObject {
|
||||
%validator "ValidateScheduledDowntimeRanges",
|
||||
|
||||
%require "host_name",
|
||||
%attribute %name(Host) "host_name",
|
||||
%attribute %string "service_name",
|
||||
|
||||
%attribute %string "name",
|
||||
|
||||
%require "author",
|
||||
%attribute %string "author",
|
||||
|
||||
%require "comment",
|
||||
%attribute %string "comment",
|
||||
|
||||
%attribute %number "duration",
|
||||
%attribute %number "fixed",
|
||||
|
||||
%require "ranges",
|
||||
%attribute %dictionary "ranges" {
|
||||
%attribute %string "*"
|
||||
},
|
||||
}
|
||||
|
||||
%type Dependency %inherits CustomVarObject {
|
||||
%validator "ValidateDependencyFilters"
|
||||
|
||||
%require "parent_host_name",
|
||||
%attribute %name(Host) "parent_host_name",
|
||||
%attribute %string "parent_service_name",
|
||||
|
||||
%require "child_host_name",
|
||||
%attribute %name(Host) "child_host_name",
|
||||
%attribute %string "child_service_name",
|
||||
|
||||
%attribute %string "name",
|
||||
|
||||
%attribute %name(TimePeriod) "period",
|
||||
|
||||
%attribute %array "states" {
|
||||
%attribute %number "*"
|
||||
},
|
||||
%attribute %number "ignore_soft_states",
|
||||
%attribute %number "disable_checks",
|
||||
%attribute %number "disable_notifications"
|
||||
}
|
@ -27,14 +27,11 @@
|
||||
#include "base/exception.hpp"
|
||||
#include "base/initialize.hpp"
|
||||
#include "base/scriptglobal.hpp"
|
||||
#include "base/function.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(Notification);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateNotificationFilters, &Notification::ValidateFilters);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateNotificationUsers, &Notification::ValidateUsers);
|
||||
INITIALIZE_ONCE(&Notification::StaticInitialize);
|
||||
|
||||
boost::signals2::signal<void (const Notification::Ptr&, double, const MessageOrigin&)> Notification::OnNextNotificationChanged;
|
||||
@ -256,8 +253,8 @@ void Notification::BeginExecuteNotification(NotificationType type, const CheckRe
|
||||
<< "Not sending notifications for notification object '" << GetName() << "': before escalation range";
|
||||
|
||||
/* we need to adjust the next notification time
|
||||
* to now + begin delaying the first notification
|
||||
*/
|
||||
* to now + begin delaying the first notification
|
||||
*/
|
||||
double nextProposedNotification = now + times->Get("begin") + 1.0;
|
||||
if (GetNextNotification() > nextProposedNotification)
|
||||
SetNextNotification(nextProposedNotification);
|
||||
@ -628,43 +625,46 @@ String Notification::NotificationHostStateToString(HostState state)
|
||||
}
|
||||
}
|
||||
|
||||
void Notification::ValidateUsers(const String& location, const Notification::Ptr& object)
|
||||
void Notification::Validate(int types, const ValidationUtils& utils)
|
||||
{
|
||||
Array::Ptr users = object->GetUsersRaw();
|
||||
Array::Ptr groups = object->GetUserGroupsRaw();
|
||||
ObjectImpl<Notification>::Validate(types, utils);
|
||||
|
||||
if ((!users || users->GetLength() == 0) && (!groups || groups->GetLength() == 0)) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": No users/user_groups specified.", object->GetDebugInfo()));
|
||||
}
|
||||
if (!(types & FAConfig))
|
||||
return;
|
||||
|
||||
Array::Ptr users = GetUsersRaw();
|
||||
Array::Ptr groups = GetUserGroupsRaw();
|
||||
|
||||
if ((!users || users->GetLength() == 0) && (!groups || groups->GetLength() == 0))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, std::vector<String>(), "Validation failed: No users/user_groups specified."));
|
||||
}
|
||||
|
||||
void Notification::ValidateFilters(const String& location, const Notification::Ptr& object)
|
||||
void Notification::ValidateStates(const Array::Ptr& value, const ValidationUtils& utils)
|
||||
{
|
||||
int sfilter = FilterArrayToInt(object->GetStates(), 0);
|
||||
ObjectImpl<Notification>::ValidateStates(value, utils);
|
||||
|
||||
if (object->GetServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid.", object->GetDebugInfo()));
|
||||
}
|
||||
int sfilter = FilterArrayToInt(value, 0);
|
||||
|
||||
if (!object->GetServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid.", object->GetDebugInfo()));
|
||||
}
|
||||
if (GetServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0)
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("states"), "State filter is invalid."));
|
||||
|
||||
int tfilter = FilterArrayToInt(object->GetTypes(), 0);
|
||||
if (!GetServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0)
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("types"), "State filter is invalid."));
|
||||
}
|
||||
|
||||
void Notification::ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils)
|
||||
{
|
||||
ObjectImpl<Notification>::ValidateTypes(value, utils);
|
||||
|
||||
int tfilter = FilterArrayToInt(value, 0);
|
||||
|
||||
if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
|
||||
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
|
||||
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Type filter is invalid.", object->GetDebugInfo()));
|
||||
}
|
||||
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0)
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("types"), "Type filter is invalid."));
|
||||
}
|
||||
|
||||
Endpoint::Ptr Notification::GetCommandEndpoint(void) const
|
||||
{
|
||||
return Endpoint::GetByName(GetCommandEndpointRaw());
|
||||
}
|
||||
|
||||
|
@ -110,8 +110,10 @@ public:
|
||||
|
||||
static void RegisterApplyRuleHandler(void);
|
||||
|
||||
static void ValidateUsers(const String& location, const Notification::Ptr& object);
|
||||
static void ValidateFilters(const String& location, const Notification::Ptr& object);
|
||||
virtual void Validate(int types, const ValidationUtils& utils) override;
|
||||
|
||||
virtual void ValidateStates(const Array::Ptr& value, const ValidationUtils& utils) override;
|
||||
virtual void ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils) override;
|
||||
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);
|
||||
|
@ -35,11 +35,11 @@ class Notification : CustomVarObject < NotificationNameComposer
|
||||
load_after Host;
|
||||
load_after Service;
|
||||
|
||||
[config, protected] String command (CommandRaw);
|
||||
[config, protected, required] name(NotificationCommand) command (CommandRaw);
|
||||
[config] double interval {
|
||||
default {{{ return 1800; }}}
|
||||
};
|
||||
[config] String period (PeriodRaw);
|
||||
[config] name(TimePeriod) period (PeriodRaw);
|
||||
[config, protected] Array::Ptr users (UsersRaw);
|
||||
[config, protected] Array::Ptr user_groups (UserGroupsRaw);
|
||||
[config] Dictionary::Ptr times;
|
||||
@ -47,7 +47,7 @@ class Notification : CustomVarObject < NotificationNameComposer
|
||||
int type_filter_real (TypeFilter);
|
||||
[config] Array::Ptr states;
|
||||
int state_filter_real (StateFilter);
|
||||
[config, protected] String host_name;
|
||||
[config, protected, required] name(Host) host_name;
|
||||
[config, protected] String service_name;
|
||||
|
||||
[state] Array::Ptr notified_users {
|
||||
@ -59,7 +59,30 @@ class Notification : CustomVarObject < NotificationNameComposer
|
||||
[state, set_protected] Value notification_number;
|
||||
[state] double last_problem_notification;
|
||||
|
||||
[config] String command_endpoint (CommandEndpointRaw);
|
||||
[config] name(Endpoint) command_endpoint (CommandEndpointRaw);
|
||||
};
|
||||
|
||||
validator Notification {
|
||||
Array users {
|
||||
name(User) "*";
|
||||
};
|
||||
|
||||
Array user_groups {
|
||||
name(UserGroup) "*";
|
||||
};
|
||||
|
||||
Dictionary times {
|
||||
Number begin;
|
||||
Number end;
|
||||
};
|
||||
|
||||
Array types {
|
||||
Number "*";
|
||||
};
|
||||
|
||||
Array states {
|
||||
Number "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(ScheduledDowntime);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateScheduledDowntimeRanges, &ScheduledDowntime::ValidateRanges);
|
||||
|
||||
INITIALIZE_ONCE(&ScheduledDowntime::StaticInitialize);
|
||||
|
||||
@ -181,11 +180,9 @@ void ScheduledDowntime::CreateNextDowntime(void)
|
||||
downtime->SetConfigOwner(GetName());
|
||||
}
|
||||
|
||||
void ScheduledDowntime::ValidateRanges(const String& location, const ScheduledDowntime::Ptr& object)
|
||||
void ScheduledDowntime::ValidateRanges(const Dictionary::Ptr& value, const ValidationUtils& utils)
|
||||
{
|
||||
Dictionary::Ptr ranges = object->GetRanges();
|
||||
|
||||
if (!ranges)
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
/* create a fake time environment to validate the definitions */
|
||||
@ -193,22 +190,20 @@ void ScheduledDowntime::ValidateRanges(const String& location, const ScheduledDo
|
||||
tm reference = Utility::LocalTime(refts);
|
||||
Array::Ptr segments = new Array();
|
||||
|
||||
ObjectLock olock(ranges);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, ranges) {
|
||||
ObjectLock olock(value);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, value) {
|
||||
try {
|
||||
tm begin_tm, end_tm;
|
||||
int stride;
|
||||
LegacyTimePeriod::ParseTimeRange(kv.first, &begin_tm, &end_tm, &stride, &reference);
|
||||
} catch (std::exception&) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Invalid time specification.", object->GetDebugInfo()));
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("ranges"), "Invalid time specification: " + kv.first));
|
||||
}
|
||||
|
||||
try {
|
||||
LegacyTimePeriod::ProcessTimeRanges(kv.second, &reference, segments);
|
||||
} catch (std::exception&) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Invalid time range definition.", object->GetDebugInfo()));
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("ranges"), "Invalid time range definition: " + kv.first));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);
|
||||
|
||||
static void ValidateRanges(const String& location, const ScheduledDowntime::Ptr& object);
|
||||
virtual void ValidateRanges(const Dictionary::Ptr& value, const ValidationUtils& utils) override;
|
||||
|
||||
protected:
|
||||
virtual void OnAllConfigLoaded(void);
|
||||
|
@ -35,18 +35,24 @@ class ScheduledDowntime : CustomVarObject < ScheduledDowntimeNameComposer
|
||||
load_after Host;
|
||||
load_after Service;
|
||||
|
||||
[config, protected] String host_name;
|
||||
[config, protected, required] name(Host) host_name;
|
||||
[config, protected] String service_name;
|
||||
|
||||
[config] String author;
|
||||
[config] String comment;
|
||||
[config, required] String author;
|
||||
[config, required] String comment;
|
||||
|
||||
[config] double duration;
|
||||
[config] bool fixed {
|
||||
default {{{ return true; }}}
|
||||
};
|
||||
|
||||
[config] Dictionary::Ptr ranges;
|
||||
[config, required] Dictionary::Ptr ranges;
|
||||
};
|
||||
|
||||
validator ScheduledDowntime {
|
||||
Dictionary ranges {
|
||||
String "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class Service : Checkable < ServiceNameComposer
|
||||
return m_DisplayName;
|
||||
}}}
|
||||
};
|
||||
[config] String host_name;
|
||||
[config, required] name(Host) host_name;
|
||||
[enum, no_storage] ServiceState "state" {
|
||||
get {{{
|
||||
return GetStateRaw();
|
||||
@ -63,4 +63,10 @@ class Service : Checkable < ServiceNameComposer
|
||||
};
|
||||
};
|
||||
|
||||
validator Service {
|
||||
Array groups {
|
||||
name(ServiceGroup) "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -39,4 +39,10 @@ class ServiceGroup : CustomVarObject
|
||||
[config] String action_url;
|
||||
};
|
||||
|
||||
validator ServiceGroup {
|
||||
Array groups {
|
||||
name(ServiceGroup) "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -30,7 +30,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(TimePeriod);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateTimePeriodRanges, &TimePeriod::ValidateRanges);
|
||||
|
||||
static Timer::Ptr l_UpdateTimer;
|
||||
|
||||
@ -306,11 +305,9 @@ void TimePeriod::Dump(void)
|
||||
Log(LogDebug, "TimePeriod", "---");
|
||||
}
|
||||
|
||||
void TimePeriod::ValidateRanges(const String& location, const TimePeriod::Ptr& object)
|
||||
void TimePeriod::ValidateRanges(const Dictionary::Ptr& value, const ValidationUtils& utils)
|
||||
{
|
||||
Dictionary::Ptr ranges = object->GetRanges();
|
||||
|
||||
if (!ranges)
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
/* create a fake time environment to validate the definitions */
|
||||
@ -318,22 +315,20 @@ void TimePeriod::ValidateRanges(const String& location, const TimePeriod::Ptr& o
|
||||
tm reference = Utility::LocalTime(refts);
|
||||
Array::Ptr segments = new Array();
|
||||
|
||||
ObjectLock olock(ranges);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, ranges) {
|
||||
ObjectLock olock(value);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, value) {
|
||||
try {
|
||||
tm begin_tm, end_tm;
|
||||
int stride;
|
||||
LegacyTimePeriod::ParseTimeRange(kv.first, &begin_tm, &end_tm, &stride, &reference);
|
||||
} catch (std::exception&) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Invalid time specification.", object->GetDebugInfo()));
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("ranges"), "Invalid time specification: " + kv.first));
|
||||
}
|
||||
|
||||
try {
|
||||
LegacyTimePeriod::ProcessTimeRanges(kv.second, &reference, segments);
|
||||
} catch (std::exception&) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Invalid time range definition.", object->GetDebugInfo()));
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("ranges"), "Invalid time range definition: " + kv.second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
bool IsInside(double ts) const;
|
||||
double FindNextTransition(double begin);
|
||||
|
||||
static void ValidateRanges(const String& location, const TimePeriod::Ptr& object);
|
||||
virtual void ValidateRanges(const Dictionary::Ptr& value, const ValidationUtils& utils) override;
|
||||
|
||||
private:
|
||||
void AddSegment(double s, double end);
|
||||
|
@ -34,7 +34,7 @@ class TimePeriod : CustomVarObject
|
||||
}}}
|
||||
};
|
||||
[config] Dictionary::Ptr ranges;
|
||||
[config] Function::Ptr update;
|
||||
[config, required] Function::Ptr update;
|
||||
[state] Value valid_begin;
|
||||
[state] Value valid_end;
|
||||
[state] Array::Ptr segments;
|
||||
@ -43,4 +43,10 @@ class TimePeriod : CustomVarObject
|
||||
};
|
||||
};
|
||||
|
||||
validator TimePeriod {
|
||||
Dictionary ranges {
|
||||
String "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "icinga/usergroup.hpp"
|
||||
#include "icinga/notification.hpp"
|
||||
#include "icinga/usergroup.hpp"
|
||||
#include "base/function.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
@ -29,7 +28,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(User);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateUserFilters, &User::ValidateFilters);
|
||||
|
||||
boost::signals2::signal<void (const User::Ptr&, bool, const MessageOrigin&)> User::OnEnableNotificationsChanged;
|
||||
|
||||
@ -101,22 +99,25 @@ TimePeriod::Ptr User::GetPeriod(void) const
|
||||
return TimePeriod::GetByName(GetPeriodRaw());
|
||||
}
|
||||
|
||||
void User::ValidateFilters(const String& location, const User::Ptr& object)
|
||||
void User::ValidateStates(const Array::Ptr& value, const ValidationUtils& utils)
|
||||
{
|
||||
int sfilter = FilterArrayToInt(object->GetStates(), 0);
|
||||
ObjectImpl<User>::ValidateStates(value, utils);
|
||||
|
||||
int sfilter = FilterArrayToInt(value, 0);
|
||||
|
||||
if ((sfilter & ~(StateFilterUp | StateFilterDown | StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": State filter is invalid.", object->GetDebugInfo()));
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("states"), "State filter is invalid."));
|
||||
}
|
||||
}
|
||||
|
||||
int tfilter = FilterArrayToInt(object->GetTypes(), 0);
|
||||
void User::ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils)
|
||||
{
|
||||
int tfilter = FilterArrayToInt(value, 0);
|
||||
|
||||
if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
|
||||
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
|
||||
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Type filter is invalid.", object->GetDebugInfo()));
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("types"), "Type filter is invalid."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,8 @@ public:
|
||||
/* Notifications */
|
||||
TimePeriod::Ptr GetPeriod(void) const;
|
||||
|
||||
static void ValidateFilters(const String& location, const User::Ptr& attrs);
|
||||
virtual void ValidateStates(const Array::Ptr& value, const ValidationUtils& utils) override;
|
||||
virtual void ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils) override;
|
||||
|
||||
bool GetEnableNotifications(void) const;
|
||||
void SetEnableNotifications(bool enabled, const MessageOrigin& origin = MessageOrigin());
|
||||
|
@ -36,7 +36,7 @@ class User : CustomVarObject
|
||||
[config] Array::Ptr groups {
|
||||
default {{{ return new Array(); }}}
|
||||
};
|
||||
[config] String period (PeriodRaw);
|
||||
[config] name(TimePeriod) period (PeriodRaw);
|
||||
[config] Array::Ptr types;
|
||||
int type_filter_real (TypeFilter);
|
||||
[config] Array::Ptr states;
|
||||
@ -53,4 +53,18 @@ class User : CustomVarObject
|
||||
[state] double last_notification;
|
||||
};
|
||||
|
||||
validator User {
|
||||
Array groups {
|
||||
name(UserGroup) "*";
|
||||
};
|
||||
|
||||
Array types {
|
||||
Number "*";
|
||||
};
|
||||
|
||||
Array states {
|
||||
Number "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -36,4 +36,10 @@ class UserGroup : CustomVarObject
|
||||
[config] Array::Ptr groups;
|
||||
};
|
||||
|
||||
validator UserGroup {
|
||||
Array groups {
|
||||
name(UserGroup) "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,8 +17,6 @@
|
||||
|
||||
mkclass_target(livestatuslistener.ti livestatuslistener.thpp)
|
||||
|
||||
mkembedconfig_target(livestatus-type.conf livestatus-type.cpp)
|
||||
|
||||
set(livestatus_SOURCES
|
||||
aggregator.cpp andfilter.cpp attributefilter.cpp
|
||||
avgaggregator.cpp column.cpp combinerfilter.cpp commandstable.cpp
|
||||
@ -30,7 +28,7 @@ set(livestatus_SOURCES
|
||||
minaggregator.cpp negatefilter.cpp orfilter.cpp
|
||||
servicegroupstable.cpp servicestable.cpp statehisttable.cpp
|
||||
statustable.cpp stdaggregator.cpp sumaggregator.cpp table.cpp
|
||||
timeperiodstable.cpp livestatus-type.cpp
|
||||
timeperiodstable.cpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -1,30 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type LivestatusListener {
|
||||
%validator "ValidateSocketType",
|
||||
|
||||
%attribute %string "socket_type",
|
||||
|
||||
%attribute %string "socket_path",
|
||||
%attribute %string "bind_host",
|
||||
%attribute %string "bind_port",
|
||||
|
||||
%attribute %string "compat_log_path",
|
||||
}
|
@ -35,7 +35,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(LivestatusListener);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateSocketType, &LivestatusListener::ValidateSocketType);
|
||||
|
||||
static int l_ClientsConnected = 0;
|
||||
static int l_Connections = 0;
|
||||
@ -213,12 +212,10 @@ void LivestatusListener::ClientHandler(const Socket::Ptr& client)
|
||||
}
|
||||
|
||||
|
||||
void LivestatusListener::ValidateSocketType(const String& location, const LivestatusListener::Ptr& object)
|
||||
void LivestatusListener::ValidateSocketType(const String& value, const ValidationUtils& utils)
|
||||
{
|
||||
String socket_type = object->GetSocketType();
|
||||
ObjectImpl<LivestatusListener>::ValidateSocketType(value, utils);
|
||||
|
||||
if (socket_type != "unix" && socket_type != "tcp") {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Socket type '" + socket_type + "' is invalid.", object->GetDebugInfo()));
|
||||
}
|
||||
if (value != "unix" && value != "tcp")
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("socket_type"), "Socket type '" + value + "' is invalid."));
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
static int GetClientsConnected(void);
|
||||
static int GetConnections(void);
|
||||
|
||||
static void ValidateSocketType(const String& location, const LivestatusListener::Ptr& object);
|
||||
virtual void ValidateSocketType(const String& value, const ValidationUtils& utils) override;
|
||||
|
||||
protected:
|
||||
virtual void Start(void);
|
||||
|
@ -17,10 +17,8 @@
|
||||
|
||||
mkclass_target(notificationcomponent.ti notificationcomponent.thpp)
|
||||
|
||||
mkembedconfig_target(notification-type.conf notification-type.cpp)
|
||||
|
||||
set(notification_SOURCES
|
||||
notificationcomponent.cpp notificationcomponent.thpp notification-type.cpp
|
||||
notificationcomponent.cpp notificationcomponent.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -1,22 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type NotificationComponent {
|
||||
%attribute %number "enable_ha"
|
||||
}
|
@ -20,10 +20,8 @@ mkclass_target(graphitewriter.ti graphitewriter.thpp)
|
||||
mkclass_target(opentsdbwriter.ti opentsdbwriter.thpp)
|
||||
mkclass_target(perfdatawriter.ti perfdatawriter.thpp)
|
||||
|
||||
mkembedconfig_target(perfdata-type.conf perfdata-type.cpp)
|
||||
|
||||
set(perfdata_SOURCES
|
||||
gelfwriter.cpp gelfwriter.thpp graphitewriter.cpp graphitewriter.thpp opentsdbwriter.cpp opentsdbwriter.thpp perfdatawriter.cpp perfdatawriter.thpp perfdata-type.cpp
|
||||
gelfwriter.cpp gelfwriter.thpp graphitewriter.cpp graphitewriter.thpp opentsdbwriter.cpp opentsdbwriter.thpp perfdatawriter.cpp perfdatawriter.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -43,7 +43,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(GraphiteWriter);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateNameTemplates, &GraphiteWriter::ValidateNameTemplates);
|
||||
|
||||
REGISTER_STATSFUNCTION(GraphiteWriterStats, &GraphiteWriter::StatsFunc);
|
||||
|
||||
@ -232,15 +231,18 @@ Value GraphiteWriter::EscapeMacroMetric(const Value& value)
|
||||
return EscapeMetric(value);
|
||||
}
|
||||
|
||||
void GraphiteWriter::ValidateNameTemplates(const String& location, const GraphiteWriter::Ptr& object)
|
||||
void GraphiteWriter::ValidateHostNameTemplate(const String& value, const ValidationUtils& utils)
|
||||
{
|
||||
if (!MacroProcessor::ValidateMacroString(object->GetHostNameTemplate())) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + object->GetHostNameTemplate() + "'.", object->GetDebugInfo()));
|
||||
}
|
||||
ObjectImpl<GraphiteWriter>::ValidateHostNameTemplate(value, utils);
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(object->GetServiceNameTemplate())) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + object->GetServiceNameTemplate() + "'.", object->GetDebugInfo()));
|
||||
}
|
||||
if (!MacroProcessor::ValidateMacroString(value))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("host_name_template"), "Closing $ not found in macro format string '" + value + "'."));
|
||||
}
|
||||
|
||||
void GraphiteWriter::ValidateServiceNameTemplate(const String& value, const ValidationUtils& utils)
|
||||
{
|
||||
ObjectImpl<GraphiteWriter>::ValidateServiceNameTemplate(value, utils);
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(value))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("service_name_template"), "Closing $ not found in macro format string '" + value + "'."));
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ public:
|
||||
|
||||
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
|
||||
|
||||
static void ValidateNameTemplates(const String& location, const GraphiteWriter::Ptr& object);
|
||||
virtual void ValidateHostNameTemplate(const String& value, const ValidationUtils& utils) override;
|
||||
virtual void ValidateServiceNameTemplate(const String& value, const ValidationUtils& utils) override;
|
||||
|
||||
protected:
|
||||
virtual void Start(void);
|
||||
|
@ -1,50 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type PerfdataWriter {
|
||||
%validator "ValidateFormatTemplates",
|
||||
|
||||
%attribute %string "host_perfdata_path",
|
||||
%attribute %string "service_perfdata_path",
|
||||
%attribute %string "host_temp_path",
|
||||
%attribute %string "service_temp_path",
|
||||
%attribute %string "host_format_template",
|
||||
%attribute %string "service_format_template",
|
||||
%attribute %number "rotation_interval"
|
||||
}
|
||||
|
||||
%type GraphiteWriter {
|
||||
%validator "ValidateNameTemplates",
|
||||
|
||||
%attribute %string "host",
|
||||
%attribute %string "port",
|
||||
%attribute %string "host_name_template",
|
||||
%attribute %string "service_name_template"
|
||||
}
|
||||
|
||||
%type GelfWriter {
|
||||
%attribute %string "host",
|
||||
%attribute %string "port",
|
||||
%attribute %string "source"
|
||||
}
|
||||
|
||||
%type OpenTsdbWriter {
|
||||
%attribute %string "host",
|
||||
%attribute %string "port",
|
||||
}
|
@ -34,7 +34,6 @@
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(PerfdataWriter);
|
||||
REGISTER_SCRIPTFUNCTION(ValidateFormatTemplates, &PerfdataWriter::ValidateFormatTemplates);
|
||||
|
||||
REGISTER_STATSFUNCTION(PerfdataWriterStats, &PerfdataWriter::StatsFunc);
|
||||
|
||||
@ -140,15 +139,18 @@ void PerfdataWriter::RotationTimerHandler(void)
|
||||
RotateFile(m_HostOutputFile, GetHostTempPath(), GetHostPerfdataPath());
|
||||
}
|
||||
|
||||
void PerfdataWriter::ValidateFormatTemplates(const String& location, const PerfdataWriter::Ptr& object)
|
||||
void PerfdataWriter::ValidateHostFormatTemplate(const String& value, const ValidationUtils& utils)
|
||||
{
|
||||
if (!MacroProcessor::ValidateMacroString(object->GetHostFormatTemplate())) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + object->GetHostFormatTemplate() + "'.", object->GetDebugInfo()));
|
||||
}
|
||||
ObjectImpl<PerfdataWriter>::ValidateHostFormatTemplate(value, utils);
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(object->GetServiceFormatTemplate())) {
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||
location + ": Closing $ not found in macro format string '" + object->GetHostFormatTemplate() + "'.", object->GetDebugInfo()));
|
||||
}
|
||||
if (!MacroProcessor::ValidateMacroString(value))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("host_format_template"), "Closing $ not found in macro format string '" + value + "'."));
|
||||
}
|
||||
|
||||
void PerfdataWriter::ValidateServiceFormatTemplate(const String& value, const ValidationUtils& utils)
|
||||
{
|
||||
ObjectImpl<PerfdataWriter>::ValidateServiceFormatTemplate(value, utils);
|
||||
|
||||
if (!MacroProcessor::ValidateMacroString(value))
|
||||
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("service_format_template"), "Closing $ not found in macro format string '" + value + "'."));
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ public:
|
||||
|
||||
static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
|
||||
|
||||
static void ValidateFormatTemplates(const String& location, const PerfdataWriter::Ptr& object);
|
||||
virtual void ValidateHostFormatTemplate(const String& value, const ValidationUtils& utils) override;
|
||||
virtual void ValidateServiceFormatTemplate(const String& value, const ValidationUtils& utils) override;
|
||||
|
||||
protected:
|
||||
virtual void Start(void);
|
||||
|
@ -19,12 +19,10 @@ mkclass_target(apilistener.ti apilistener.thpp)
|
||||
mkclass_target(endpoint.ti endpoint.thpp)
|
||||
mkclass_target(zone.ti zone.thpp)
|
||||
|
||||
mkembedconfig_target(remote-type.conf remote-type.cpp)
|
||||
|
||||
set(remote_SOURCES
|
||||
apiclient.cpp apiclient-heartbeat.cpp apifunction.cpp apilistener.cpp apilistener-sync.cpp
|
||||
apilistener.thpp authority.cpp endpoint.cpp endpoint.thpp jsonrpc.cpp
|
||||
messageorigin.cpp remote-type.cpp zone.cpp zone.thpp
|
||||
messageorigin.cpp zone.cpp zone.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
|
@ -25,9 +25,9 @@ namespace icinga
|
||||
|
||||
class ApiListener : DynamicObject
|
||||
{
|
||||
[config] String cert_path;
|
||||
[config] String key_path;
|
||||
[config] String ca_path;
|
||||
[config, required] String cert_path;
|
||||
[config, required] String key_path;
|
||||
[config, required] String ca_path;
|
||||
[config] String crl_path;
|
||||
|
||||
[config] String bind_host;
|
||||
|
@ -1,56 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
%type ApiListener {
|
||||
%require "cert_path",
|
||||
%attribute %string "cert_path",
|
||||
|
||||
%require "key_path",
|
||||
%attribute %string "key_path",
|
||||
|
||||
%require "ca_path",
|
||||
%attribute %string "ca_path",
|
||||
|
||||
%attribute %string "crl_path",
|
||||
|
||||
%attribute %string "bind_host",
|
||||
%attribute %string "bind_port",
|
||||
|
||||
%attribute %number "accept_config",
|
||||
%attribute %number "accept_commands",
|
||||
|
||||
%attribute %string "ticket_salt"
|
||||
}
|
||||
|
||||
%type Endpoint {
|
||||
%attribute %string "host",
|
||||
%attribute %string "port",
|
||||
|
||||
%attribute %number "log_duration"
|
||||
}
|
||||
|
||||
%type Zone {
|
||||
%attribute %name(Zone) "parent",
|
||||
|
||||
%attribute %array "endpoints" {
|
||||
%attribute %name(Endpoint) "*"
|
||||
},
|
||||
|
||||
%attribute %number "global"
|
||||
}
|
@ -24,9 +24,15 @@ namespace icinga
|
||||
|
||||
class Zone : DynamicObject
|
||||
{
|
||||
[config] String parent (ParentRaw);
|
||||
[config] name(Zone) parent (ParentRaw);
|
||||
[config] Array::Ptr endpoints (EndpointsRaw);
|
||||
[config] bool global;
|
||||
};
|
||||
|
||||
validator Zone {
|
||||
Array endpoints {
|
||||
name(Endpoint) "*";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
@ -18,13 +18,9 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "livestatus/livestatusquery.hpp"
|
||||
#include "config/configtype.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "base/application.hpp"
|
||||
#include "base/debug.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/console.hpp"
|
||||
#include "base/serializer.hpp"
|
||||
#include "base/stdiostream.hpp"
|
||||
#include "base/json.hpp"
|
||||
#include "base/loader.hpp"
|
||||
@ -32,7 +28,6 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
struct GlobalConfigFixture {
|
||||
|
@ -143,6 +143,9 @@ set_protected { yylval->num = FASetProtected; return T_FIELD_ATTRIBUTE; }
|
||||
protected { yylval->num = FAGetProtected | FASetProtected; return T_FIELD_ATTRIBUTE; }
|
||||
internal { yylval->num = FAInternal; return T_FIELD_ATTRIBUTE; }
|
||||
no_storage { yylval->num = FANoStorage; return T_FIELD_ATTRIBUTE; }
|
||||
validator { return T_VALIDATOR; }
|
||||
required { return T_REQUIRED; }
|
||||
name { return T_NAME; }
|
||||
default { yylval->num = FTDefault; return T_FIELD_ACCESSOR_TYPE; }
|
||||
get { yylval->num = FTGet; return T_FIELD_ACCESSOR_TYPE; }
|
||||
set { yylval->num = FTSet; return T_FIELD_ACCESSOR_TYPE; }
|
||||
|
@ -45,11 +45,15 @@ using namespace icinga;
|
||||
%union {
|
||||
char *text;
|
||||
int num;
|
||||
FieldType *type;
|
||||
Field *field;
|
||||
std::vector<Field> *fields;
|
||||
Klass *klass;
|
||||
FieldAccessor *fieldaccessor;
|
||||
std::vector<FieldAccessor> *fieldaccessors;
|
||||
Rule *rule;
|
||||
std::vector<Rule> *rules;
|
||||
Validator *validator;
|
||||
}
|
||||
|
||||
%token T_INCLUDE "include (T_INCLUDE)"
|
||||
@ -57,6 +61,9 @@ using namespace icinga;
|
||||
%token T_CODE "code (T_CODE)"
|
||||
%token T_LOAD_AFTER "load_after (T_LOAD_AFTER)"
|
||||
%token T_NAMESPACE "namespace (T_NAMESPACE)"
|
||||
%token T_VALIDATOR "validator (T_VALIDATOR)"
|
||||
%token T_REQUIRED "required (T_REQUIRED)"
|
||||
%token T_NAME "name (T_NAME)"
|
||||
%token T_STRING "string (T_STRING)"
|
||||
%token T_ANGLE_STRING "angle_string (T_ANGLE_STRING)"
|
||||
%token T_FIELD_ATTRIBUTE "field_attribute (T_FIELD_ATTRIBUTE)"
|
||||
@ -77,17 +84,22 @@ using namespace icinga;
|
||||
%type <text> angle_include
|
||||
%type <text> code
|
||||
%type <num> T_FIELD_ATTRIBUTE
|
||||
%type <num> field_attribute
|
||||
%type <num> field_attributes
|
||||
%type <num> field_attribute_list
|
||||
%type <num> T_FIELD_ACCESSOR_TYPE
|
||||
%type <num> T_CLASS_ATTRIBUTE
|
||||
%type <num> class_attribute_list
|
||||
%type <type> field_type
|
||||
%type <field> class_field
|
||||
%type <fields> class_fields
|
||||
%type <klass> class
|
||||
%type <fieldaccessors> field_accessor_list
|
||||
%type <fieldaccessors> field_accessors
|
||||
%type <fieldaccessor> field_accessor
|
||||
%type <rule> validator_rule
|
||||
%type <rules> validator_rules
|
||||
%type <validator> validator
|
||||
|
||||
%{
|
||||
|
||||
@ -110,6 +122,8 @@ void ClassCompiler::Compile(void)
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Exception: " << ex.what();
|
||||
}
|
||||
|
||||
HandleMissingValidators();
|
||||
}
|
||||
|
||||
#define scanner (context->GetScanner())
|
||||
@ -137,6 +151,11 @@ statement: include
|
||||
context->HandleClass(*$1, yylloc);
|
||||
delete $1;
|
||||
}
|
||||
| validator
|
||||
{
|
||||
context->HandleValidator(*$1, yylloc);
|
||||
delete $1;
|
||||
}
|
||||
| namespace
|
||||
| code
|
||||
{
|
||||
@ -250,7 +269,23 @@ class_fields: /* empty */
|
||||
}
|
||||
;
|
||||
|
||||
class_field: field_attribute_list identifier identifier alternative_name_specifier field_accessor_list ';'
|
||||
field_type: identifier
|
||||
{
|
||||
$$ = new FieldType();
|
||||
$$->IsName = false;
|
||||
$$->TypeName = $1;
|
||||
free($1);
|
||||
}
|
||||
| T_NAME '(' identifier ')'
|
||||
{
|
||||
$$ = new FieldType();
|
||||
$$->IsName = true;
|
||||
$$->TypeName = $3;
|
||||
free($3);
|
||||
}
|
||||
;
|
||||
|
||||
class_field: field_attribute_list field_type identifier alternative_name_specifier field_accessor_list ';'
|
||||
{
|
||||
Field *field = new Field();
|
||||
|
||||
@ -259,8 +294,8 @@ class_field: field_attribute_list identifier identifier alternative_name_specifi
|
||||
if ((field->Attributes & (FAConfig | FAState)) == 0)
|
||||
field->Attributes |= FAEphemeral;
|
||||
|
||||
field->Type = $2;
|
||||
std::free($2);
|
||||
field->Type = *$2;
|
||||
delete $2;
|
||||
|
||||
field->Name = $3;
|
||||
std::free($3);
|
||||
@ -321,15 +356,25 @@ field_attribute_list: /* empty */
|
||||
}
|
||||
;
|
||||
|
||||
field_attribute: T_FIELD_ATTRIBUTE
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| T_REQUIRED
|
||||
{
|
||||
$$ = FARequired;
|
||||
}
|
||||
;
|
||||
|
||||
field_attributes: /* empty */
|
||||
{
|
||||
$$ = 0;
|
||||
}
|
||||
| field_attributes ',' T_FIELD_ATTRIBUTE
|
||||
| field_attributes ',' field_attribute
|
||||
{
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
| T_FIELD_ATTRIBUTE
|
||||
| field_attribute
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
@ -368,6 +413,84 @@ field_accessor: T_FIELD_ACCESSOR_TYPE T_STRING
|
||||
}
|
||||
;
|
||||
|
||||
validator_rules: /* empty */
|
||||
{
|
||||
$$ = new std::vector<Rule>();
|
||||
}
|
||||
| validator_rules validator_rule
|
||||
{
|
||||
$$->push_back(*$2);
|
||||
delete $2;
|
||||
}
|
||||
;
|
||||
|
||||
validator_rule: T_NAME '(' T_IDENTIFIER ')' identifier ';'
|
||||
{
|
||||
$$ = new Rule();
|
||||
$$->Attributes = 0;
|
||||
$$->IsName = true;
|
||||
$$->Type = $3;
|
||||
std::free($3);
|
||||
$$->Pattern = $5;
|
||||
std::free($5);
|
||||
}
|
||||
| T_IDENTIFIER identifier ';'
|
||||
{
|
||||
$$ = new Rule();
|
||||
$$->Attributes = 0;
|
||||
$$->IsName = false;
|
||||
$$->Type = $1;
|
||||
std::free($1);
|
||||
$$->Pattern = $2;
|
||||
std::free($2);
|
||||
}
|
||||
| T_NAME '(' T_IDENTIFIER ')' identifier '{' validator_rules '}' ';'
|
||||
{
|
||||
$$ = new Rule();
|
||||
$$->Attributes = 0;
|
||||
$$->IsName = true;
|
||||
$$->Type = $3;
|
||||
std::free($3);
|
||||
$$->Pattern = $5;
|
||||
std::free($5);
|
||||
$$->Rules = *$7;
|
||||
delete $7;
|
||||
}
|
||||
| T_IDENTIFIER identifier '{' validator_rules '}' ';'
|
||||
{
|
||||
$$ = new Rule();
|
||||
$$->Attributes = 0;
|
||||
$$->IsName = false;
|
||||
$$->Type = $1;
|
||||
std::free($1);
|
||||
$$->Pattern = $2;
|
||||
std::free($2);
|
||||
$$->Rules = *$4;
|
||||
delete $4;
|
||||
}
|
||||
| T_REQUIRED identifier ';'
|
||||
{
|
||||
$$ = new Rule();
|
||||
$$->Attributes = RARequired;
|
||||
$$->IsName = false;
|
||||
$$->Type = "";
|
||||
$$->Pattern = $2;
|
||||
std::free($2);
|
||||
}
|
||||
;
|
||||
|
||||
validator: T_VALIDATOR T_IDENTIFIER '{' validator_rules '}' ';'
|
||||
{
|
||||
$$ = new Validator();
|
||||
|
||||
$$->Name = $2;
|
||||
std::free($2);
|
||||
|
||||
$$->Rules = *$4;
|
||||
delete $4;
|
||||
}
|
||||
;
|
||||
|
||||
identifier: T_IDENTIFIER
|
||||
| T_STRING
|
||||
{
|
||||
|
@ -19,9 +19,11 @@
|
||||
|
||||
#include "classcompiler.hpp"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#ifndef _WIN32
|
||||
@ -77,6 +79,8 @@ void ClassCompiler::HandleNamespaceBegin(const std::string& name, const ClassDeb
|
||||
|
||||
void ClassCompiler::HandleNamespaceEnd(const ClassDebugInfo&)
|
||||
{
|
||||
HandleMissingValidators();
|
||||
|
||||
std::cout << "}" << std::endl;
|
||||
}
|
||||
|
||||
@ -94,16 +98,16 @@ unsigned long ClassCompiler::SDBM(const std::string& str, size_t len = std::stri
|
||||
|
||||
for (it = str.begin(); it != str.end(); it++) {
|
||||
if (current >= len)
|
||||
break;
|
||||
break;
|
||||
|
||||
char c = *it;
|
||||
|
||||
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||
|
||||
current++;
|
||||
}
|
||||
current++;
|
||||
}
|
||||
|
||||
return hash;
|
||||
return hash;
|
||||
}
|
||||
|
||||
static int TypePreference(const std::string& type)
|
||||
@ -124,12 +128,12 @@ static int TypePreference(const std::string& type)
|
||||
|
||||
static bool FieldLayoutCmp(const Field& a, const Field& b)
|
||||
{
|
||||
return TypePreference(a.Type) < TypePreference(b.Type);
|
||||
return TypePreference(a.Type.GetRealType()) < TypePreference(b.Type.GetRealType());
|
||||
}
|
||||
|
||||
static bool FieldTypeCmp(const Field& a, const Field& b)
|
||||
{
|
||||
return a.Type < b.Type;
|
||||
return a.Type.GetRealType() < b.Type.GetRealType();
|
||||
}
|
||||
|
||||
void ClassCompiler::OptimizeStructLayout(std::vector<Field>& fields)
|
||||
@ -297,7 +301,10 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||
|
||||
size_t num = 0;
|
||||
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||
std::string ftype = it->Type;
|
||||
std::string ftype = it->Type.GetRealType();
|
||||
|
||||
if (ftype == "bool" || ftype == "int" || ftype == "double")
|
||||
ftype = "Number";
|
||||
|
||||
if (ftype == "int" || ftype == "double")
|
||||
ftype = "Number";
|
||||
@ -310,8 +317,15 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||
if (it->Attributes & FAEnum)
|
||||
ftype = "Number";
|
||||
|
||||
std::string nameref;
|
||||
|
||||
if (it->Type.IsName)
|
||||
nameref = "\"" + it->Type.TypeName + "\"";
|
||||
else
|
||||
nameref = "NULL";
|
||||
|
||||
std::cout << "\t\t\t" << "case " << num << ":" << std::endl
|
||||
<< "\t\t\t\t" << "return Field(" << num << ", \"" << ftype << "\", \"" << it->Name << "\", " << it->Attributes << ");" << std::endl;
|
||||
<< "\t\t\t\t" << "return Field(" << num << ", \"" << ftype << "\", \"" << it->Name << "\", " << nameref << ", " << it->Attributes << ");" << std::endl;
|
||||
num++;
|
||||
}
|
||||
|
||||
@ -362,13 +376,56 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||
|
||||
std::cout << "};" << std::endl << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
/* ObjectImpl */
|
||||
std::cout << "template<>" << std::endl
|
||||
<< "class ObjectImpl<" << klass.Name << ">"
|
||||
<< " : public " << (klass.Parent.empty() ? "Object" : klass.Parent) << std::endl
|
||||
<< "{" << std::endl
|
||||
<< "public:" << std::endl
|
||||
<< "\t" << "DECLARE_PTR_TYPEDEFS(ObjectImpl<" << klass.Name << ">);" << std::endl;
|
||||
<< "\t" << "DECLARE_PTR_TYPEDEFS(ObjectImpl<" << klass.Name << ">);" << std::endl << std::endl;
|
||||
|
||||
/* Validate */
|
||||
std::cout << "\t" << "virtual void Validate(int types, const ValidationUtils& utils)" << std::endl
|
||||
<< "\t" << "{" << std::endl;
|
||||
|
||||
if (!klass.Parent.empty())
|
||||
std::cout << "\t\t" << klass.Parent << "::Validate(types, utils);" << std::endl << std::endl;
|
||||
|
||||
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||
std::cout << "\t\t" << "if (" << (it->Attributes & (FAEphemeral|FAConfig|FAState)) << " & types)" << std::endl
|
||||
<< "\t\t\t" << "Validate" << it->GetFriendlyName() << "(Get" << it->GetFriendlyName() << "(), utils);" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "\t" << "}" << std::endl << std::endl;
|
||||
|
||||
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||
std::cout << "\t" << "inline void SimpleValidate" << it->GetFriendlyName() << "(" << it->Type.GetArgumentType() << " value, const ValidationUtils& utils)" << std::endl
|
||||
<< "\t" << "{" << std::endl;
|
||||
|
||||
const Field& field = *it;
|
||||
|
||||
if ((field.Attributes & (FARequired)) || field.Type.IsName) {
|
||||
if (field.Attributes & FARequired) {
|
||||
if (field.Type.GetRealType().find("::Ptr") != std::string::npos)
|
||||
std::cout << "\t\t" << "if (!value)" << std::endl;
|
||||
else
|
||||
std::cout << "\t\t" << "if (value.IsEmpty())" << std::endl;
|
||||
|
||||
std::cout << "\t\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of(\"" << field.Name << "\"), \"Attribute must not be empty.\"));" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
if (field.Type.IsName) {
|
||||
std::cout << "\t\t" << "String ref = value;" << std::endl
|
||||
<< "\t\t" << "if (!ref.IsEmpty() && !utils.ValidateName(\"" << field.Type.TypeName << "\", ref))" << std::endl
|
||||
<< "\t\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of(\"" << field.Name << "\"), \"Object '\" + ref + \"' of type '" << field.Type.TypeName
|
||||
<< "' does not exist.\"));" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\t" << "}" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
if (!klass.Fields.empty()) {
|
||||
/* constructor */
|
||||
@ -389,7 +446,7 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||
|
||||
if (!klass.Parent.empty())
|
||||
std::cout << "\t\t" << "int real_id = id - TypeImpl<" << klass.Parent << ">::StaticGetFieldCount(); " << std::endl
|
||||
<< "\t\t" << "if (real_id < 0) { " << klass.Parent << "::SetField(id, value); return; }" << std::endl;
|
||||
<< "\t\t" << "if (real_id < 0) { " << klass.Parent << "::SetField(id, value); return; }" << std::endl;
|
||||
|
||||
std::cout << "\t\t" << "switch (";
|
||||
|
||||
@ -406,7 +463,7 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||
<< "\t\t\t\t" << "Set" << it->GetFriendlyName() << "(";
|
||||
|
||||
if (it->Attributes & FAEnum)
|
||||
std::cout << "static_cast<" << it->Type << ">(static_cast<int>(";
|
||||
std::cout << "static_cast<" << it->Type.GetRealType() << ">(static_cast<int>(";
|
||||
|
||||
std::cout << "value";
|
||||
|
||||
@ -465,7 +522,7 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||
prot = "public";
|
||||
|
||||
std::cout << prot << ":" << std::endl
|
||||
<< "\t" << "virtual " << it->Type << " Get" << it->GetFriendlyName() << "(void) const";
|
||||
<< "\t" << "virtual " << it->Type.GetRealType() << " Get" << it->GetFriendlyName() << "(void) const";
|
||||
|
||||
if (it->PureGetAccessor) {
|
||||
std::cout << " = 0;" << std::endl;
|
||||
@ -494,14 +551,7 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||
prot = "public";
|
||||
|
||||
std::cout << prot << ":" << std::endl
|
||||
<< "\t" << "virtual void Set" << it->GetFriendlyName() << "(";
|
||||
|
||||
if (it->Type == "bool" || it->Type == "double" || it->Type == "int")
|
||||
std::cout << it->Type;
|
||||
else
|
||||
std::cout << "const " << it->Type << "&";
|
||||
|
||||
std::cout << " value)" << std::endl;
|
||||
<< "\t" << "virtual void Set" << it->GetFriendlyName() << "(" << it->Type.GetArgumentType() << " value)" << std::endl;
|
||||
|
||||
if (it->PureSetAccessor) {
|
||||
std::cout << " = 0;" << std::endl;
|
||||
@ -519,26 +569,32 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||
|
||||
/* default */
|
||||
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||
std::string prot;
|
||||
std::string realType = it->Type.GetRealType();
|
||||
|
||||
std::cout << "private:" << std::endl
|
||||
<< "\t" << it->Type << " GetDefault" << it->GetFriendlyName() << "(void) const" << std::endl
|
||||
<< "\t" << realType << " GetDefault" << it->GetFriendlyName() << "(void) const" << std::endl
|
||||
<< "\t" << "{" << std::endl;
|
||||
|
||||
if (it->DefaultAccessor.empty())
|
||||
std::cout << "\t\t" << "return " << it->Type << "();" << std::endl;
|
||||
std::cout << "\t\t" << "return " << realType << "();" << std::endl;
|
||||
else
|
||||
std::cout << it->DefaultAccessor << std::endl;
|
||||
|
||||
std::cout << "\t" << "}" << std::endl;
|
||||
}
|
||||
|
||||
/* validators */
|
||||
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||
std::cout << "protected:" << std::endl
|
||||
<< "\t" << "virtual void Validate" << it->GetFriendlyName() << "(" << it->Type.GetArgumentType() << " value, const ValidationUtils& utils);" << std::endl;
|
||||
}
|
||||
|
||||
/* instance variables */
|
||||
std::cout << "private:" << std::endl;
|
||||
|
||||
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||
if (!(it->Attributes & FANoStorage))
|
||||
std::cout << "\t" << it->Type << " m_" << it->GetFriendlyName() << ";" << std::endl;
|
||||
std::cout << "\t" << it->Type.GetRealType() << " m_" << it->GetFriendlyName() << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,6 +605,286 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||
std::cout << "\t" << "friend class " << klass.TypeBase << ";" << std::endl;
|
||||
|
||||
std::cout << "};" << std::endl << std::endl;
|
||||
|
||||
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||
m_MissingValidators[std::make_pair(klass.Name, it->GetFriendlyName())] = *it;
|
||||
}
|
||||
}
|
||||
|
||||
enum ValidatorType
|
||||
{
|
||||
ValidatorField,
|
||||
ValidatorArray,
|
||||
ValidatorDictionary
|
||||
};
|
||||
|
||||
static void CodeGenValidator(const std::string& name, const std::string& klass, const std::vector<Rule>& rules, const std::string& field, const FieldType& fieldType, ValidatorType validatorType)
|
||||
{
|
||||
std::cout << "inline void TIValidate" << name << "(const intrusive_ptr<ObjectImpl<" << klass << "> >& object, ";
|
||||
|
||||
if (validatorType != ValidatorField)
|
||||
std::cout << "const String& key, ";
|
||||
|
||||
bool static_known_attribute = false;
|
||||
|
||||
std::cout << fieldType.GetArgumentType() << " value, std::vector<String>& location, const ValidationUtils& utils)" << std::endl
|
||||
<< "{" << std::endl;
|
||||
|
||||
if (validatorType == ValidatorField) {
|
||||
static_known_attribute = true;
|
||||
|
||||
bool required = false;
|
||||
|
||||
for (std::vector<Rule>::size_type i = 0; i < rules.size(); i++) {
|
||||
const Rule& rule = rules[i];
|
||||
|
||||
if ((rule.Attributes & RARequired) && rule.Pattern == field) {
|
||||
required = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldType.GetRealType() != "int" && fieldType.GetRealType() != "double") {
|
||||
if (fieldType.GetRealType() == "Value" || fieldType.GetRealType() == "String")
|
||||
std::cout << "\t" << "if (value.IsEmpty())" << std::endl;
|
||||
else
|
||||
std::cout << "\t" << "if (!value)" << std::endl;
|
||||
|
||||
if (required)
|
||||
std::cout << "BOOST_THROW_EXCEPTION(ValidationError(this, location, \"This attribute must not be empty.\"));" << std::endl;
|
||||
else
|
||||
std::cout << "\t\t" << "return;" << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (!static_known_attribute)
|
||||
std::cout << "\t" << "bool known_attribute = false;" << std::endl;
|
||||
|
||||
bool type_check = false;
|
||||
|
||||
for (std::vector<Rule>::size_type i = 0; i < rules.size(); i++) {
|
||||
const Rule& rule = rules[i];
|
||||
|
||||
if (rule.Attributes & RARequired)
|
||||
continue;
|
||||
|
||||
if (validatorType == ValidatorField && rule.Pattern != field)
|
||||
continue;
|
||||
|
||||
std::cout << "\t" << "do {" << std::endl;
|
||||
|
||||
if (validatorType != ValidatorField) {
|
||||
if (rule.Pattern != "*") {
|
||||
if (rule.Pattern.find_first_of("*?") != std::string::npos)
|
||||
std::cout << "\t\t" << "if (!Utility::Match(\"" << rule.Pattern << "\", key))" << std::endl;
|
||||
else
|
||||
std::cout << "\t\t" << "if (key != \"" << rule.Pattern << "\")" << std::endl;
|
||||
|
||||
std::cout << "\t\t\t" << "break;" << std::endl;
|
||||
} else
|
||||
static_known_attribute = true;
|
||||
|
||||
if (!static_known_attribute)
|
||||
std::cout << "\t\t" << "known_attribute = true;" << std::endl;
|
||||
}
|
||||
|
||||
if (rule.IsName) {
|
||||
std::cout << "\t\t" << "if (value.IsScalar()) {" << std::endl
|
||||
<< "\t\t\t" << "if (utils.ValidateName(\"" << rule.Type << "\", value))" << std::endl
|
||||
<< "\t\t\t\t" << "return;" << std::endl
|
||||
<< "\t\t\t" << "else" << std::endl
|
||||
<< "\t\t\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(object, location, \"Object '\" + value + \"' of type '" << rule.Type << "' does not exist.\"));" << std::endl
|
||||
<< "\t\t" << "}" << std::endl;
|
||||
}
|
||||
|
||||
if (fieldType.GetRealType() == "Value") {
|
||||
if (rule.Type == "String")
|
||||
std::cout << "\t\t" << "if (value.IsScalar())" << std::endl
|
||||
<< "\t\t\t" << "return;" << std::endl;
|
||||
else if (rule.Type == "Number") {
|
||||
std::cout << "\t\t" << "try {" << std::endl
|
||||
<< "\t\t\t" << "Convert::ToDouble(value);" << std::endl
|
||||
<< "\t\t\t" << "return;" << std::endl
|
||||
<< "\t\t" << "} catch (...) { }" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (rule.Type == "Dictionary" || rule.Type == "Array" || rule.Type == "Function") {
|
||||
if (fieldType.GetRealType() == "Value") {
|
||||
std::cout << "\t\t" << "if (value.IsObjectType<" << rule.Type << ">()) {" << std::endl;
|
||||
type_check = true;
|
||||
} else if (fieldType.GetRealType() != rule.Type + "::Ptr") {
|
||||
std::cout << "\t\t" << "if (dynamic_pointer_cast<" << rule.Type << ">(value)) {" << std::endl;
|
||||
type_check = true;
|
||||
}
|
||||
|
||||
if (!rule.Rules.empty()) {
|
||||
bool indent = false;
|
||||
|
||||
if (rule.Type == "Dictionary") {
|
||||
if (type_check)
|
||||
std::cout << "\t\t\t" << "Dictionary::Ptr dict = value;" << std::endl;
|
||||
else
|
||||
std::cout << "\t\t" << "const Dictionary::Ptr& dict = value;" << std::endl;
|
||||
|
||||
std::cout << (type_check ? "\t" : "") << "\t\t" << "ObjectLock olock(dict);" << std::endl
|
||||
<< (type_check ? "\t" : "") << "\t\t" << "BOOST_FOREACH(const Dictionary::Pair& kv, dict) {" << std::endl
|
||||
<< (type_check ? "\t" : "") << "\t\t\t" << "const String& akey = kv.first;" << std::endl
|
||||
<< (type_check ? "\t" : "") << "\t\t\t" << "const Value& avalue = kv.second;" << std::endl;
|
||||
indent = true;
|
||||
} else if (rule.Type == "Array") {
|
||||
if (type_check)
|
||||
std::cout << "\t\t\t" << "Array::Ptr arr = value;" << std::endl;
|
||||
else
|
||||
std::cout << "\t\t" << "const Array::Ptr& arr = value;" << std::endl;
|
||||
|
||||
std::cout << (type_check ? "\t" : "") << "\t\t" << "Array::SizeType anum = 0;" << std::endl
|
||||
<< (type_check ? "\t" : "") << "\t\t" << "ObjectLock olock(arr);" << std::endl
|
||||
<< (type_check ? "\t" : "") << "\t\t" << "BOOST_FOREACH(const Value& avalue, arr) {" << std::endl
|
||||
<< (type_check ? "\t" : "") << "\t\t\t" << "String akey = Convert::ToString(anum);" << std::endl;
|
||||
indent = true;
|
||||
} else {
|
||||
std::cout << (type_check ? "\t" : "") << "\t\t" << "String akey = \"\";" << std::endl
|
||||
<< (type_check ? "\t" : "") << "\t\t" << "const Value& avalue = value;" << std::endl;
|
||||
}
|
||||
|
||||
std::string subvalidator_prefix;
|
||||
|
||||
if (validatorType == ValidatorField)
|
||||
subvalidator_prefix = klass;
|
||||
else
|
||||
subvalidator_prefix = name;
|
||||
|
||||
std::cout << (type_check ? "\t" : "") << (indent ? "\t" : "") << "\t\t" << "location.push_back(akey);" << std::endl
|
||||
<< (type_check ? "\t" : "") << (indent ? "\t" : "") << "\t\t" << "TIValidate" << subvalidator_prefix << "_" << i << "(object, akey, avalue, location, utils);" << std::endl;
|
||||
|
||||
if (rule.Type == "Array")
|
||||
std::cout << (type_check ? "\t" : "") << "\t\t\t" << "anum++;" << std::endl;
|
||||
|
||||
if (rule.Type == "Dictionary" || rule.Type == "Array")
|
||||
std::cout << (type_check ? "\t" : "") << "\t\t" << "}" << std::endl;
|
||||
|
||||
for (std::vector<Rule>::size_type i = 0; i < rule.Rules.size(); i++) {
|
||||
const Rule& srule = rule.Rules[i];
|
||||
|
||||
if ((srule.Attributes & RARequired) == 0)
|
||||
continue;
|
||||
|
||||
if (rule.Type == "Dictionary") {
|
||||
std::cout << (type_check ? "\t" : "") << "\t\t" << "if (dict.Get(\"" << srule.Pattern << "\").IsEmpty())" << std::endl
|
||||
<< (type_check ? "\t" : "") << "\t\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(this, location, \"Required dictionary item '" << srule.Pattern << "' is not set.\"));" << std::endl;
|
||||
} else if (rule.Type == "Array") {
|
||||
int index = -1;
|
||||
std::stringstream idxbuf;
|
||||
idxbuf << srule.Pattern;
|
||||
idxbuf >> index;
|
||||
|
||||
if (index == -1) {
|
||||
std::cerr << "Invalid index for 'required' keyword: " << srule.Pattern;
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
std::cout << (type_check ? "\t" : "") << "\t\t" << "if (arr.GetLength() < " << (index + 1) << ")" << std::endl
|
||||
<< (type_check ? "\t" : "") << "\t\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(this, location, \"Required index '" << index << "' is not set.\"));" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << (type_check ? "\t" : "") << (indent ? "\t" : "") << "\t\t" << "location.pop_back();" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << (type_check ? "\t" : "") << "\t\t" << "return;" << std::endl;
|
||||
|
||||
if (fieldType.GetRealType() == "Value" || fieldType.GetRealType() != rule.Type + "::Ptr")
|
||||
std::cout << "\t\t" << "}" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "\t" << "} while (0);" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
if (type_check || validatorType != ValidatorField) {
|
||||
if (!static_known_attribute)
|
||||
std::cout << "\t" << "if (!known_attribute)" << std::endl
|
||||
<< "\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(object, location, \"Invalid attribute: \" + key));" << std::endl
|
||||
<< "\t" << "else" << std::endl;
|
||||
|
||||
std::cout << (!static_known_attribute ? "\t" : "") << "\t" << "BOOST_THROW_EXCEPTION(ValidationError(object, boost::assign::list_of(";
|
||||
|
||||
if (validatorType == ValidatorField)
|
||||
std::cout << "\"" << field << "\"";
|
||||
else
|
||||
std::cout << "key";
|
||||
|
||||
std::cout << "), \"Invalid type.\"));" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "}" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
static void CodeGenValidatorSubrules(const std::string& name, const std::string& klass, const std::vector<Rule>& rules)
|
||||
{
|
||||
for (std::vector<Rule>::size_type i = 0; i < rules.size(); i++) {
|
||||
const Rule& rule = rules[i];
|
||||
|
||||
if (rule.Attributes & RARequired)
|
||||
continue;
|
||||
|
||||
if (!rule.Rules.empty()) {
|
||||
ValidatorType subtype;
|
||||
|
||||
if (rule.Type == "Array")
|
||||
subtype = ValidatorArray;
|
||||
else if (rule.Type == "Dictionary")
|
||||
subtype = ValidatorDictionary;
|
||||
else {
|
||||
std::cerr << "Invalid sub-validator type: " << rule.Type << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
std::ostringstream namebuf;
|
||||
namebuf << name << "_" << i;
|
||||
|
||||
CodeGenValidatorSubrules(namebuf.str(), klass, rule.Rules);
|
||||
|
||||
FieldType ftype;
|
||||
ftype.IsName = false;
|
||||
ftype.TypeName = "Value";
|
||||
CodeGenValidator(namebuf.str(), klass, rule.Rules, rule.Pattern, ftype, subtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassCompiler::HandleValidator(const Validator& validator, const ClassDebugInfo&)
|
||||
{
|
||||
CodeGenValidatorSubrules(validator.Name, validator.Name, validator.Rules);
|
||||
|
||||
for (std::map<std::pair<std::string, std::string>, Field>::const_iterator it = m_MissingValidators.begin(); it != m_MissingValidators.end(); it++)
|
||||
CodeGenValidator(it->first.first + it->first.second, it->first.first, validator.Rules, it->second.Name, it->second.Type, ValidatorField);
|
||||
|
||||
for (std::map<std::pair<std::string, std::string>, Field>::const_iterator it = m_MissingValidators.begin(); it != m_MissingValidators.end(); it++) {
|
||||
std::cout << "inline void ObjectImpl<" << it->first.first << ">::Validate" << it->first.second << "(" << it->second.Type.GetArgumentType() << " value, const ValidationUtils& utils)" << std::endl
|
||||
<< "{" << std::endl
|
||||
<< "\t" << "SimpleValidate" << it->first.second << "(value, utils);" << std::endl
|
||||
<< "\t" << "std::vector<String> location;" << std::endl
|
||||
<< "\t" << "location.push_back(\"" << it->second.Name << "\");" << std::endl
|
||||
<< "\t" << "TIValidate" << it->first.first << it->first.second << "(this, value, location, utils);" << std::endl
|
||||
<< "}" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
m_MissingValidators.clear();
|
||||
}
|
||||
|
||||
void ClassCompiler::HandleMissingValidators(void)
|
||||
{
|
||||
for (std::map<std::pair<std::string, std::string>, Field>::const_iterator it = m_MissingValidators.begin(); it != m_MissingValidators.end(); it++) {
|
||||
std::cout << "inline void ObjectImpl<" << it->first.first << ">::Validate" << it->first.second << "(" << it->second.Type.GetArgumentType() << " value, const ValidationUtils& utils)" << std::endl
|
||||
<< "{" << std::endl
|
||||
<< "\t" << "SimpleValidate" << it->first.second << "(value, utils);" << std::endl
|
||||
<< "}" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
m_MissingValidators.clear();
|
||||
}
|
||||
|
||||
void ClassCompiler::CompileFile(const std::string& path)
|
||||
@ -562,7 +898,7 @@ void ClassCompiler::CompileFile(const std::string& path)
|
||||
return CompileStream(path, &stream);
|
||||
}
|
||||
|
||||
std::string ClassCompiler::BaseName(const std::string& path)
|
||||
std::string ClassCompiler::BaseName(const std::string& path)
|
||||
{
|
||||
char *dir = strdup(path.c_str());
|
||||
std::string result;
|
||||
@ -610,7 +946,12 @@ void ClassCompiler::CompileStream(const std::string& path, std::istream *stream)
|
||||
<< "#include \"base/value.hpp\"" << std::endl
|
||||
<< "#include \"base/array.hpp\"" << std::endl
|
||||
<< "#include \"base/dictionary.hpp\"" << std::endl
|
||||
<< "#include \"base/convert.hpp\"" << std::endl
|
||||
<< "#include \"base/exception.hpp\"" << std::endl
|
||||
<< "#include \"base/objectlock.hpp\"" << std::endl
|
||||
<< "#include \"base/utility.hpp\"" << std::endl << std::endl
|
||||
<< "#include <boost/foreach.hpp>" << std::endl
|
||||
<< "#include <boost/assign/list_of.hpp>" << std::endl
|
||||
<< "#ifdef _MSC_VER" << std::endl
|
||||
<< "#pragma warning( push )" << std::endl
|
||||
<< "#pragma warning( disable : 4244 )" << std::endl
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <istream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
@ -66,13 +67,38 @@ enum FieldAttribute
|
||||
FASetProtected = 32,
|
||||
FAInternal = 64,
|
||||
FANoStorage = 128,
|
||||
FALoadDependency = 256
|
||||
FALoadDependency = 256,
|
||||
FARequired = 512
|
||||
};
|
||||
|
||||
struct FieldType
|
||||
{
|
||||
bool IsName;
|
||||
std::string TypeName;
|
||||
|
||||
inline std::string GetRealType(void) const
|
||||
{
|
||||
if (IsName)
|
||||
return "String";
|
||||
else
|
||||
return TypeName;
|
||||
}
|
||||
|
||||
inline std::string GetArgumentType(void) const
|
||||
{
|
||||
std::string realType = GetRealType();
|
||||
|
||||
if (realType == "bool" || realType == "double" || realType == "int")
|
||||
return realType;
|
||||
else
|
||||
return "const " + realType + "&";
|
||||
}
|
||||
};
|
||||
|
||||
struct Field
|
||||
{
|
||||
int Attributes;
|
||||
std::string Type;
|
||||
FieldType Type;
|
||||
std::string Name;
|
||||
std::string AlternativeName;
|
||||
std::string GetAccessor;
|
||||
@ -85,7 +111,7 @@ struct Field
|
||||
: Attributes(0), PureGetAccessor(false), PureSetAccessor(false)
|
||||
{ }
|
||||
|
||||
std::string GetFriendlyName(void) const
|
||||
inline std::string GetFriendlyName(void) const
|
||||
{
|
||||
if (!AlternativeName.empty())
|
||||
return AlternativeName;
|
||||
@ -130,6 +156,27 @@ struct Klass
|
||||
std::vector<std::string> LoadDependencies;
|
||||
};
|
||||
|
||||
enum RuleAttribute
|
||||
{
|
||||
RARequired = 1
|
||||
};
|
||||
|
||||
struct Rule
|
||||
{
|
||||
int Attributes;
|
||||
bool IsName;
|
||||
std::string Type;
|
||||
std::string Pattern;
|
||||
|
||||
std::vector<Rule> Rules;
|
||||
};
|
||||
|
||||
struct Validator
|
||||
{
|
||||
std::string Name;
|
||||
std::vector<Rule> Rules;
|
||||
};
|
||||
|
||||
class ClassCompiler
|
||||
{
|
||||
public:
|
||||
@ -150,9 +197,11 @@ public:
|
||||
void HandleInclude(const std::string& path, const ClassDebugInfo& locp);
|
||||
void HandleAngleInclude(const std::string& path, const ClassDebugInfo& locp);
|
||||
void HandleClass(const Klass& klass, const ClassDebugInfo& locp);
|
||||
void HandleValidator(const Validator& validator, const ClassDebugInfo& locp);
|
||||
void HandleNamespaceBegin(const std::string& name, const ClassDebugInfo& locp);
|
||||
void HandleNamespaceEnd(const ClassDebugInfo& locp);
|
||||
void HandleCode(const std::string& code, const ClassDebugInfo& locp);
|
||||
void HandleMissingValidators(void);
|
||||
|
||||
static void CompileFile(const std::string& path);
|
||||
static void CompileStream(const std::string& path, std::istream *stream);
|
||||
@ -164,6 +213,8 @@ private:
|
||||
std::istream *m_Input;
|
||||
void *m_Scanner;
|
||||
|
||||
std::map<std::pair<std::string, std::string>, Field> m_MissingValidators;
|
||||
|
||||
static unsigned long SDBM(const std::string& str, size_t len);
|
||||
static std::string BaseName(const std::string& path);
|
||||
static std::string FileNameToGuardName(const std::string& path);
|
||||
|
Loading…
x
Reference in New Issue
Block a user