diff --git a/doc/4.1-configuration-syntax.md b/doc/4.1-configuration-syntax.md index 27a812a53..2c02c9f17 100644 --- a/doc/4.1-configuration-syntax.md +++ b/doc/4.1-configuration-syntax.md @@ -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 ... diff --git a/etc/icinga2/conf.d/macros.conf b/etc/icinga2/conf.d/macros.conf index fc270e231..696b3a58d 100644 --- a/etc/icinga2/conf.d/macros.conf +++ b/etc/icinga2/conf.d/macros.conf @@ -1,7 +1,7 @@ /** * Global macros */ -set IcingaMacros = { +var IcingaMacros = { plugindir = "/usr/lib/nagios/plugins" } diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index d10671b70..f41db959d 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -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()); diff --git a/itl/constants.conf b/itl/constants.conf index 9bea23778..09b2e2656 100644 --- a/itl/constants.conf +++ b/itl/constants.conf @@ -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<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. * diff --git a/lib/base/application.h b/lib/base/application.h index 720f43c70..583980c35 100644 --- a/lib/base/application.h +++ b/lib/base/application.h @@ -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); diff --git a/lib/base/scriptvariable.cpp b/lib/base/scriptvariable.cpp index 7b7f454de..7e8a50d07 100644 --- a/lib/base/scriptvariable.cpp +++ b/lib/base/scriptvariable.cpp @@ -71,6 +71,9 @@ ScriptVariable::Ptr ScriptVariable::Set(const String& name, const Value& value, sv = make_shared(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); } diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll index 7ea8a11b5..9ca7ee52f 100644 --- a/lib/config/config_lexer.ll +++ b/lib/config/config_lexer.ll @@ -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; } diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 3798dce4a..6d8b9f035 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -74,7 +74,8 @@ using namespace icinga; %token T_MINUS_EQUAL "-= (T_MINUS_EQUAL)" %token T_MULTIPLY_EQUAL "*= (T_MULTIPLY_EQUAL)" %token 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 T_TYPE_DICTIONARY "dictionary (T_TYPE_DICTIONARY)" @@ -113,6 +114,7 @@ using namespace icinga; %type object_inherits_specifier %type aterm %type aexpression +%type 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()) { @@ -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