mirror of https://github.com/Icinga/icinga2.git
parent
3587dbbd13
commit
caad7a7973
|
@ -320,7 +320,7 @@ Simple calculations can be performed using the constant expression syntax:
|
|||
check_interval = (15 * 60)
|
||||
}
|
||||
|
||||
Valid operators include ~, +, -, * and /. The default precedence rules can be
|
||||
Valid operators include ~, +, -, *, /, == and !=. The default precedence rules can be
|
||||
overridden by grouping expressions using parentheses:
|
||||
|
||||
{
|
||||
|
@ -339,8 +339,27 @@ Global constants may be used in constant expressions.
|
|||
|
||||
> **Note**
|
||||
>
|
||||
> Constant expressions are evaluated as soon as they're encountered in
|
||||
> the configuration file.
|
||||
> Constant expressions in attributes and variable definitions are evaluated as
|
||||
> soon as they're encountered in the configuration file.
|
||||
|
||||
### <a id="apply"></a> Apply
|
||||
|
||||
The `apply` keyword can be used to associate a template with another group of
|
||||
objects. The exact effect of this association depends on the two object types.
|
||||
|
||||
template Service "ping-service" {
|
||||
short_name = "ping",
|
||||
check_command = "ping4"
|
||||
}
|
||||
|
||||
apply template Service "ping-service" to Host where (host == "localhost")
|
||||
|
||||
In this example the `where` condition is a constant expression which is
|
||||
evaluated for all objects of type Host and a new service is created for each
|
||||
matching host.
|
||||
|
||||
Depending on the object types used in the `apply` expression additional local
|
||||
variables may be available for use in the `where` condition.
|
||||
|
||||
### <a id="comments"></a> Comments
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ mkembedconfig_target(base-type.conf base-type.cpp)
|
|||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_library(config SHARED
|
||||
aexpression.cpp avalue.cpp base-type.conf base-type.cpp
|
||||
aexpression.cpp applyrule.cpp avalue.cpp base-type.conf base-type.cpp
|
||||
configcompilercontext.cpp configcompiler.cpp configitembuilder.cpp
|
||||
configitem.cpp ${FLEX_config_lexer_OUTPUTS} ${BISON_config_parser_OUTPUTS}
|
||||
configtype.cpp expression.cpp expressionlist.cpp typerule.cpp typerulelist.cpp
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-present 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/applyrule.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
ApplyRule::RuleMap ApplyRule::m_Rules;
|
||||
ApplyRule::CallbackMap ApplyRule::m_Callbacks;
|
||||
|
||||
ApplyRule::ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di)
|
||||
: m_Template(tmpl), m_Expression(expression), m_DebugInfo(di)
|
||||
{ }
|
||||
|
||||
String ApplyRule::GetTemplate(void) const
|
||||
{
|
||||
return m_Template;
|
||||
}
|
||||
|
||||
AExpression::Ptr ApplyRule::GetExpression(void) const
|
||||
{
|
||||
return m_Expression;
|
||||
}
|
||||
|
||||
DebugInfo ApplyRule::GetDebugInfo(void) const
|
||||
{
|
||||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
void ApplyRule::AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di)
|
||||
{
|
||||
m_Rules[std::make_pair(sourceType, targetType)].push_back(ApplyRule(tmpl, expression, di));
|
||||
}
|
||||
|
||||
void ApplyRule::EvaluateRules(void)
|
||||
{
|
||||
std::pair<TypeCombination, Callback> kv;
|
||||
BOOST_FOREACH(kv, m_Callbacks) {
|
||||
RuleMap::const_iterator it = m_Rules.find(kv.first);
|
||||
|
||||
if (it == m_Rules.end())
|
||||
continue;
|
||||
|
||||
kv.second(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyRule::RegisterCombination(const String& sourceType, const String& targetType, const ApplyRule::Callback& callback)
|
||||
{
|
||||
m_Callbacks[std::make_pair(sourceType, targetType)] = callback;
|
||||
}
|
||||
|
||||
bool ApplyRule::IsValidCombination(const String& sourceType, const String& targetType)
|
||||
{
|
||||
return m_Callbacks.find(std::make_pair(sourceType, targetType)) != m_Callbacks.end();
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-present 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 APPLYRULE_H
|
||||
#define APPLYRULE_H
|
||||
|
||||
#include "config/i2-config.h"
|
||||
#include "config/aexpression.h"
|
||||
#include "config/debuginfo.h"
|
||||
#include "base/dynamictype.h"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*/
|
||||
class I2_CONFIG_API ApplyRule
|
||||
{
|
||||
public:
|
||||
typedef std::pair<String, String> TypeCombination;
|
||||
typedef boost::function<void (const std::vector<ApplyRule>& rules)> Callback;
|
||||
typedef std::map<TypeCombination, Callback> CallbackMap;
|
||||
typedef std::map<TypeCombination, std::vector<ApplyRule> > RuleMap;
|
||||
|
||||
String GetTemplate(void) const;
|
||||
AExpression::Ptr GetExpression(void) const;
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
|
||||
static void AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di);
|
||||
static void EvaluateRules(void);
|
||||
|
||||
static void RegisterCombination(const String& sourceType, const String& targetType, const ApplyRule::Callback& callback);
|
||||
static bool IsValidCombination(const String& sourceType, const String& targetType);
|
||||
|
||||
private:
|
||||
String m_Template;
|
||||
AExpression::Ptr m_Expression;
|
||||
DebugInfo m_DebugInfo;
|
||||
|
||||
static CallbackMap m_Callbacks;
|
||||
static RuleMap m_Rules;
|
||||
|
||||
ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* APPLYRULE_H */
|
|
@ -222,6 +222,9 @@ false { yylval->num = 0; return T_NUMBER; }
|
|||
set return T_VAR;
|
||||
var return T_VAR;
|
||||
const return T_CONST;
|
||||
apply return T_APPLY;
|
||||
to return T_TO;
|
||||
where return T_WHERE;
|
||||
\<\< return T_SHIFT_LEFT;
|
||||
\>\> return T_SHIFT_RIGHT;
|
||||
[a-zA-Z_][:a-zA-Z0-9\-_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; }
|
||||
|
|
|
@ -27,11 +27,13 @@
|
|||
#include "config/typerule.h"
|
||||
#include "config/typerulelist.h"
|
||||
#include "config/aexpression.h"
|
||||
#include "config/applyrule.h"
|
||||
#include "base/value.h"
|
||||
#include "base/utility.h"
|
||||
#include "base/array.h"
|
||||
#include "base/scriptvariable.h"
|
||||
#include "base/exception.h"
|
||||
#include "base/dynamictype.h"
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -98,6 +100,9 @@ using namespace icinga;
|
|||
%token T_LIBRARY "library (T_LIBRARY)"
|
||||
%token T_INHERITS "inherits (T_INHERITS)"
|
||||
%token T_PARTIAL "partial (T_PARTIAL)"
|
||||
%token T_APPLY "apply (T_APPLY)"
|
||||
%token T_TO "to (T_TO)"
|
||||
%token T_WHERE "where (T_WHERE)"
|
||||
%type <text> identifier
|
||||
%type <array> array
|
||||
%type <array> array_items
|
||||
|
@ -158,7 +163,7 @@ statements: /* empty */
|
|||
| statements statement
|
||||
;
|
||||
|
||||
statement: object | type | include | include_recursive | library | variable
|
||||
statement: object | type | include | include_recursive | library | variable | apply
|
||||
;
|
||||
|
||||
include: T_INCLUDE value
|
||||
|
@ -672,4 +677,18 @@ value: simplevalue
|
|||
delete $1;
|
||||
}
|
||||
;
|
||||
|
||||
optional_template: /* empty */
|
||||
| T_TEMPLATE
|
||||
;
|
||||
|
||||
apply: T_APPLY optional_template identifier identifier T_TO identifier T_WHERE aterm
|
||||
{
|
||||
if (!ApplyRule::IsValidCombination($3, $6)) {
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("'apply' cannot be used with types '" + String($3) + "' and '" + String($6) + "'."));
|
||||
}
|
||||
|
||||
ApplyRule::AddRule($3, $4, $6, *$8, yylloc);
|
||||
delete $8;
|
||||
}
|
||||
%%
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "config/configitem.h"
|
||||
#include "config/configcompilercontext.h"
|
||||
#include "config/applyrule.h"
|
||||
#include "base/application.h"
|
||||
#include "base/dynamictype.h"
|
||||
#include "base/objectlock.h"
|
||||
|
@ -303,6 +304,9 @@ bool ConfigItem::ActivateItems(bool validateOnly)
|
|||
|
||||
upq.Join();
|
||||
|
||||
Log(LogInformation, "config", "Evaluating 'apply' rules...");
|
||||
ApplyRule::EvaluateRules();
|
||||
|
||||
Log(LogInformation, "config", "Validating config items (step 2)...");
|
||||
|
||||
BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
|
||||
|
|
|
@ -43,7 +43,7 @@ add_library(icinga SHARED
|
|||
api.cpp api.h checkcommand.cpp checkcommand.th checkresult.cpp checkresult.th
|
||||
cib.cpp command.cpp command.th comment.cpp comment.th compatutility.cpp dependency.cpp dependency.th
|
||||
domain.cpp domain.th downtime.cpp downtime.th eventcommand.cpp eventcommand.th
|
||||
externalcommandprocessor.cpp host.cpp host.th hostgroup.cpp hostgroup.th
|
||||
externalcommandprocessor.cpp host.cpp host.th host-apply.cpp hostgroup.cpp hostgroup.th
|
||||
icingaapplication.cpp icingaapplication.th icingastatuswriter.cpp
|
||||
icingastatuswriter.th legacytimeperiod.cpp
|
||||
macroprocessor.cpp macroresolver.cpp notificationcommand.cpp notificationcommand.th
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-present 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 "icinga/host.h"
|
||||
#include "config/configitembuilder.h"
|
||||
#include "base/initialize.h"
|
||||
#include "base/dynamictype.h"
|
||||
#include "base/convert.h"
|
||||
#include "base/logger_fwd.h"
|
||||
#include "base/context.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
INITIALIZE_ONCE(&Host::RegisterApplyRuleHandler);
|
||||
|
||||
void Host::RegisterApplyRuleHandler(void)
|
||||
{
|
||||
ApplyRule::RegisterCombination("Service", "Host", &Host::EvaluateApplyRules);
|
||||
}
|
||||
|
||||
void Host::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
|
||||
{
|
||||
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjects<Host>()) {
|
||||
CONTEXT("Evaluating 'apply' rules for Host '" + host->GetName() + "'");
|
||||
|
||||
Dictionary::Ptr locals = make_shared<Dictionary>();
|
||||
locals->Set("host", host->GetName());
|
||||
|
||||
BOOST_FOREACH(const ApplyRule& rule, rules) {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Evaluating 'apply' rule (" << rule.GetDebugInfo() << ")";
|
||||
CONTEXT(msgbuf.str());
|
||||
|
||||
Value result = rule.GetExpression()->Evaluate(locals);
|
||||
|
||||
try {
|
||||
if (!static_cast<bool>(result))
|
||||
continue;
|
||||
} catch (...) {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Apply rule (" << rule.GetDebugInfo() << ") returned invalid data type, expected bool: " + JsonSerialize(result);
|
||||
Log(LogCritical, "icinga", msgbuf.str());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result.IsEmpty())
|
||||
continue;
|
||||
|
||||
std::ostringstream namebuf;
|
||||
namebuf << host->GetName() << "!apply!" << rule.GetTemplate();
|
||||
String name = namebuf.str();
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(rule.GetDebugInfo());
|
||||
builder->SetType("Service");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host", OperatorSet, host->GetName());
|
||||
|
||||
builder->AddParent(rule.GetTemplate());
|
||||
|
||||
ConfigItem::Ptr serviceItem = builder->Compile();
|
||||
serviceItem->Register();
|
||||
DynamicObject::Ptr dobj = serviceItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
|
||||
Log(LogInformation, "icinga", "Rule result: " + Convert::ToString(result));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
#include "icinga/host.th"
|
||||
#include "icinga/macroresolver.h"
|
||||
#include "icinga/checkresult.h"
|
||||
#include "config/applyrule.h"
|
||||
#include "base/array.h"
|
||||
#include "base/dictionary.h"
|
||||
|
||||
|
@ -101,6 +102,9 @@ public:
|
|||
|
||||
virtual bool ResolveMacro(const String& macro, const CheckResult::Ptr& cr, String *result) const;
|
||||
|
||||
static void RegisterApplyRuleHandler(void);
|
||||
static void EvaluateApplyRules(const std::vector<ApplyRule>& rules);
|
||||
|
||||
protected:
|
||||
virtual void Stop(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue