]> granicus.if.org Git - icinga2/blob - doc/17-language-reference.md
Unify documentation code formatting
[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 attributes and the custom attribute `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-configuring-icinga-2.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 paths:
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:
496
497 Constant            | Description
498 --------------------|-------------------
499 Vars                |**Read-write.** Contains a dictionary with global custom attributes. Not set by default.
500 NodeName            |**Read-write.** Contains the cluster node name. Set to the local hostname by default.
501 Environment         |**Read-write.** The name of the Icinga environment. Included in the SNI host name for outbound connections. Not set by default.
502 RunAsUser           |**Read-write.** Defines the user the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
503 RunAsGroup          |**Read-write.** Defines the group the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig.
504 MaxConcurrentChecks |**Read-write.** The number of max checks run simultaneously. Defaults to `512`.
505 ApiBindHost         |**Read-write.** Overrides the default value for the ApiListener `bind_host` attribute. Not set by default.
506 ApiBindPort         |**Read-write.** Overrides the default value for the ApiListener `bind_port` attribute. Not set by default.
507
508 Application runtime details:
509
510 Constant            | Description
511 --------------------|-------------------
512 PlatformName        |**Read-only.** The name of the operating system, e.g. `Ubuntu`.
513 PlatformVersion     |**Read-only.** The version of the operating system, e.g. `14.04.3 LTS`.
514 PlatformKernel      |**Read-only.** The name of the operating system kernel, e.g. `Linux`.
515 PlatformKernelVersion|**Read-only.** The version of the operating system kernel, e.g. `3.13.0-63-generic`.
516 BuildCompilerName   |**Read-only.** The name of the compiler Icinga was built with, e.g. `Clang`.
517 BuildCompilerVersion|**Read-only.** The version of the compiler Icinga was built with, e.g. `7.3.0.7030031`.
518 BuildHostName       |**Read-only.** The name of the host Icinga was built on, e.g. `acheron`.
519 ApplicationVersion  |**Read-only.** The application version, e.g. `2.9.0`.
520
521 Writable constants can be specified on the CLI using the `--define/-D` parameter.
522
523 > **Note for v2.10+**
524 >
525 > Default paths which include `/etc` and `/var` as base directory continue to work
526 > based on the `SysconfDir` and `LocalStateDir` constants respectively.
527
528 In addition to that, the constants below are used to define specific file paths. You should never need
529 to change them, as they are pre-compiled based on the constants above.
530
531 Variable            |Description
532 --------------------|-------------------
533 StatePath           |**Read-write.** Contains the path of the Icinga 2 state file. Defaults to `DataDir + "/icinga2.state"`.
534 ObjectsPath         |**Read-write.** Contains the path of the Icinga 2 objects file. Defaults to `CacheDir + "/icinga2.debug"`.
535 PidPath             |**Read-write.** Contains the path of the Icinga 2 PID file. Defaults to `InitRunDir + "/icinga2.pid"`.
536 PkgDataDir          |**Read-only.** Contains the path of the package data directory. Defaults to `PrefixDir + "/share/icinga2"`.
537
538 The constants below have been used until Icinga v2.10, and are still intact. You don't need them
539 for future builds and configuration based on the newly available constants above.
540
541 Variable            |Description
542 --------------------|-------------------
543 PrefixDir           |**Read-only.** Contains the installation prefix that was specified with `cmake -DCMAKE_INSTALL_PREFIX`. `Defaults to "/usr/local"`.
544 SysconfDir          |**Read-only.** Contains the path of the sysconf directory. Defaults to `PrefixDir + "/etc"`.
545 LocalStateDir       |**Read-only.** Contains the path of the local state directory. Defaults to `PrefixDir + "/var"`.
546 RunDir              |**Read-only.** Contains the path of the run directory. Defaults to `LocalStateDir + "/run"`.
547
548 Advanced runtime constants. Please only use them if advised by support or developers.
549
550 Variable                   | Description
551 ---------------------------|-------------------
552 EventEngine                |**Read-write.** The name of the socket event engine, can be `poll` or `epoll`. The epoll interface is only supported on Linux.
553 AttachDebugger             |**Read-write.** Whether to attach a debugger when Icinga 2 crashes. Defaults to `false`.
554 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.
555 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.
556 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.
557
558 ## Apply <a id="apply"></a>
559
560 The `apply` keyword can be used to create new objects which are associated with
561 another group of objects.
562
563 ```
564 apply Service "ping" to Host {
565   import "generic-service"
566
567   check_command = "ping4"
568
569   assign where host.name == "localhost"
570 }
571 ```
572
573 In this example the `assign where` condition is a boolean expression which is
574 evaluated for all objects of type `Host` and a new service with name "ping"
575 is created for each matching host. [Expression operators](17-language-reference.md#expression-operators)
576 may be used in `assign where` conditions.
577
578 The `to` keyword and the target type may be omitted if there is only one target
579 type, e.g. for the `Service` type.
580
581 Depending on the object type used in the `apply` expression additional local
582 variables may be available for use in the `where` condition:
583
584 Source Type       | Target Type | Variables
585 ------------------|-------------|--------------
586 Service           | Host        | host
587 Dependency        | Host        | host
588 Dependency        | Service     | host, service
589 Notification      | Host        | host
590 Notification      | Service     | host, service
591 ScheduledDowntime | Host        | host
592 ScheduledDowntime | Service     | host, service
593
594 Any valid config attribute can be accessed using the `host` and `service`
595 variables. For example, `host.address` would return the value of the host's
596 "address" attribute -- or null if that attribute isn't set.
597
598 More usage examples are documented in the [monitoring basics](03-monitoring-basics.md#using-apply-expressions)
599 chapter.
600
601 ## Apply For <a id="apply-for"></a>
602
603 [Apply](17-language-reference.md#apply) rules can be extended with the
604 [for loop](17-language-reference.md#for-loops) keyword.
605
606 ```
607 apply Service "prefix-" for (key => value in host.vars.dictionary) to Host {
608   import "generic-service"
609
610   check_command = "ping4"
611   vars.host_value = value
612 }
613 ```
614
615 Any valid config attribute can be accessed using the `host` and `service`
616 variables. The attribute must be of the Array or Dictionary type. In this example
617 `host.vars.dictionary` is of the Dictionary type which needs a key-value-pair
618 as iterator.
619
620 In this example all generated service object names consist of `prefix-` and
621 the value of the `key` iterator. The prefix string can be omitted if not required.
622
623 The `key` and `value` variables can be used for object attribute assignment, e.g. for
624 setting the `check_command` attribute or custom attributes as command parameters.
625
626 `apply for` rules are first evaluated against all objects matching the `for loop` list
627 and afterwards the `assign where` and `ignore where` conditions are evaluated.
628
629 It is not necessary to check attributes referenced in the `for loop` expression
630 for their existance using an additional `assign where` condition.
631
632 More usage examples are documented in the [monitoring basics](03-monitoring-basics.md#using-apply-for)
633 chapter.
634
635 ## Group Assign <a id="group-assign"></a>
636
637 Group objects can be assigned to specific member objects using the `assign where`
638 and `ignore where` conditions.
639
640 ```
641 object HostGroup "linux-servers" {
642   display_name = "Linux Servers"
643
644   assign where host.vars.os == "Linux"
645 }
646 ```
647
648 In this example the `assign where` condition is a boolean expression which is evaluated
649 for all objects of the type `Host`. Each matching host is added as member to the host group
650 with the name "linux-servers". Membership exclusion can be controlled using the `ignore where`
651 condition. [Expression operators](17-language-reference.md#expression-operators) may be used in `assign where` and
652 `ignore where` conditions.
653
654 Source Type       | Variables
655 ------------------|--------------
656 HostGroup         | host
657 ServiceGroup      | host, service
658 UserGroup         | user
659
660
661 ## Boolean Values <a id="boolean-values"></a>
662
663 The `assign where`, `ignore where`, `if` and `while`  statements, the `!` operator as
664 well as the `bool()` function convert their arguments to a boolean value based on the
665 following rules:
666
667 Description          | Example Value     | Boolean Value
668 ---------------------|-------------------|--------------
669 Empty value          | null              | false
670 Zero                 | 0                 | false
671 Non-zero integer     | -23945            | true
672 Empty string         | ""                | false
673 Non-empty string     | "Hello"           | true
674 Empty array          | []                | false
675 Non-empty array      | [ "Hello" ]       | true
676 Empty dictionary     | {}                | false
677 Non-empty dictionary | { key = "value" } | true
678
679 For a list of supported expression operators for `assign where` and `ignore where`
680 statements, see [expression operators](17-language-reference.md#expression-operators).
681
682 ## Comments <a id="comments"></a>
683
684 The Icinga 2 configuration format supports C/C++-style and shell-style comments.
685
686 Example:
687
688 ```
689 /*
690  This is a comment.
691  */
692 object Host "localhost" {
693   check_interval = 30 // this is also a comment.
694   retry_interval = 15 # yet another comment
695 }
696 ```
697
698 ## Includes <a id="includes"></a>
699
700 Other configuration files can be included using the `include` directive.
701 Paths must be relative to the configuration file that contains the
702 `include` directive.
703
704 Example:
705
706 ```
707 include "some/other/file.conf"
708 include "conf.d/*.conf"
709 ```
710
711 Wildcard includes are not recursive.
712
713 Icinga also supports include search paths similar to how they work in a
714 C/C++ compiler:
715
716 ```
717 include <itl>
718 ```
719
720 Note the use of angle brackets instead of double quotes. This causes the
721 config compiler to search the include search paths for the specified
722 file. By default $PREFIX/share/icinga2/include is included in the list of search
723 paths. Additional include search paths can be added using
724 [command-line options](11-cli-commands.md#config-include-path).
725
726 Wildcards are not permitted when using angle brackets.
727
728 ## Recursive Includes <a id="recursive-includes"></a>
729
730 The `include_recursive` directive can be used to recursively include all
731 files in a directory which match a certain pattern.
732
733 Example:
734
735 ```
736 include_recursive "conf.d", "*.conf"
737 include_recursive "templates"
738 ```
739
740 The first parameter specifies the directory from which files should be
741 recursively included.
742
743 The file names need to match the pattern given in the second parameter.
744 When no pattern is specified the default pattern "*.conf" is used.
745
746 ## Zone Includes <a id="zone-includes"></a>
747
748 The `include_zones` recursively includes all subdirectories for the
749 given path.
750
751 In addition to that it sets the `zone` attribute for all objects created
752 in these subdirectories to the name of the subdirectory.
753
754 Example:
755
756 ```
757 include_zones "etc", "zones.d", "*.conf"
758 include_zones "puppet", "puppet-zones"
759 ```
760
761 The first parameter specifies a tag name for this directive. Each `include_zones`
762 invocation should use a unique tag name. When copying the zones' configuration
763 files Icinga uses the tag name as the name for the destination directory in
764 `/var/lib/icinga2/api/config`.
765
766 The second parameter specifies the directory which contains the subdirectories.
767
768 The file names need to match the pattern given in the third parameter.
769 When no pattern is specified the default pattern "*.conf" is used.
770
771 ## Library directive <a id="library"></a>
772
773 The `library` directive was used to manually load additional
774 libraries. Starting with version 2.9 it is no longer necessary to explicitly load
775 libraries and this directive has no effect.
776
777 ## Functions <a id="functions"></a>
778
779 Functions can be defined using the `function` keyword.
780
781 Example:
782
783 ```
784 function multiply(a, b) {
785   return a * b
786 }
787 ```
788
789 When encountering the `return` keyword further execution of the function is terminated and
790 the specified value is supplied to the caller of the function:
791
792 ```
793 log(multiply(3, 5))
794 ```
795
796 In this example the `multiply` function we declared earlier is invoked with two arguments (3 and 5).
797 The function computes the product of those arguments and makes the result available to the
798 function's caller.
799
800 When no value is supplied for the `return` statement the function returns `null`.
801
802 Functions which do not have a `return` statement have their return value set to the value of the
803 last expression which was performed by the function. For example, we could have also written our
804 `multiply` function like this:
805
806 ```
807 function multiply(a, b) {
808   a * b
809 }
810 ```
811
812 Anonymous functions can be created by omitting the name in the function definition. The
813 resulting function object can be used like any other value:
814
815 ```
816 var fn = function() { 3 }
817
818 fn() /* Returns 3 */
819 ```
820
821 ## Lambda Expressions <a id="lambdas"></a>
822
823 Functions can also be declared using the alternative lambda syntax.
824
825 Example:
826
827 ```
828 f = (x) => x * x
829 ```
830
831 Multiple statements can be used by putting the function body into braces:
832
833 ```
834 f = (x) => {
835   log("Lambda called")
836   x * x
837 }
838 ```
839
840 Just like with ordinary functions the return value is the value of the last statement.
841
842 For lambdas which take exactly one argument the braces around the arguments can be omitted:
843
844 ```
845 f = x => x * x
846 ```
847
848 ## Abbreviated Lambda Syntax <a id="nullary-lambdas"></a>
849
850 Lambdas which take no arguments can also be written using the abbreviated lambda syntax.
851
852 Example:
853
854 ```
855 f = {{ 3 }}
856 ```
857
858 This creates a new function which returns the value 3.
859
860 ## Variable Scopes <a id="variable-scopes"></a>
861
862 When setting a variable Icinga checks the following scopes in this order whether the variable
863 already exists there:
864
865 * Local Scope
866 * `this` Scope
867 * Global Scope
868
869 The local scope contains variables which only exist during the invocation of the current function,
870 object or apply statement. Local variables can be declared using the `var` keyword:
871
872 ```
873 function multiply(a, b) {
874   var temp = a * b
875   return temp
876 }
877 ```
878
879 Each time the `multiply` function is invoked a new `temp` variable is used which is in no way
880 related to previous invocations of the function.
881
882 When setting a variable which has not previously been declared as local using the `var` keyword
883 the `this` scope is used.
884
885 The `this` scope refers to the current object which the function or object/apply statement
886 operates on.
887
888 ```
889 object Host "localhost" {
890   check_interval = 5m
891 }
892 ```
893
894 In this example the `this` scope refers to the "localhost" object. The `check_interval` attribute
895 is set for this particular host.
896
897 You can explicitly access the `this` scope using the `this` keyword:
898
899 ```
900 object Host "localhost" {
901   var check_interval = 5m
902
903   /* This explicitly specifies that the attribute should be set
904    * for the host, if we had omitted `this.` the (poorly named)
905    * local variable `check_interval` would have been modified instead.
906    */
907   this.check_interval = 1m
908 }
909 ```
910 Similarly the keywords `locals` and `globals` are available to access the local and global scope.
911
912 Functions also have a `this` scope. However unlike for object/apply statements the `this` scope for
913 a function is set to whichever object was used to invoke the function. Here's an example:
914
915 ```
916  hm = {
917    h_word = null
918
919    function init(word) {
920      h_word = word
921    }
922  }
923
924  /* Let's invoke the init() function */
925  hm.init("hello")
926 ```
927
928 We're using `hm.init` to invoke the function which causes the value of `hm` to become the `this`
929 scope for this function call.
930
931 ## Closures <a id="closures"></a>
932
933 By default `function`s, `object`s and `apply` rules do not have access to variables declared
934 outside of their scope (except for global variables).
935
936 In order to access variables which are defined in the outer scope the `use` keyword can be used:
937
938 ```
939 function MakeHelloFunction(name) {
940   return function() use(name) {
941     log("Hello, " + name)
942   }
943 }
944 ```
945
946 In this case a new variable `name` is created inside the inner function's scope which has the
947 value of the `name` function argument.
948
949 Alternatively a different value for the inner variable can be specified:
950
951 ```
952 function MakeHelloFunction(name) {
953   return function() use (greeting = "Hello, " + name) {
954     log(greeting)
955   }
956 }
957 ```
958
959 ## Conditional Statements <a id="conditional-statements"></a>
960
961 Sometimes it can be desirable to only evaluate statements when certain conditions are met. The if/else
962 construct can be used to accomplish this.
963
964 Example:
965
966 ```
967 a = 3
968
969 if (a < 5) {
970   a *= 7
971 } else if (a > 10) {
972   a *= 5
973 } else {
974   a *= 2
975 }
976 ```
977
978 An if/else construct can also be used in place of any other value. The value of an if/else statement
979 is the value of the last statement which was evaluated for the branch which was taken:
980
981 ```
982 a = if (true) {
983   log("Taking the 'true' branch")
984   7 * 3
985 } else {
986   log("Taking the 'false' branch")
987   9
988 }
989 ```
990
991 This example prints the log message "Taking the 'true' branch" and the `a` variable is set to 21 (7 * 3).
992
993 The value of an if/else construct is null if the condition evaluates to false and no else branch is given.
994
995 ## While Loops <a id="while-loops"></a>
996
997 The `while` statement checks a condition and executes the loop body when the condition evaluates to `true`.
998 This is repeated until the condition is no longer true.
999
1000 Example:
1001
1002 ```
1003 var num = 5
1004
1005 while (num > 5) {
1006     log("Test")
1007     num -= 1
1008 }
1009 ```
1010
1011 The `continue` and `break` keywords can be used to control how the loop is executed: The `continue` keyword
1012 skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword
1013 breaks out of the loop.
1014
1015 ## For Loops <a id="for-loops"></a>
1016
1017 The `for` statement can be used to iterate over arrays and dictionaries.
1018
1019 Example:
1020
1021 ```
1022 var list = [ "a", "b", "c" ]
1023
1024 for (var item in list) {
1025   log("Item: " + item)
1026 }
1027 ```
1028
1029 The loop body is evaluated once for each item in the array. The variable `item` is declared as a local
1030 variable just as if the `var` keyword had been used.
1031
1032 Iterating over dictionaries can be accomplished in a similar manner:
1033
1034 ```
1035 var dict = { a = 3, b = 7 }
1036
1037 for (var key => var value in dict) {
1038   log("Key: " + key + ", Value: " + value)
1039 }
1040 ```
1041
1042 The `continue` and `break` keywords can be used to control how the loop is executed: The `continue` keyword
1043 skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword
1044 breaks out of the loop.
1045
1046 The `var` keyword is optional when declaring variables in the loop's header. Variables declared without the `var`
1047 keyword are nonetheless local to the function.
1048
1049 ## Constructors <a id="constructor"></a>
1050
1051 In order to create a new value of a specific type constructor calls may be used.
1052
1053 Example:
1054
1055 ```
1056 var pd = PerfdataValue()
1057 pd.label = "test"
1058 pd.value = 10
1059 ```
1060
1061 You can also try to convert an existing value to another type by specifying it as an argument for the constructor call.
1062
1063 Example:
1064
1065 ```
1066 var s = String(3) /* Sets s to "3". */
1067 ```
1068
1069 ## Throwing Exceptions <a id="throw"></a>
1070
1071 Built-in commands may throw exceptions to signal errors such as invalid arguments. User scripts can throw exceptions
1072 using the `throw` keyword.
1073
1074 Example:
1075
1076 ```
1077 throw "An error occurred."
1078 ```
1079
1080 ## Handling Exceptions <a id="try-except"></a>
1081
1082 Exceptions can be handled using the `try` and `except` keywords. When an exception occurs while executing code in the
1083 `try` clause no further statements in the `try` clause are evaluated and the `except` clause is executed instead.
1084
1085 Example:
1086
1087 ```
1088 try {
1089     throw "Test"
1090
1091     log("This statement won't get executed.")
1092 } except {
1093     log("An error occurred in the try clause.")
1094 }
1095 ```
1096
1097 ## Breakpoints <a id="breakpoints"></a>
1098
1099 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.
1100
1101 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.
1102
1103 ## Types <a id="types"></a>
1104
1105 All values have a static type. The `typeof` function can be used to determine the type of a value:
1106
1107 ```
1108 typeof(3) /* Returns an object which represents the type for numbers */
1109 ```
1110
1111 The following built-in types are available:
1112
1113 Type       | Examples          | Description
1114 -----------|-------------------|------------------------
1115 Number     | 3.7               | A numerical value.
1116 Boolean    | true, false       | A boolean value.
1117 String     | "hello"           | A string.
1118 Array      | [ "a", "b" ]      | An array.
1119 Dictionary | { a = 3 }         | A dictionary.
1120
1121 Depending on which libraries are loaded additional types may become available. The `icinga`
1122 library implements a whole bunch of other [object types](09-object-types.md#object-types),
1123 e.g. Host, Service, CheckCommand, etc.
1124
1125 Each type has an associated type object which describes the type's semantics. These
1126 type objects are made available using global variables which match the type's name:
1127
1128 ```
1129 /* This logs 'true' */
1130 log(typeof(3) == Number)
1131 ```
1132
1133 The type object's `prototype` property can be used to find out which methods a certain type
1134 supports:
1135
1136 ```
1137 /* This returns: ["contains","find","len","lower","replace","reverse","split","substr","to_string","trim","upper"] */
1138 keys(String.prototype)
1139 ```
1140
1141 Additional documentation on type methods is available in the
1142 [library reference](18-library-reference.md#library-reference).
1143
1144 ## Location Information <a id="location-information"></a>
1145
1146 The location of the currently executing script can be obtained using the
1147 `current_filename` and `current_line` keywords.
1148
1149 Example:
1150
1151 ```
1152 log("Hello from '" + current_filename + "' in line " + current_line)
1153 ```
1154
1155 ## Reserved Keywords <a id="reserved-keywords"></a>
1156
1157 These keywords are reserved and must not be used as constants or custom attributes.
1158
1159 ```
1160 object
1161 template
1162 include
1163 include_recursive
1164 include_zones
1165 library
1166 null
1167 true
1168 false
1169 const
1170 var
1171 this
1172 globals
1173 locals
1174 use
1175 default
1176 ignore_on_error
1177 current_filename
1178 current_line
1179 apply
1180 to
1181 where
1182 import
1183 assign
1184 ignore
1185 function
1186 return
1187 break
1188 continue
1189 for
1190 if
1191 else
1192 while
1193 throw
1194 try
1195 except
1196 in
1197 using
1198 namespace
1199 ```
1200 You can escape reserved keywords using the `@` character. The following example
1201 tries to set `vars.include` which references a reserved keyword and generates
1202 an error:
1203
1204 ```
1205 [2014-09-15 17:24:00 +0200] critical/config: Location:
1206 /etc/icinga2/conf.d/hosts/localhost.conf(13):   vars.sla = "24x7"
1207 /etc/icinga2/conf.d/hosts/localhost.conf(14):
1208 /etc/icinga2/conf.d/hosts/localhost.conf(15):   vars.include = "some cmdb export field"
1209                                                      ^^^^^^^
1210 /etc/icinga2/conf.d/hosts/localhost.conf(16): }
1211 /etc/icinga2/conf.d/hosts/localhost.conf(17):
1212
1213 Config error: in /etc/icinga2/conf.d/hosts/localhost.conf: 15:8-15:14: syntax error, unexpected include (T_INCLUDE), expecting T_IDENTIFIER
1214 [2014-09-15 17:24:00 +0200] critical/config: 1 errors, 0 warnings.
1215 ```
1216
1217 You can escape the `include` keyword by prefixing it with an additional `@` character:
1218
1219 ```
1220 object Host "localhost" {
1221   import "generic-host"
1222
1223   address = "127.0.0.1"
1224   address6 = "::1"
1225
1226   vars.os = "Linux"
1227   vars.sla = "24x7"
1228
1229   vars.@include = "some cmdb export field"
1230 }
1231 ```