]> granicus.if.org Git - icinga2/commitdiff
Implement support for constants in the config parser.
authorGunnar Beutner <gunnar.beutner@netways.de>
Wed, 4 Dec 2013 10:04:36 +0000 (11:04 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Wed, 4 Dec 2013 10:32:45 +0000 (11:32 +0100)
Refs #4946

doc/4.1-configuration-syntax.md
etc/icinga2/conf.d/macros.conf
icinga-app/icinga.cpp
itl/constants.conf
lib/base/application.cpp
lib/base/application.h
lib/base/scriptvariable.cpp
lib/config/config_lexer.ll
lib/config/config_parser.yy

index 27a812a5360742326a3fa086f41aa0f9eb2a5548..2c02c9f1725b1e5923d4f9234219280fd6d3f23a 100644 (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
 
     ...
 
index fc270e231a2bde7fbae9a4e3e0e75ae5a06a9dda..696b3a58dd30f055c99eccd31489826a538e312e 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * Global macros
  */
-set IcingaMacros = {
+var IcingaMacros = {
   plugindir = "/usr/lib/nagios/plugins"
 }
 
index d10671b70f468798070a87fb5b4839ae52659cfd..f41db959d0a90ecf75a77364071154ea076af3ce 100644 (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());
index 9bea2377835f302697b122d4c0ada20fcc10bd76..09b2e26563178d71faef199e7bf4ac6ad2faebce 100644 (file)
  * 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)
index ca7ea167dbed04a5d642094547e989e4542db30f..7a8564875af66f6d9d764cd27f0af444474de99e 100644 (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.
  *
index 720f43c703a8e19b7e9fddaa959ea9828cd4722b..583980c3559e2301289839ea82c9f1139e7a7a01 100644 (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);
index 7b7f454de8ef997699b60182c9ae185d24ed2a94..7e8a50d07b8943a7a4bf533a5b815ef3a01758b3 100644 (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);
        }
 
index 7ea8a11b57be5aa34899f56800ce2206ccd21f7c..9ca7ee52fb1986f17fc4786425ade83599329f49 100644 (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; }
index 3798dce4a8fee13fa55785c52d5c2aefc57aeb27..6d8b9f0359e2b1d79ab4ff1add631cf260d59e76 100644 (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