]> granicus.if.org Git - icinga2/blob - doc/17-language-reference.md
Merge pull request #7347 from Icinga/feature/docs-tls-security
[icinga2] / doc / 17-language-reference.md
1 # Language Reference <a id="language-reference"></a>
2
3 ## Object Definition <a id="object-definition"></a>
4
5 Icinga 2 features an object-based configuration format. You can define new
6 objects using the `object` keyword:
7
8 ```
9 object Host "host1.example.org" {
10   display_name = "host1"
11
12   address = "192.168.0.1"
13   address6 = "2001:db8:1234::42"
14 }
15 ```
16
17 In general you need to write each statement on a new line. Expressions started
18 with `{`, `(` and `[` extend until the matching closing character and can be broken
19 up into multiple lines.
20
21 Alternatively you can write multiple statements on a single line by separating
22 them with a semicolon:
23
24 ```
25 object Host "host1.example.org" {
26   display_name = "host1"
27
28   address = "192.168.0.1"; address6 = "2001:db8:1234::42"
29 }
30 ```
31
32 Each object is uniquely identified by its type (`Host`) and name
33 (`host1.example.org`). Some types have composite names, e.g. the
34 `Service` type which uses the `host_name` attribute and the name
35 you specified to generate its object name.
36
37 Exclamation marks (!) are not permitted in object names.
38
39 Objects can contain a comma-separated list of property
40 declarations. Instead of commas semicolons may also be used.
41 The following data types are available for property values:
42
43 All objects have at least the following attributes:
44
45 Attribute            | Description
46 ---------------------|-----------------------------
47 name                 | The name of the object. This attribute can be modified in the object definition to override the name specified with the `object` directive.
48 type                 | The type of the object.
49
50 ## Expressions <a id="expressions"></a>
51
52 The following expressions can be used on the right-hand side of assignments.
53
54 ### Numeric Literals <a id="numeric-literals"></a>
55
56 A floating-point number.
57
58 Example:
59
60 ```
61 27.3
62 ```
63
64 ### Duration Literals <a id="duration-literals"></a>
65
66 Similar to floating-point numbers except for the fact that they support
67 suffixes to help with specifying time durations.
68
69 Example:
70
71 ```
72 2.5m
73 ```
74
75 Supported suffixes include ms (milliseconds), s (seconds), m (minutes),
76 h (hours) and d (days).
77
78 Duration literals are converted to seconds by the config parser and
79 are treated like numeric literals.
80
81 ### String Literals <a id="string-literals"></a>
82
83 A string.
84
85 Example:
86
87 ```
88 "Hello World!"
89 ```
90
91 #### String Literals Escape Sequences <a id="string-literals-escape-sequences"></a>
92
93 Certain characters need to be escaped. The following escape sequences
94 are supported:
95
96 Character                 | Escape sequence
97 --------------------------|------------------------------------
98 "                         | \\"
99 \\                        | \\\\
100 &lt;TAB&gt;               | \\t
101 &lt;CARRIAGE-RETURN&gt;   | \\r
102 &lt;LINE-FEED&gt;         | \\n
103 &lt;BEL&gt;               | \\b
104 &lt;FORM-FEED&gt;         | \\f
105
106 In addition to these pre-defined escape sequences you can specify
107 arbitrary ASCII characters using the backslash character (\\) followed
108 by an ASCII character in octal encoding.
109
110 ### Multi-line String Literals <a id="multiline-string-literals"></a>
111
112 Strings spanning multiple lines can be specified by enclosing them in
113 {{{ and }}}.
114
115 Example:
116
117 ```
118 {{{This
119 is
120 a multi-line
121 string.}}}
122 ```
123
124 Unlike in ordinary strings special characters do not have to be escaped
125 in multi-line string literals.
126
127 ### Boolean Literals <a id="boolean-literals"></a>
128
129 The keywords `true` and `false` are used to denote truth values.
130
131 ### Null Value <a id="null-value"></a>
132
133 The `null` keyword can be used to specify an empty value.
134
135 ### Dictionary <a id="dictionary"></a>
136
137 An unordered list of key-value pairs. Keys must be unique and are
138 compared in a case-sensitive manner.
139
140 Individual key-value pairs must either be comma-separated or on separate lines.
141 The comma after the last key-value pair is optional.
142
143 Example:
144
145 ```
146 {
147   address = "192.168.0.1"
148   port = 443
149 }
150 ```
151
152 Identifiers may not contain certain characters (e.g. space) or start
153 with certain characters (e.g. digits). If you want to use a dictionary
154 key that is not a valid identifier, you can enclose the key in double
155 quotes.
156
157 ### Array <a id="array"></a>
158
159 An ordered list of values.
160
161 Individual array elements must be comma-separated.
162 The comma after the last element is optional.
163
164 Example:
165
166 ```
167 [ "hello", 42 ]
168 ```
169
170 An array may simultaneously contain values of different types, such as
171 strings and numbers.
172
173 ### Operators <a id="expression-operators"></a>
174
175 The following operators are supported in expressions. The operators are sorted by descending precedence.
176
177 Operator | Precedence | Examples (Result)                             | Description
178 ---------|------------|-----------------------------------------------|--------------------------------
179 `()`       | 1          | (3 + 3) * 5                                   | Groups sub-expressions
180 `()`       | 1          | Math.random()                                 | Calls a function
181 `[]`       | 1          | a[3]                                          | Array subscript
182 `.`       | 1          | a.b                                           | Element access
183 `!`        | 2          | !"Hello" (false), !false (true)               | Logical negation of the operand
184 `~`        | 2          | ~true (false)                                 | Bitwise negation of the operand
185 `+`        | 2          | +3                                            | Unary plus
186 `-`        | 2          | -3                                            | Unary minus
187 `&`        | 2          | &var (reference to 'var')                     | Reference operator
188 `*`        | 2          | *var                                          | Indirection operator
189 `*`        | 3          | 5m * 10 (3000)                                | Multiplies two numbers
190 `/`        | 3          | 5m / 5 (60)                                   | Divides two numbers
191 `%`        | 3          | 17 % 12 (5)                                   | Remainder after division
192 `+`        | 4          | 1 + 3 (4), "hello " + "world" ("hello world") | Adds two numbers; concatenates strings
193 `-`        | 4          | 3 - 1 (2)                                     | Subtracts two numbers
194 `<<`       | 5          | 4 << 8 (1024)                                 | Left shift
195 `>>`       | 5          | 1024 >> 4 (64)                                | Right shift
196 `<`        | 6         | 3 < 5 (true)                                  | Less than
197 `>`        | 6         | 3 > 5 (false)                                 | Greater than
198 `<=`       | 6         | 3 <= 3 (true)                                 | Less than or equal
199 `>=`       | 6         | 3 >= 3 (true)                                 | Greater than or equal
200 `in`       | 7          | "foo" in [ "foo", "bar" ] (true)              | Element contained in array
201 `!in`      | 7          | "foo" !in [ "bar", "baz" ] (true)             | Element not contained in array
202 `==`       | 8         | "hello" == "hello" (true), 3 == 5 (false)     | Equal to
203 `!=`       | 8         | "hello" != "world" (true), 3 != 3 (false)     | Not equal to
204 `&`        | 9          | 7 & 3 (3)                                     | Binary AND
205 `^`        | 10          | 17 ^ 12 (29)                                  | Bitwise XOR
206 <code>&#124;</code>    | 11          | 2 &#124; 3 (3)                                | Binary OR
207 <code>&#124;&#124;</code>  | 12     | true &#124;&#124; false (true), 0 &#124;&#124; 7 (7)| Logical OR
208 `&&`       | 13         | true && false (false), 3 && 7 (7), 0 && 7 (0) | Logical AND
209 `=`        | 14         | a = 3                                         | Assignment
210 `=>`       | 15         | x => x * x (function with arg x)              | Lambda, for loop
211
212 ### References <a id="references"></a>
213
214 A reference to a value can be obtained using the `&` operator. The `*` operator can be used
215 to dereference a reference:
216
217 ```
218 var value = "Hello!"
219 var p = &value /* p refers to value */
220 *p = "Hi!"
221 log(value) // Prints "Hi!" because the variable was changed
222 ```
223
224 ### Namespaces <a id="namespaces"></a>
225
226 Namespaces can be used to organize variables and functions. They are used to avoid name conflicts. The `namespace`
227 keyword is used to create a new namespace:
228
229 ```
230 namespace Utils {
231     function calculate() {
232         return 2 + 2
233     }
234 }
235 ```
236
237 The namespace is made available as a global variable which has the namespace's name (e.g. `Utils`):
238
239 ```
240 Utils.calculate()
241 ```
242
243 The `using` keyword can be used to make all attributes in a namespace available to a script without having to
244 explicitly specify the namespace's name for each access:
245
246 ```
247 using Utils
248 calculate()
249 ```
250
251 The `using` keyword only has an effect for the current file and only for code that follows the keyword:
252
253 ```
254 calculate() // This will not work.
255 using Utils
256 ```
257
258 The following namespaces are automatically imported as if by using the `using` keyword:
259
260 * System
261 * System.Configuration
262 * Types
263 * Icinga
264
265 ### Function Calls <a id="function-calls"></a>
266
267 Functions can be called using the `()` operator:
268
269 ```
270 const MyGroups = [ "test1", "test" ]
271
272 {
273   check_interval = len(MyGroups) * 1m
274 }
275 ```
276
277 A list of available functions is available in the [Library Reference](18-library-reference.md#library-reference) chapter.
278
279 ## Assignments <a id="dictionary-operators"></a>
280
281 In addition to the `=` operator shown above a number of other operators
282 to manipulate attributes are supported. Here's a list of all
283 available operators (the outermost `{` `}` stand for a local variable scope):
284
285 ### Operator = <a id="operator-assignment"></a>
286
287 Sets an attribute to the specified value.
288
289 Example:
290
291 ```
292 {
293   a = 5
294   a = 7
295 }
296 ```
297
298 In this example `a` has the value `7` after both instructions are executed.
299
300 ### Operator += <a id="operator-additive-assignment"></a>
301
302 The += operator is a shortcut. The following expression:
303
304 ```
305 {
306   a = [ "hello" ]
307   a += [ "world" ]
308 }
309 ```
310
311 is equivalent to:
312
313 ```
314 {
315   a = [ "hello" ]
316   a = a + [ "world" ]
317 }
318 ```
319
320 ### Operator -= <a id="operator-substractive-assignment"></a>
321
322 The -= operator is a shortcut. The following expression:
323
324 ```
325 {
326   a = 10
327   a -= 5
328 }
329 ```
330
331 is equivalent to:
332
333 ```
334 {
335   a = 10
336   a = a - 5
337 }
338 ```
339
340 ### Operator \*= <a id="operator-multiply-assignment"></a>
341
342 The *= operator is a shortcut. The following expression:
343
344 ```
345 {
346   a = 60
347   a *= 5
348 }
349 ```
350
351 is equivalent to:
352
353 ```
354 {
355   a = 60
356   a = a * 5
357 }
358 ```
359
360 ### Operator /= <a id="operator-dividing-assignment"></a>
361
362 The /= operator is a shortcut. The following expression:
363
364 ```
365 {
366   a = 300
367   a /= 5
368 }
369 ```
370
371 is equivalent to:
372
373 ```
374 {
375   a = 300
376   a = a / 5
377 }
378 ```
379
380 ## Indexer <a id="indexer"></a>
381
382 The indexer syntax provides a convenient way to set dictionary elements.
383
384 Example:
385
386 ```
387 {
388   hello.key = "world"
389 }
390 ```
391
392 Example (alternative syntax):
393
394 ```
395 {
396   hello["key"] = "world"
397 }
398 ```
399
400 This is equivalent to writing:
401
402 ```
403 {
404   hello += {
405     key = "world"
406   }
407 }
408 ```
409
410 If the `hello` attribute does not already have a value, it is automatically initialized to an empty dictionary.
411
412 ## Template Imports <a id="template-imports"></a>
413
414 Objects can import attributes from other objects.
415
416 Example:
417
418 ```
419 template Host "default-host" {
420   vars.colour = "red"
421 }
422
423 template Host "test-host" {
424   import "default-host"
425
426   vars.colour = "blue"
427 }
428
429 object Host "localhost" {
430   import "test-host"
431
432   address = "127.0.0.1"
433   address6 = "::1"
434 }
435 ```
436
437 The `default-host` and `test-host` objects are marked as templates
438 using the `template` keyword. Unlike ordinary objects templates are not
439 instantiated at run-time. Parent objects do not necessarily have to be
440 templates, however in general they are.
441
442 The `vars` dictionary for the `localhost` object contains all three
443 custom variables and the custom variable `colour` has the value `"blue"`.
444
445 Parent objects are resolved in the order they're specified using the
446 `import` keyword.
447
448 Default templates which are automatically imported into all object definitions
449 can be specified using the `default` keyword:
450
451 ```
452 template CheckCommand "plugin-check-command" default {
453   // ...
454 }
455 ```
456
457 Default templates are imported before any other user-specified statement in an
458 object definition is evaluated.
459
460 If there are multiple default templates the order in which they are imported
461 is unspecified.
462
463 ## Constants <a id="constants"></a>
464
465 Global constants can be set using the `const` keyword:
466
467 ```
468 const VarName = "some value"
469 ```
470
471 Once defined a constant can be accessed from any file. Constants cannot be changed
472 once they are set.
473
474 > **Tip**
475 >
476 > Best practice is to manage constants in the [constants.conf](04-configuration.md#constants-conf) file.
477
478 ### Icinga 2 Specific Constants <a id="icinga-constants"></a>
479
480 Icinga 2 provides a number of special global constants. These include directory paths, global configuration
481 and runtime parameters for the application version and (build) platform.
482
483 #### Directory Path Constants <a id="icinga-constants-director-path"></a>
484
485 Constant            | Description
486 --------------------|-------------------
487 ConfigDir           |**Read-only.** Main configuration directory. Usually set to `/etc/icinga2`.
488 DataDir             |**Read-only.** Runtime data for the Icinga daemon. Usually set to `/var/lib/icinga2`.
489 LogDir              |**Read-only.** Logfiles from the daemon. Usually set to `/var/log/icinga2`.
490 CacheDir            |**Read-only.** Cached status information of the daemon. Usually set to `/var/cache/icinga2`.
491 SpoolDir            |**Read-only.** Spool directory for certain data outputs. Usually set to `/var/spool/icinga2`.
492 InitRunDir          |**Read-only.** Directory for PID files and sockets in daemon mode. Usually set to `/run/icinga2`.
493 ZonesDir            |**Read-only.** Contains the path of the zones.d directory. Defaults to `ConfigDir + "/zones.d"`.
494
495 #### Global Configuration Constants <a id="icinga-constants-global-config"></a>
496
497 Constant            | Description
498 --------------------|-------------------
499 Vars                |**Read-write.** Contains a dictionary with global custom variables. Not set by default.
500 NodeName            |**Read-write.** Contains the cluster node name. Set to the local hostname by default.
501 ReloadTimeout       |**Read-write.** Defines the reload timeout for child processes. Defaults to `300s`.
502 Environment         |**Read-write.** The name of the Icinga environment. Included in the SNI host name for outbound connections. Not set by default.
503 RunAsUser           |**Read-write.** Defines the user the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
504 RunAsGroup          |**Read-write.** Defines the group the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
505 MaxConcurrentChecks |**Read-write.** The number of max checks run simultaneously. Defaults to `512`.
506 ApiBindHost         |**Read-write.** Overrides the default value for the ApiListener `bind_host` attribute. Not set by default.
507 ApiBindPort         |**Read-write.** Overrides the default value for the ApiListener `bind_port` attribute. Not set by default.
508
509 #### Application Runtime Constants <a id="icinga-constants-application-runtime"></a>
510
511 Constant            | Description
512 --------------------|-------------------
513 PlatformName        |**Read-only.** The name of the operating system, e.g. `Ubuntu`.
514 PlatformVersion     |**Read-only.** The version of the operating system, e.g. `14.04.3 LTS`.
515 PlatformKernel      |**Read-only.** The name of the operating system kernel, e.g. `Linux`.
516 PlatformKernelVersion|**Read-only.** The version of the operating system kernel, e.g. `3.13.0-63-generic`.
517 BuildCompilerName   |**Read-only.** The name of the compiler Icinga was built with, e.g. `Clang`.
518 BuildCompilerVersion|**Read-only.** The version of the compiler Icinga was built with, e.g. `7.3.0.7030031`.
519 BuildHostName       |**Read-only.** The name of the host Icinga was built on, e.g. `acheron`.
520 ApplicationVersion  |**Read-only.** The application version, e.g. `2.9.0`.
521
522 #### Additional Constants <a id="icinga-constants-additional"></a>
523
524 Writable constants can be specified on the CLI using the `--define/-D` parameter.
525
526 > **Note for v2.10+**
527 >
528 > Default paths which include `/etc` and `/var` as base directory continue to work
529 > based on the `SysconfDir` and `LocalStateDir` constants respectively.
530
531 In addition to that, the constants below are used to define specific file paths. You should never need
532 to change them, as they are pre-compiled based on the constants above.
533
534 Variable            |Description
535 --------------------|-------------------
536 StatePath           |**Read-write.** Contains the path of the Icinga 2 state file. Defaults to `DataDir + "/icinga2.state"`.
537 ObjectsPath         |**Read-write.** Contains the path of the Icinga 2 objects file. Defaults to `CacheDir + "/icinga2.debug"`.
538 PidPath             |**Read-write.** Contains the path of the Icinga 2 PID file. Defaults to `InitRunDir + "/icinga2.pid"`.
539 PkgDataDir          |**Read-only.** Contains the path of the package data directory. Defaults to `PrefixDir + "/share/icinga2"`.
540
541 The constants below have been used until Icinga v2.10, and are still intact. You don't need them
542 for future builds and configuration based on the newly available constants above.
543
544 Variable            |Description
545 --------------------|-------------------
546 PrefixDir           |**Read-only.** Contains the installation prefix that was specified with `cmake -DCMAKE_INSTALL_PREFIX`. `Defaults to "/usr/local"`.
547 SysconfDir          |**Read-only.** Contains the path of the sysconf directory. Defaults to `PrefixDir + "/etc"`.
548 LocalStateDir       |**Read-only.** Contains the path of the local state directory. Defaults to `PrefixDir + "/var"`.
549 RunDir              |**Read-only.** Contains the path of the run directory. Defaults to `LocalStateDir + "/run"`.
550
551 #### Advanced Constants and Variables <a id="icinga-constants-advanced"></a>
552
553 Advanced runtime constants. Please only use them if advised by support or developers.
554
555 Variable                   | Description
556 ---------------------------|-------------------
557 EventEngine                |**Read-write.** The name of the socket event engine, can be `poll` or `epoll`. The epoll interface is only supported on Linux.
558 AttachDebugger             |**Read-write.** Whether to attach a debugger when Icinga 2 crashes. Defaults to `false`.
559
560 Advanced sysconfig environment variables, defined in `/etc/sysconfig/icinga2` (RHEL/SLES) or `/etc/default/icinga2` (Debian/Ubuntu).
561
562 Variable                   | Description
563 ---------------------------|-------------------
564 ICINGA2\_RLIMIT\_FILES     |**Read-write.** Defines the resource limit for `RLIMIT_NOFILE` that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig.
565 ICINGA2\_RLIMIT\_PROCESSES |**Read-write.** Defines the resource limit for `RLIMIT_NPROC` that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig.
566 ICINGA2\_RLIMIT\_STACK     |**Read-write.** Defines the resource limit for `RLIMIT_STACK` that should be set at start-up. Value cannot be set lower than the default `256 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig.
567
568
569 ## Apply <a id="apply"></a>
570
571 The `apply` keyword can be used to create new objects which are associated with
572 another group of objects.
573
574 ```
575 apply Service "ping" to Host {
576   import "generic-service"
577
578   check_command = "ping4"
579
580   assign where host.name == "localhost"
581 }
582 ```
583
584 In this example the `assign where` condition is a boolean expression which is
585 evaluated for all objects of type `Host` and a new service with name "ping"
586 is created for each matching host. [Expression operators](17-language-reference.md#expression-operators)
587 may be used in `assign where` conditions.
588
589 The `to` keyword and the target type may be omitted if there is only one target
590 type, e.g. for the `Service` type.
591
592 Depending on the object type used in the `apply` expression additional local
593 variables may be available for use in the `where` condition:
594
595 Source Type       | Target Type | Variables
596 ------------------|-------------|--------------
597 Service           | Host        | host
598 Dependency        | Host        | host
599 Dependency        | Service     | host, service
600 Notification      | Host        | host
601 Notification      | Service     | host, service
602 ScheduledDowntime | Host        | host
603 ScheduledDowntime | Service     | host, service
604
605 Any valid config attribute can be accessed using the `host` and `service`
606 variables. For example, `host.address` would return the value of the host's
607 "address" attribute -- or null if that attribute isn't set.
608
609 More usage examples are documented in the [monitoring basics](03-monitoring-basics.md#using-apply-expressions)
610 chapter.
611
612 ## Apply For <a id="apply-for"></a>
613
614 [Apply](17-language-reference.md#apply) rules can be extended with the
615 [for loop](17-language-reference.md#for-loops) keyword.
616
617 ```
618 apply Service "prefix-" for (key => value in host.vars.dictionary) to Host {
619   import "generic-service"
620
621   check_command = "ping4"
622   vars.host_value = value
623 }
624 ```
625
626 Any valid config attribute can be accessed using the `host` and `service`
627 variables. The attribute must be of the Array or Dictionary type. In this example
628 `host.vars.dictionary` is of the Dictionary type which needs a key-value-pair
629 as iterator.
630
631 In this example all generated service object names consist of `prefix-` and
632 the value of the `key` iterator. The prefix string can be omitted if not required.
633
634 The `key` and `value` variables can be used for object attribute assignment, e.g. for
635 setting the `check_command` attribute or custom variables as command parameters.
636
637 `apply for` rules are first evaluated against all objects matching the `for loop` list
638 and afterwards the `assign where` and `ignore where` conditions are evaluated.
639
640 It is not necessary to check attributes referenced in the `for loop` expression
641 for their existance using an additional `assign where` condition.
642
643 More usage examples are documented in the [monitoring basics](03-monitoring-basics.md#using-apply-for)
644 chapter.
645
646 ## Group Assign <a id="group-assign"></a>
647
648 Group objects can be assigned to specific member objects using the `assign where`
649 and `ignore where` conditions.
650
651 ```
652 object HostGroup "linux-servers" {
653   display_name = "Linux Servers"
654
655   assign where host.vars.os == "Linux"
656 }
657 ```
658
659 In this example the `assign where` condition is a boolean expression which is evaluated
660 for all objects of the type `Host`. Each matching host is added as member to the host group
661 with the name "linux-servers". Membership exclusion can be controlled using the `ignore where`
662 condition. [Expression operators](17-language-reference.md#expression-operators) may be used in `assign where` and
663 `ignore where` conditions.
664
665 Source Type       | Variables
666 ------------------|--------------
667 HostGroup         | host
668 ServiceGroup      | host, service
669 UserGroup         | user
670
671
672 ## Boolean Values <a id="boolean-values"></a>
673
674 The `assign where`, `ignore where`, `if` and `while`  statements, the `!` operator as
675 well as the `bool()` function convert their arguments to a boolean value based on the
676 following rules:
677
678 Description          | Example Value     | Boolean Value
679 ---------------------|-------------------|--------------
680 Empty value          | null              | false
681 Zero                 | 0                 | false
682 Non-zero integer     | -23945            | true
683 Empty string         | ""                | false
684 Non-empty string     | "Hello"           | true
685 Empty array          | []                | false
686 Non-empty array      | [ "Hello" ]       | true
687 Empty dictionary     | {}                | false
688 Non-empty dictionary | { key = "value" } | true
689
690 For a list of supported expression operators for `assign where` and `ignore where`
691 statements, see [expression operators](17-language-reference.md#expression-operators).
692
693 ## Comments <a id="comments"></a>
694
695 The Icinga 2 configuration format supports C/C++-style and shell-style comments.
696
697 Example:
698
699 ```
700 /*
701  This is a comment.
702  */
703 object Host "localhost" {
704   check_interval = 30 // this is also a comment.
705   retry_interval = 15 # yet another comment
706 }
707 ```
708
709 ## Includes <a id="includes"></a>
710
711 Other configuration files can be included using the `include` directive.
712 Paths must be relative to the configuration file that contains the
713 `include` directive.
714
715 Example:
716
717 ```
718 include "some/other/file.conf"
719 include "conf.d/*.conf"
720 ```
721
722 Wildcard includes are not recursive.
723
724 Icinga also supports include search paths similar to how they work in a
725 C/C++ compiler:
726
727 ```
728 include <itl>
729 ```
730
731 Note the use of angle brackets instead of double quotes. This causes the
732 config compiler to search the include search paths for the specified
733 file. By default $PREFIX/share/icinga2/include is included in the list of search
734 paths. Additional include search paths can be added using
735 [command-line options](11-cli-commands.md#config-include-path).
736
737 Wildcards are not permitted when using angle brackets.
738
739 ## Recursive Includes <a id="recursive-includes"></a>
740
741 The `include_recursive` directive can be used to recursively include all
742 files in a directory which match a certain pattern.
743
744 Example:
745
746 ```
747 include_recursive "conf.d", "*.conf"
748 include_recursive "templates"
749 ```
750
751 The first parameter specifies the directory from which files should be
752 recursively included.
753
754 The file names need to match the pattern given in the second parameter.
755 When no pattern is specified the default pattern "*.conf" is used.
756
757 ## Zone Includes <a id="zone-includes"></a>
758
759 > **Note**
760 >
761 > This is an internal functionality consumed by Icinga itself.
762 >
763 > The preferred way for users managing configuration files in
764 > zones is to use the [cluster config sync](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync)
765 > or [REST API config packages](12-icinga2-api.md#icinga2-api-config-management).
766
767 The `include_zones` recursively includes all subdirectories for the
768 given path.
769
770 In addition to that it sets the `zone` attribute for all objects created
771 in these subdirectories to the name of the subdirectory.
772
773 Example:
774
775 ```
776 include_zones "etc", "zones.d", "*.conf"
777 include_zones "puppet", "puppet-zones"
778 ```
779
780 The first parameter specifies a tag name for this directive. Each `include_zones`
781 invocation should use a unique tag name. When copying the zones' configuration
782 files Icinga uses the tag name as the name for the destination directory in
783 `/var/lib/icinga2/api/config`.
784
785 The second parameter specifies the directory which contains the subdirectories.
786
787 The file names need to match the pattern given in the third parameter.
788 When no pattern is specified the default pattern "*.conf" is used.
789
790 ## Library directive <a id="library"></a>
791
792 The `library` directive was used to manually load additional
793 libraries. Starting with version 2.9 it is no longer necessary to explicitly load
794 libraries and this directive has no effect.
795
796 ## Functions <a id="functions"></a>
797
798 Functions can be defined using the `function` keyword.
799
800 Example:
801
802 ```
803 function multiply(a, b) {
804   return a * b
805 }
806 ```
807
808 When encountering the `return` keyword further execution of the function is terminated and
809 the specified value is supplied to the caller of the function:
810
811 ```
812 log(multiply(3, 5))
813 ```
814
815 In this example the `multiply` function we declared earlier is invoked with two arguments (3 and 5).
816 The function computes the product of those arguments and makes the result available to the
817 function's caller.
818
819 When no value is supplied for the `return` statement the function returns `null`.
820
821 Functions which do not have a `return` statement have their return value set to the value of the
822 last expression which was performed by the function. For example, we could have also written our
823 `multiply` function like this:
824
825 ```
826 function multiply(a, b) {
827   a * b
828 }
829 ```
830
831 Anonymous functions can be created by omitting the name in the function definition. The
832 resulting function object can be used like any other value:
833
834 ```
835 var fn = function() { 3 }
836
837 fn() /* Returns 3 */
838 ```
839
840 ## Lambda Expressions <a id="lambdas"></a>
841
842 Functions can also be declared using the alternative lambda syntax.
843
844 Example:
845
846 ```
847 f = (x) => x * x
848 ```
849
850 Multiple statements can be used by putting the function body into braces:
851
852 ```
853 f = (x) => {
854   log("Lambda called")
855   x * x
856 }
857 ```
858
859 Just like with ordinary functions the return value is the value of the last statement.
860
861 For lambdas which take exactly one argument the braces around the arguments can be omitted:
862
863 ```
864 f = x => x * x
865 ```
866
867 ## Abbreviated Lambda Syntax <a id="nullary-lambdas"></a>
868
869 Lambdas which take no arguments can also be written using the abbreviated lambda syntax.
870
871 Example:
872
873 ```
874 f = {{ 3 }}
875 ```
876
877 This creates a new function which returns the value 3.
878
879 ## Variable Scopes <a id="variable-scopes"></a>
880
881 When setting a variable Icinga checks the following scopes in this order whether the variable
882 already exists there:
883
884 * Local Scope
885 * `this` Scope
886 * Global Scope
887
888 The local scope contains variables which only exist during the invocation of the current function,
889 object or apply statement. Local variables can be declared using the `var` keyword:
890
891 ```
892 function multiply(a, b) {
893   var temp = a * b
894   return temp
895 }
896 ```
897
898 Each time the `multiply` function is invoked a new `temp` variable is used which is in no way
899 related to previous invocations of the function.
900
901 When setting a variable which has not previously been declared as local using the `var` keyword
902 the `this` scope is used.
903
904 The `this` scope refers to the current object which the function or object/apply statement
905 operates on.
906
907 ```
908 object Host "localhost" {
909   check_interval = 5m
910 }
911 ```
912
913 In this example the `this` scope refers to the "localhost" object. The `check_interval` attribute
914 is set for this particular host.
915
916 You can explicitly access the `this` scope using the `this` keyword:
917
918 ```
919 object Host "localhost" {
920   var check_interval = 5m
921
922   /* This explicitly specifies that the attribute should be set
923    * for the host, if we had omitted `this.` the (poorly named)
924    * local variable `check_interval` would have been modified instead.
925    */
926   this.check_interval = 1m
927 }
928 ```
929 Similarly the keywords `locals` and `globals` are available to access the local and global scope.
930
931 Functions also have a `this` scope. However unlike for object/apply statements the `this` scope for
932 a function is set to whichever object was used to invoke the function. Here's an example:
933
934 ```
935  hm = {
936    h_word = null
937
938    function init(word) {
939      h_word = word
940    }
941  }
942
943  /* Let's invoke the init() function */
944  hm.init("hello")
945 ```
946
947 We're using `hm.init` to invoke the function which causes the value of `hm` to become the `this`
948 scope for this function call.
949
950 ## Closures <a id="closures"></a>
951
952 By default `function`s, `object`s and `apply` rules do not have access to variables declared
953 outside of their scope (except for global variables).
954
955 In order to access variables which are defined in the outer scope the `use` keyword can be used:
956
957 ```
958 function MakeHelloFunction(name) {
959   return function() use(name) {
960     log("Hello, " + name)
961   }
962 }
963 ```
964
965 In this case a new variable `name` is created inside the inner function's scope which has the
966 value of the `name` function argument.
967
968 Alternatively a different value for the inner variable can be specified:
969
970 ```
971 function MakeHelloFunction(name) {
972   return function() use (greeting = "Hello, " + name) {
973     log(greeting)
974   }
975 }
976 ```
977
978 ## Conditional Statements <a id="conditional-statements"></a>
979
980 Sometimes it can be desirable to only evaluate statements when certain conditions are met. The if/else
981 construct can be used to accomplish this.
982
983 Example:
984
985 ```
986 a = 3
987
988 if (a < 5) {
989   a *= 7
990 } else if (a > 10) {
991   a *= 5
992 } else {
993   a *= 2
994 }
995 ```
996
997 An if/else construct can also be used in place of any other value. The value of an if/else statement
998 is the value of the last statement which was evaluated for the branch which was taken:
999
1000 ```
1001 a = if (true) {
1002   log("Taking the 'true' branch")
1003   7 * 3
1004 } else {
1005   log("Taking the 'false' branch")
1006   9
1007 }
1008 ```
1009
1010 This example prints the log message "Taking the 'true' branch" and the `a` variable is set to 21 (7 * 3).
1011
1012 The value of an if/else construct is null if the condition evaluates to false and no else branch is given.
1013
1014 ## While Loops <a id="while-loops"></a>
1015
1016 The `while` statement checks a condition and executes the loop body when the condition evaluates to `true`.
1017 This is repeated until the condition is no longer true.
1018
1019 Example:
1020
1021 ```
1022 var num = 5
1023
1024 while (num > 5) {
1025     log("Test")
1026     num -= 1
1027 }
1028 ```
1029
1030 The `continue` and `break` keywords can be used to control how the loop is executed: The `continue` keyword
1031 skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword
1032 breaks out of the loop.
1033
1034 ## For Loops <a id="for-loops"></a>
1035
1036 The `for` statement can be used to iterate over arrays and dictionaries.
1037
1038 Example:
1039
1040 ```
1041 var list = [ "a", "b", "c" ]
1042
1043 for (var item in list) {
1044   log("Item: " + item)
1045 }
1046 ```
1047
1048 The loop body is evaluated once for each item in the array. The variable `item` is declared as a local
1049 variable just as if the `var` keyword had been used.
1050
1051 Iterating over dictionaries can be accomplished in a similar manner:
1052
1053 ```
1054 var dict = { a = 3, b = 7 }
1055
1056 for (var key => var value in dict) {
1057   log("Key: " + key + ", Value: " + value)
1058 }
1059 ```
1060
1061 The `continue` and `break` keywords can be used to control how the loop is executed: The `continue` keyword
1062 skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword
1063 breaks out of the loop.
1064
1065 The `var` keyword is optional when declaring variables in the loop's header. Variables declared without the `var`
1066 keyword are nonetheless local to the function.
1067
1068 ## Constructors <a id="constructor"></a>
1069
1070 In order to create a new value of a specific type constructor calls may be used.
1071
1072 Example:
1073
1074 ```
1075 var pd = PerfdataValue()
1076 pd.label = "test"
1077 pd.value = 10
1078 ```
1079
1080 You can also try to convert an existing value to another type by specifying it as an argument for the constructor call.
1081
1082 Example:
1083
1084 ```
1085 var s = String(3) /* Sets s to "3". */
1086 ```
1087
1088 ## Throwing Exceptions <a id="throw"></a>
1089
1090 Built-in commands may throw exceptions to signal errors such as invalid arguments. User scripts can throw exceptions
1091 using the `throw` keyword.
1092
1093 Example:
1094
1095 ```
1096 throw "An error occurred."
1097 ```
1098
1099 ## Handling Exceptions <a id="try-except"></a>
1100
1101 Exceptions can be handled using the `try` and `except` keywords. When an exception occurs while executing code in the
1102 `try` clause no further statements in the `try` clause are evaluated and the `except` clause is executed instead.
1103
1104 Example:
1105
1106 ```
1107 try {
1108     throw "Test"
1109
1110     log("This statement won't get executed.")
1111 } except {
1112     log("An error occurred in the try clause.")
1113 }
1114 ```
1115
1116 ## Breakpoints <a id="breakpoints"></a>
1117
1118 The `debugger` keyword can be used to insert a breakpoint. It may be used at any place where an assignment would also be a valid expression.
1119
1120 By default breakpoints have no effect unless Icinga is started with the `--script-debugger` command-line option. When the script debugger is enabled Icinga stops execution of the script when it encounters a breakpoint and spawns a console which lets the user inspect the current state of the execution environment.
1121
1122 ## Types <a id="types"></a>
1123
1124 All values have a static type. The `typeof` function can be used to determine the type of a value:
1125
1126 ```
1127 typeof(3) /* Returns an object which represents the type for numbers */
1128 ```
1129
1130 The following built-in types are available:
1131
1132 Type       | Examples          | Description
1133 -----------|-------------------|------------------------
1134 Number     | 3.7               | A numerical value.
1135 Boolean    | true, false       | A boolean value.
1136 String     | "hello"           | A string.
1137 Array      | [ "a", "b" ]      | An array.
1138 Dictionary | { a = 3 }         | A dictionary.
1139
1140 Depending on which libraries are loaded additional types may become available. The `icinga`
1141 library implements a whole bunch of other [object types](09-object-types.md#object-types),
1142 e.g. Host, Service, CheckCommand, etc.
1143
1144 Each type has an associated type object which describes the type's semantics. These
1145 type objects are made available using global variables which match the type's name:
1146
1147 ```
1148 /* This logs 'true' */
1149 log(typeof(3) == Number)
1150 ```
1151
1152 The type object's `prototype` property can be used to find out which methods a certain type
1153 supports:
1154
1155 ```
1156 /* This returns: ["contains","find","len","lower","replace","reverse","split","substr","to_string","trim","upper"] */
1157 keys(String.prototype)
1158 ```
1159
1160 Additional documentation on type methods is available in the
1161 [library reference](18-library-reference.md#library-reference).
1162
1163 ## Location Information <a id="location-information"></a>
1164
1165 The location of the currently executing script can be obtained using the
1166 `current_filename` and `current_line` keywords.
1167
1168 Example:
1169
1170 ```
1171 log("Hello from '" + current_filename + "' in line " + current_line)
1172 ```
1173
1174 ## Reserved Keywords <a id="reserved-keywords"></a>
1175
1176 These keywords are reserved and must not be used as constants or custom variables.
1177
1178 ```
1179 object
1180 template
1181 include
1182 include_recursive
1183 include_zones
1184 library
1185 null
1186 true
1187 false
1188 const
1189 var
1190 this
1191 globals
1192 locals
1193 use
1194 default
1195 ignore_on_error
1196 current_filename
1197 current_line
1198 apply
1199 to
1200 where
1201 import
1202 assign
1203 ignore
1204 function
1205 return
1206 break
1207 continue
1208 for
1209 if
1210 else
1211 while
1212 throw
1213 try
1214 except
1215 in
1216 using
1217 namespace
1218 ```
1219 You can escape reserved keywords using the `@` character. The following example
1220 tries to set `vars.include` which references a reserved keyword and generates
1221 an error:
1222
1223 ```
1224 [2014-09-15 17:24:00 +0200] critical/config: Location:
1225 /etc/icinga2/conf.d/hosts/localhost.conf(13):   vars.sla = "24x7"
1226 /etc/icinga2/conf.d/hosts/localhost.conf(14):
1227 /etc/icinga2/conf.d/hosts/localhost.conf(15):   vars.include = "some cmdb export field"
1228                                                      ^^^^^^^
1229 /etc/icinga2/conf.d/hosts/localhost.conf(16): }
1230 /etc/icinga2/conf.d/hosts/localhost.conf(17):
1231
1232 Config error: in /etc/icinga2/conf.d/hosts/localhost.conf: 15:8-15:14: syntax error, unexpected include (T_INCLUDE), expecting T_IDENTIFIER
1233 [2014-09-15 17:24:00 +0200] critical/config: 1 errors, 0 warnings.
1234 ```
1235
1236 You can escape the `include` keyword by prefixing it with an additional `@` character:
1237
1238 ```
1239 object Host "localhost" {
1240   import "generic-host"
1241
1242   address = "127.0.0.1"
1243   address6 = "::1"
1244
1245   vars.os = "Linux"
1246   vars.sla = "24x7"
1247
1248   vars.@include = "some cmdb export field"
1249 }
1250 ```