Implement support for constants in the config parser.

Refs #4946
This commit is contained in:
Gunnar Beutner 2013-12-04 11:04:36 +01:00
parent 25cece444d
commit e540685e13
9 changed files with 102 additions and 55 deletions

View File

@ -273,12 +273,21 @@ Parent objects are resolved in the order they're specified using the
### Variables
Global variables can be set using the `set` keyword:
Global variables can be set using the `var` and `const` keywords:
set VarName = "some value"
var VarName = "some value"
The value can be a string, number, array or a dictionary.
Variables can be set multiple times unless they were introduced using
the `const` keyword.
> **Note**
>
> The `set` keyword is an alias for the `var` keyword and is available
> in order to provide compatibility with older versions. Its use is
> deprecated.
### Constant Expressions
Simple calculations can be performed using the constant expression syntax:
@ -287,7 +296,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:
{
@ -296,7 +305,7 @@ overridden by grouping expressions using parentheses:
Global variables may be used in constant expressions.
set MyCheckInterval = 10m
var MyCheckInterval = 10m
...

View File

@ -1,7 +1,7 @@
/**
* Global macros
*/
set IcingaMacros = {
var IcingaMacros = {
plugindir = "/usr/lib/nagios/plugins"
}

View File

@ -335,6 +335,8 @@ int main(int argc, char **argv)
Application::DeclareStatePath(Application::GetLocalStateDir() + "/lib/icinga2/icinga2.state");
Application::DeclarePidPath(Application::GetLocalStateDir() + "/run/icinga2/icinga2.pid");
Application::MakeVariablesConstant();
Log(LogInformation, "icinga-app", "Icinga application loader (version: " + Application::GetVersion() + ")");
String appType = LoadAppType(Application::GetApplicationType());

View File

@ -17,68 +17,68 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
set StateOK = (0)
set StateWarning = (1)
set StateCritical = (2)
set StateUnknown = (3)
const StateOK = 0
const StateWarning = 1
const StateCritical = 2
const StateUnknown = 3
/*
* Converting states to their filter values: 1<<state
*/
set StateFilterOK = (1<<StateOK)
set StateFilterWarning = (1<<StateWarning)
set StateFilterCritical = (1<<StateCritical)
set StateFilterUnknown = (1<<StateUnknown)
const StateFilterOK = (1<<StateOK)
const StateFilterWarning = (1<<StateWarning)
const StateFilterCritical = (1<<StateCritical)
const StateFilterUnknown = (1<<StateUnknown)
set NotificationDowntimeStart = (0)
set NotificationDowntimeEnd = (1)
set NotificationDowntimeRemoved = (2)
set NotificationCustom = (3)
set NotificationAcknowledgement = (4)
set NotificationProblem = (5)
set NotificationRecovery = (6)
set NotificationFlappingStart = (7)
set NotificationFlappingEnd = (8)
const NotificationDowntimeStart = 0
const NotificationDowntimeEnd = 1
const NotificationDowntimeRemoved = 2
const NotificationCustom = 3
const NotificationAcknowledgement = 4
const NotificationProblem = 5
const NotificationRecovery = 6
const NotificationFlappingStart = 7
const NotificationFlappingEnd = 8
/*
* Converting notification types to their filter values: 1<<type
*/
set NotificationFilterDowntimeStart = (1<<NotificationDowntimeStart)
set NotificationFilterDowntimeEnd = (1<<NotificationDowntimeEnd)
set NotificationFilterDowntimeRemoved = (1<<NotificationDowntimeRemoved)
set NotificationFilterCustom = (1<<NotificationCustom)
set NotificationFilterAcknowledgement = (1<<NotificationAcknowledgement)
set NotificationFilterProblem = (1<<NotificationProblem)
set NotificationFilterRecovery = (1<<NotificationRecovery)
set NotificationFilterFlappingStart = (1<<NotificationFlappingStart)
set NotificationFilterFlappingEnd = (1<<NotificationFlappingEnd)
const NotificationFilterDowntimeStart = (1<<NotificationDowntimeStart)
const NotificationFilterDowntimeEnd = (1<<NotificationDowntimeEnd)
const NotificationFilterDowntimeRemoved = (1<<NotificationDowntimeRemoved)
const NotificationFilterCustom = (1<<NotificationCustom)
const NotificationFilterAcknowledgement = (1<<NotificationAcknowledgement)
const NotificationFilterProblem = (1<<NotificationProblem)
const NotificationFilterRecovery = (1<<NotificationRecovery)
const NotificationFilterFlappingStart = (1<<NotificationFlappingStart)
const NotificationFilterFlappingEnd = (1<<NotificationFlappingEnd)
/*
* Domain privilege flags
*/
set DomainPrivRead = (1<<0)
set DomainPrivCheckResult = (1<<1)
set DomainPrivCommand = (1<<2)
const DomainPrivRead = (1<<0)
const DomainPrivCheckResult = (1<<1)
const DomainPrivCommand = (1<<2)
set DomainPrivReadOnly = (DomainPrivRead)
set DomainPrivReadWrite = (DomainPrivRead | DomainPrivCheckResult | DomainPrivCommand)
const DomainPrivReadOnly = (DomainPrivRead)
const DomainPrivReadWrite = (DomainPrivRead | DomainPrivCheckResult | DomainPrivCommand)
/*
* IDO filter categories
*/
set DbCatConfig = (1 << 0)
set DbCatState = (1 << 1)
set DbCatAcknowledgement = (1 << 2)
set DbCatComment = (1 << 3)
set DbCatDowntime = (1 << 4)
set DbCatEventHandler = (1 << 5)
set DbCatExternalCommand = (1 << 6)
set DbCatFlapping = (1 << 7)
set DbCatCheck = (1 << 8)
set DbCatLog = (1 << 9)
set DbCatNotification = (1 << 10)
set DbCatProgramStatus = (1 << 11)
set DbCatRetention = (1 << 12)
set DbCatStateHistory = (1 << 13)
const DbCatConfig = (1 << 0)
const DbCatState = (1 << 1)
const DbCatAcknowledgement = (1 << 2)
const DbCatComment = (1 << 3)
const DbCatDowntime = (1 << 4)
const DbCatEventHandler = (1 << 5)
const DbCatExternalCommand = (1 << 6)
const DbCatFlapping = (1 << 7)
const DbCatCheck = (1 << 8)
const DbCatLog = (1 << 9)
const DbCatNotification = (1 << 10)
const DbCatProgramStatus = (1 << 11)
const DbCatRetention = (1 << 12)
const DbCatStateHistory = (1 << 13)
set DbCatEverything = (~0)
const DbCatEverything = (~0)

View File

@ -730,6 +730,17 @@ void Application::DeclareApplicationType(const String& type)
ScriptVariable::Set("ApplicationType", type, false);
}
void Application::MakeVariablesConstant(void)
{
ScriptVariable::GetByName("IcingaPrefixDir")->SetConstant(true);
ScriptVariable::GetByName("IcingaSysconfDir")->SetConstant(true);
ScriptVariable::GetByName("IcingaLocalStateDir")->SetConstant(true);
ScriptVariable::GetByName("IcingaPkgDataDir")->SetConstant(true);
ScriptVariable::GetByName("IcingaStatePath")->SetConstant(true);
ScriptVariable::GetByName("IcingaPidPath")->SetConstant(true);
ScriptVariable::GetByName("ApplicationType")->SetConstant(true);
}
/**
* Returns the global thread pool.
*

View File

@ -91,6 +91,8 @@ public:
static String GetApplicationType(void);
static void DeclareApplicationType(const String& type);
static void MakeVariablesConstant(void);
static ThreadPool& GetTP(void);
static String GetVersion(void);

View File

@ -71,6 +71,9 @@ ScriptVariable::Ptr ScriptVariable::Set(const String& name, const Value& value,
sv = make_shared<ScriptVariable>(value);
ScriptVariableRegistry::GetInstance()->Register(name, sv);
} else if (overwrite) {
if (sv->IsConstant())
BOOST_THROW_EXCEPTION(std::invalid_argument("Tried to modify read-only script variable '" + name + "'"));
sv->SetData(value);
}

View File

@ -219,7 +219,9 @@ null return T_NULL;
partial return T_PARTIAL;
true { yylval->num = 1; return T_NUMBER; }
false { yylval->num = 0; return T_NUMBER; }
set return T_SET;
set return T_VAR;
var return T_VAR;
const return T_CONST;
\<\< return T_SHIFT_LEFT;
\>\> return T_SHIFT_RIGHT;
[a-zA-Z_][:a-zA-Z0-9\-_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; }

View File

@ -74,7 +74,8 @@ using namespace icinga;
%token <op> T_MINUS_EQUAL "-= (T_MINUS_EQUAL)"
%token <op> T_MULTIPLY_EQUAL "*= (T_MULTIPLY_EQUAL)"
%token <op> T_DIVIDE_EQUAL "/= (T_DIVIDE_EQUAL)"
%token T_SET "set (T_SET)"
%token T_VAR "var (T_VAR)"
%token T_CONST "const (T_CONST)"
%token T_SHIFT_LEFT "<< (T_SHIFT_LEFT)"
%token T_SHIFT_RIGHT ">> (T_SHIFT_RIGHT)"
%token <type> T_TYPE_DICTIONARY "dictionary (T_TYPE_DICTIONARY)"
@ -113,6 +114,7 @@ using namespace icinga;
%type <slist> object_inherits_specifier
%type <aexpr> aterm
%type <aexpr> aexpression
%type <num> variable_decl
%left '+' '-'
%left '*' '/'
%left '&'
@ -187,8 +189,9 @@ library: T_LIBRARY T_STRING
context->HandleLibrary($2);
free($2);
}
;
variable: T_SET identifier T_EQUAL value
variable: variable_decl identifier T_EQUAL value
{
Value *value = $4;
if (value->IsObjectType<ExpressionList>()) {
@ -199,10 +202,25 @@ variable: T_SET identifier T_EQUAL value
value = new Value(dict);
}
ScriptVariable::Set($2, *value);
ScriptVariable::Ptr sv = ScriptVariable::Set($2, *value);
if (!$1)
sv->SetConstant(true);
free($2);
delete value;
}
;
variable_decl: T_VAR
{
$$ = true;
}
| T_CONST
{
$$ = false;
}
;
identifier: T_IDENTIFIER
| T_STRING