From 6c975dab5f0fb48ae7efa7c5232bb292797ecc23 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Fri, 25 Nov 2016 13:40:42 +0100 Subject: [PATCH] Docs: Update API and Library Reference chapters New sub chapters for global functions linked everywhere. New API examples and clarifications. fixes #13327 fixes #12449 --- doc/12-icinga2-api.md | 57 +++- doc/18-library-reference.md | 476 ++++++++++++++++++++++++++++++-- doc/3-monitoring-basics.md | 20 +- doc/4-configuring-icinga-2.md | 2 +- doc/6-distributed-monitoring.md | 5 + doc/8-advanced-topics.md | 4 +- 6 files changed, 520 insertions(+), 44 deletions(-) diff --git a/doc/12-icinga2-api.md b/doc/12-icinga2-api.md index a437e3a71..959838b59 100644 --- a/doc/12-icinga2-api.md +++ b/doc/12-icinga2-api.md @@ -82,6 +82,10 @@ The output will be sent back as a JSON object: ] } +Tip: If you are working on the CLI with curl you can also use [jq](https://stedolan.github.io/jq/) +to format the returned JSON output in a readable manner. The documentation +prefers `python -m json.tool` as Python is available nearly everywhere. + > **Note** > > Future versions of Icinga 2 might set additional fields. Your application @@ -182,6 +186,7 @@ which must return a boolean value. The following example allows the API user to query all hosts and services which have a custom attribute `os` that matches the regular expression `^Linux`. +The [regex function](18-library-reference.md#global-functions-regex) is available as global function. permissions = [ { @@ -235,6 +240,9 @@ Here are the exact same query parameters as a JSON object: { "filter": "match(\"example.localdomain*\",host.name)", "attrs": [ "host.name", "host.state" ] } +The [match function](18-library-reference.md#global-functions-match) is available as global function +in Icinga 2. + ### Request Method Override `GET` requests do not allow you to send a request body. In case you cannot pass everything as URL parameters (e.g. complex filters or JSON-encoded dictionaries) you can use the `X-HTTP-Method-Override` header. This comes in handy when you are using HTTP proxies disallowing `PUT` or `DELETE` requests too. @@ -293,7 +301,7 @@ Example matching all services in NOT-OK state: https://localhost:5665/v1/objects/services?filter=service.state!=ServiceOK -Example matching all hosts by name: +Example [matching](18-library-reference.md#global-functions-match) all hosts by a name string pattern: https://localhost:5665/v1/objects/hosts?filter=match("example.localdomain*",host.name) @@ -510,6 +518,35 @@ for downtimes): https://localhost:5665/v1/objects/comments?joins=host&joins=service +This is another example for listing all service objects which are unhandled problems (state is not OK +and no downtime or acknowledgement set): + + $ curl -k -s -u root:icinga -H 'X-HTTP-Method-Override: GET' -X POST 'https://127.0.0.1:5665/v1/objects/services' \ + -d '{ "joins": [ "host.name", "host.address" ], "attrs": [ "name", "state", "downtime_depth", "acknowledgement" ], "filter": "service.state != ServiceOK && service.downtime_depth == 0.0 && service.acknowledgement == 0.0" }' | python -m json.tool + + { + "results": [ + { + "attrs": { + "acknowledgement": 0.0, + "downtime_depth": 0.0, + "name": "10807-service", + "state": 3.0 + }, + "joins": { + "host": { + "address": "", + "name": "10807-host" + } + }, + "meta": {}, + "name": "10807-host!10807-service", + "type": "Service" + } + ] + } + + ### Creating Config Objects New objects must be created by sending a PUT request. The following @@ -517,7 +554,7 @@ parameters need to be passed inside the JSON body: Parameters | Type | Description -----------|--------------|-------------------------- - templates | string array | **Optional.** Import existing configuration templates for this object type. + templates | string array | **Optional.** Import existing configuration templates for this object type. Note: These templates must either be statically configured or provided in [config packages](12-icinga2-api.md#icinga2-api-config-management)- attrs | dictionary | **Required.** Set specific object attributes for this [object type](9-object-types.md#object-types). The object name must be specified as part of the URL path. For objects with composite names (e.g. services) @@ -586,6 +623,8 @@ In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters **Note**: Modified attributes do not trigger a re-evaluation of existing static [apply rules](3-monitoring-basics.md#using-apply) and [group assignments](3-monitoring-basics.md#group-assign-intro). Delete and re-create the objects if you require such changes. +Furthermore you cannot modify templates which have already been resolved +during [object creation](12-icinga2-api.md#icinga2-api-config-objects-create). If attributes are of the Dictionary type, you can also use the indexer format: @@ -640,6 +679,8 @@ Provides methods to manage configuration templates: * [querying templates](12-icinga2-api.md#icinga2-api-config-templates-query) +Creation, modification and deletion of templates at runtime is not supported. + ### Querying Templates You can request information about configuration templates by sending @@ -653,9 +694,11 @@ A list of all available configuration types is available in the [object types](9-object-types.md#object-types) chapter. A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The -template object can be accessed in the filter using the `tmpl` variable: +template object can be accessed in the filter using the `tmpl` variable. In this +example the [match function](18-library-reference.md#global-functions-match) is used to +check a wildcard string pattern against `tmpl.name`: - $ curl -u root:root -k 'https://localhost:5661/v1/templates/hosts' -H "Accept: application/json" -X PUT -H "X-HTTP-Method-Override: GET" \ + $ curl -k -s -u root:icinga 'https://localhost:5661/v1/templates/hosts' -H "Accept: application/json" -X PUT -H "X-HTTP-Method-Override: GET" \ -d '{ "filter": "match(\"g*\", tmpl.name)" }' Instead of using a filter you can optionally specify the template name in the @@ -1180,7 +1223,8 @@ Example for the `CheckResult` type with the `exit_code` set to `2`: &types=CheckResult&filter=event.check_result.exit_status==2 -Example for the `CheckResult` type with the service matching the string "random": +Example for the `CheckResult` type with the service [matching](18-library-reference.md#global-functions-match) +the string pattern "random\*": &types=CheckResult&filter=match%28%22random*%22,event.service%29 @@ -1649,7 +1693,8 @@ The request method is `POST` using `X-HTTP-Method-Override: GET` which allows you to send a JSON request body. The examples request specific service attributes joined with host attributes. `attrs` and `joins` are therefore specified as array. -The `filter` attribute matches on all services with `ping` in their name. +The `filter` attribute [matches](18-library-reference.md#global-functions-match) +on all services with `ping` in their name. #### Example API Client in Python diff --git a/doc/18-library-reference.md b/doc/18-library-reference.md index 577c7fdea..8020283d1 100644 --- a/doc/18-library-reference.md +++ b/doc/18-library-reference.md @@ -2,31 +2,457 @@ ## Global functions -Function | Description ---------------------------------|----------------------- -regex(pattern, text) | Returns true if the regex pattern matches the text, false otherwise. -match(pattern, text) | Returns true if the wildcard pattern matches the text, false otherwise. -cidr_match(pattern, ip) | Returns true if the CIDR pattern matches the IP address, false otherwise. IPv4 addresses are converted to IPv4-mapped IPv6 addresses before being matched against the pattern. -len(value) | Returns the length of the value, i.e. the number of elements for an array or dictionary, or the length of the string in bytes. -union(array, array, ...) | Returns an array containing all unique elements from the specified arrays. -intersection(array, array, ...) | Returns an array containing all unique elements which are common to all specified arrays. -keys(dict) | Returns an array containing the dictionary's keys. -string(value) | Converts the value to a string. -number(value) | Converts the value to a number. -bool(value) | Converts the value to a bool. -random() | Returns a random value between 0 and RAND_MAX (as defined in stdlib.h). -log(value) | Writes a message to the log. Non-string values are converted to a JSON string. -log(severity, facility, value) | Writes a message to the log. `severity` can be one of `LogDebug`, `LogNotice`, `LogInformation`, `LogWarning`, and `LogCritical`. Non-string values are converted to a JSON string. -typeof(value) | Returns the [Type](18-library-reference.md#type-type) object for a value. -get_time() | Returns the current UNIX timestamp. -parse_performance_data(pd) | Parses a performance data string and returns an array describing the values. -dirname(path) | Returns the directory portion of the specified path. -basename(path) | Returns the filename portion of the specified path. -escape\_shell\_arg(text) | Escapes a string for use as a single shell argument. -escape\_shell\_cmd(text) | Escapes shell meta characters in a string. -escape\_create\_process\_arg(text)| (Windows only) Escapes a string for use as an argument for CreateProcess(). -exit(integer) | Terminates the application. -sleep(interval) | Sleeps for the specified amount of time (in seconds). +These functions are globally available in [assign/ignore where expressions](3-monitoring-basics.md#using-apply-expressions), +[functions](17-language-reference.md#functions), [API filters](12-icinga2-api.md#icinga2-api-filters) +and the [Icinga 2 console](11-cli-commands.md#cli-command-console). + +You can use the [Icinga 2 console](11-cli-commands.md#cli-command-console) +as a sandbox to test these functions before implementing +them in your scenarios. + +### regex + +Signature: + + function regex(pattern, text) + +Returns true if the regular expression matches the text, false otherwise. +**Tip**: In case you are looking for regular expression tests try [regex101](https://regex101.com). + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => host.vars.os_type = "Linux/Unix" + null + <2> => regex("^Linux", host.vars.os_type) + true + <3> => regex("^Linux$", host.vars.os_type) + false + +### match + +Signature: + + function match(pattern, text) + +Returns true if the wildcard (`\*`) pattern matches the text, false otherwise. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => host.display_name = "NUE-DB-PROD-586" + null + <2> => match("NUE-*", host.display_name) + true + <3> => match("*NUE-*", host.display_name) + true + <4> => match("NUE-*-DEV-*", host.display_name) + false + +### cidr_match + +Signature: + + function cidr_match(pattern, ip) + +Returns true if the CIDR pattern matches the IP address, false otherwise. +IPv4 addresses are converted to IPv4-mapped IPv6 addresses before being +matched against the pattern. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => host.address = "192.168.56.101" + null + <2> => cidr_match("192.168.56.0/24", host.address) + true + <3> => cidr_match("192.168.56.0/26", host.address) + false + +### range + +Signature: + + function range(end) + function range(start, end) + function range(start, end, increment) + +Returns an array of numbers in the specified range. +If you specify one parameter, the first element starts at `0`. +The following array numbers are incremented by `1` and stop before +the specified end. +If you specify the start and end numbers, the returned array +number are incremented by `1`. They start at the specified start +number and stop before the end number. +Optionally you can specify the incremented step between numbers +as third parameter. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => range(5) + [ 0.000000, 1.000000, 2.000000, 3.000000, 4.000000 ] + <2> => range(2,4) + [ 2.000000, 3.000000 ] + <3> => range(2,10,2) + [ 2.000000, 4.000000, 6.000000, 8.000000 ] + +### len + +Signature: + + function len(value) + +Returns the length of the value, i.e. the number of elements for an array +or dictionary, or the length of the string in bytes. + +**Note**: Instead of using this global function you are advised to use the type's +prototype method: [Array#len](18-library-reference.md#array-len), [Dictionary#len](18-library-reference.md#dictionary-len) and +[String#len](18-library-reference.md#string-len). + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => host.groups = [ "linux-servers", "db-servers" ] + null + <2> => host.groups.len() + 2.000000 + <3> => host.vars.disks["/"] = {} + null + <4> => host.vars.disks["/var"] = {} + null + <5> => host.vars.disks.len() + 2.000000 + <6> => host.vars.os_type = "Linux/Unix" + null + <7> => host.vars.os_type.len() + 10.000000 + + +### union + +Signature: + + function union(array, array, ...) + +Returns an array containing all unique elements from the specified arrays. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => var dev_notification_groups = [ "devs", "slack" ] + null + <2> => var host_notification_groups = [ "slack", "noc" ] + null + <3> => union(dev_notification_groups, host_notification_groups) + [ "devs", "noc", "slack" ] + +### intersection + +Signature: + + function intersection(array, array, ...) + +Returns an array containing all unique elements which are common to all +specified arrays. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => var dev_notification_groups = [ "devs", "slack" ] + null + <2> => var host_notification_groups = [ "slack", "noc" ] + null + <3> => intersection(dev_notification_groups, host_notification_groups) + [ "slack" ] + +### keys + +Signature: + + function keys(dict) + +Returns an array containing the dictionary's keys. + +**Note**: Instead of using this global function you are advised to use the type's +prototype method: [Dictionary#keys](18-library-reference.md#dictionary-keys). + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => host.vars.disks["/"] = {} + null + <2> => host.vars.disks["/var"] = {} + null + <3> => host.vars.disks.keys() + [ "/", "/var" ] + +### string + +Signature: + + function string(value) + +Converts the value to a string. + +**Note**: Instead of using this global function you are advised to use the type's +prototype method: + +* [Number#to_string](18-library-reference.md#number-to_string) +* [Boolean#to_string](18-library-reference.md#boolean-to_string) +* [String#to_string](18-library-reference.md#string-to_string) +* [Object#to_string](18-library-reference.md#object-to-string) for Array and Dictionary types +* [DateTime#to_string](18-library-reference.md#datetime-tostring) + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => 5.to_string() + "5" + <2> => false.to_string() + "false" + <3> => "abc".to_string() + "abc" + <4> => [ "dev", "slack" ].to_string() + "[ \"dev\", \"slack\" ]" + <5> => { "/" = {}, "/var" = {} }.to_string() + "{\n\t\"/\" = {\n\t}\n\t\"/var\" = {\n\t}\n}" + <6> => DateTime(2016, 11, 25).to_string() + "2016-11-25 00:00:00 +0100" + +### number + +Signature: + + function number(value) + +Converts the value to a number. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => number(false) + 0.000000 + <2> => number("78") + 78.000000 + +### bool + +Signature: + + function bool(value) + +Converts the value to a bool. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => bool(1) + true + <2> => bool(0) + false + +### random + +Signature: + + function random() + +Returns a random value between 0 and RAND\_MAX (as defined in stdlib.h). + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => random() + 1263171996.000000 + <2> => random() + 108402530.000000 + +### log + +Signature: + + function log(value) + +Writes a message to the log. Non-string values are converted to a JSON string. + +Signature: + + function log(severity, facility, value) + +Writes a message to the log. `severity` can be one of `LogDebug`, `LogNotice`, +`LogInformation`, `LogWarning`, and `LogCritical`. + +Non-string values are converted to a JSON string. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => log(LogCritical, "Console", "First line") + critical/Console: First line + null + <2> => var groups = [ "devs", "slack" ] + null + <3> => log(LogCritical, "Console", groups) + critical/Console: ["devs","slack"] + null + +### typeof + +Signature: + + function typeof(value) + +Returns the [Type](18-library-reference.md#type-type) object for a value. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => typeof(3) == Number + true + <2> => typeof("str") == String + true + <3> => typeof(true) == Boolean + true + <4> => typeof([ 1, 2, 3]) == Array + true + <5> => typeof({ a = 2, b = 3}) == Dictionary + +### get_time + +Signature: + + function get_time() + +Returns the current UNIX timestamp as floating point number. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => get_time() + 1480072135.633008 + <2> => get_time() + 1480072140.401207 + +### parse_performance_data + +Signature: + + function parse_performance_data(pd) + +Parses a performance data string and returns an array describing the values. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => var pd = "'time'=1480074205.197363;;;" + null + <2> => parse_performance_data(pd) + { + counter = false + crit = null + label = "time" + max = null + min = null + type = "PerfdataValue" + unit = "" + value = 1480074205.197363 + warn = null + } + +### dirname + +Signature: + + function dirname(path) + +Returns the directory portion of the specified path. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => var path = "/etc/icinga2/scripts/xmpp-notification.pl" + null + <2> => dirname(path) + "/etc/icinga2/scripts" + +### basename + +Signature: + + function basename(path) + +Returns the filename portion of the specified path. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => var path = "/etc/icinga2/scripts/xmpp-notification.pl" + null + <2> => basename(path) + "xmpp-notification.pl" + +### escape_shell_arg + +Signature: + + function escape_shell_arg(text) + +Escapes a string for use as a single shell argument. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => escape_shell_arg("'$host.name$' '$service.name$'") + "''\\''$host.name$'\\'' '\\''$service.name$'\\'''" + +### escape_shell_cmd + +Signature: + + function escape_shell_cmd(text) + +Escapes shell meta characters in a string. + +Example: + + $ icinga2 console + Icinga 2 (version: v2.6.0) + <1> => escape_shell_cmd("/bin/echo 'shell test' $ENV") + "/bin/echo 'shell test' \\$ENV" + +### escape_create_process_arg + +Signature: + + function escape_create_process_arg(text) + +Escapes a string for use as an argument for CreateProcess(). Windows only. + +### sleep + +Signature: + + function sleep(interval) + +Sleeps for the specified amount of time (in seconds). ## Object Accessor Functions diff --git a/doc/3-monitoring-basics.md b/doc/3-monitoring-basics.md index f053fc938..5fd86dad1 100644 --- a/doc/3-monitoring-basics.md +++ b/doc/3-monitoring-basics.md @@ -434,7 +434,7 @@ Before you start using the apply rules keep the following in mind: * Define the best match. * A set of unique [custom attributes](3-monitoring-basics.md#custom-attributes) for these hosts/services? * Or [group](3-monitoring-basics.md#groups) memberships, e.g. a host being a member of a hostgroup, applying services to it? - * A generic pattern [match](17-language-reference.md#function-calls) on the host/service name? + * A generic pattern [match](18-library-reference.md#global-functions-match) on the host/service name? * [Multiple expressions combined](3-monitoring-basics.md#using-apply-expressions) with `&&` or `||` [operators](17-language-reference.md#expression-operators) * All expressions must return a boolean value (an empty string is equal to `false` e.g.) @@ -481,7 +481,7 @@ you want to be able to add more than one assign/ignore where expression which ma a specific condition. To achieve this you can use the logical `and` and `or` operators. -Match all `*mysql*` patterns in the host name and (`&&`) custom attribute `prod_mysql_db` +[Match](18-library-reference.md#global-functions-match) all `*mysql*` patterns in the host name and (`&&`) custom attribute `prod_mysql_db` matches the `db-*` pattern. All hosts with the custom attribute `test_server` set to `true` should be ignored, or any host name ending with `*internal` pattern. @@ -494,7 +494,7 @@ should be ignored, or any host name ending with `*internal` pattern. } Similar example for advanced notification apply rule filters: If the service -attribute `notes` contains the `has gold support 24x7` string `AND` one of the +attribute `notes` [matches](18-library-reference.md#global-functions-match) the `has gold support 24x7` string `AND` one of the two condition passes, either the `customer` host custom attribute is set to `customer-xy` `OR` the host custom attribute `always_notify` is set to `true`. @@ -651,8 +651,8 @@ Icinga 2 evaluates the `apply for` rule for all objects with the custom attribut `assign/ignore where` expressions. You can access the loop variable in these expressions, e.g. for ignoring certain values. In this example we'd ignore the `bgp` identifier and avoid generating an unwanted service. -We could extend the configuration by also matching the `oid` value on certain regex/wildcard -patterns for example. +We could extend the configuration by also matching the `oid` value on certain +[regex](18-library-reference.md#global-functions-regex)/[wildcard match](18-library-reference.md#global-functions-match) patterns for example. > **Note** > @@ -967,9 +967,9 @@ to a group based on their attributes: } In this example all hosts with the `vars` attribute `mssql_port` -will be added as members to the host group `mssql`. However, all `\*internal` -hosts or with the `test_server` attribute set to `true` are not added to this -group. +will be added as members to the host group `mssql`. However, all +hosts [matching](18-library-reference.md#global-functions-match) the string `\*internal` +or with the `test_server` attribute set to `true` are **not** added to this group. Details on the `assign where` syntax can be found in the [Language Reference](17-language-reference.md#apply). @@ -1898,8 +1898,8 @@ for the agent daemon responding to your requests, and make all other services querying that daemon depend on that health check. The following configuration defines two nrpe based service checks `nrpe-load` -and `nrpe-disk` applied to the `nrpe-server`. The health check is defined as -`nrpe-health` service. +and `nrpe-disk` applied to the host `nrpe-server` [matched](18-library-reference.md#global-functions-match) +by its name. The health check is defined as `nrpe-health` service. apply Service "nrpe-health" { import "generic-service" diff --git a/doc/4-configuring-icinga-2.md b/doc/4-configuring-icinga-2.md index 5a54bd919..c2e93fcaf 100644 --- a/doc/4-configuring-icinga-2.md +++ b/doc/4-configuring-icinga-2.md @@ -553,7 +553,7 @@ to previously seen [apply rules](3-monitoring-basics.md#using-apply). } Service groups can be grouped together by similar pattern matches. -The [match() function](17-language-reference.md#function-calls) expects a wildcard match string +The [match function](18-library-reference.md#global-functions-match) expects a wildcard match string and the attribute string to match with. object ServiceGroup "ping" { diff --git a/doc/6-distributed-monitoring.md b/doc/6-distributed-monitoring.md index 0315c3ab7..3555e710b 100644 --- a/doc/6-distributed-monitoring.md +++ b/doc/6-distributed-monitoring.md @@ -1957,6 +1957,11 @@ execute a local disk check in the `master` on a specific endpoint then. assign where host.zone == "master" && match("icinga2-master*", host.name) } +The `host.zone` attribute check inside the expression ensures that +the service object is only created for host objects inside the `master` +zone. In addition to that the [match](18-library-reference.md#global-functions-match) +function ensures to only create services for the master nodes. + ### Windows Firewall By default ICMP requests are disabled in the Windows firewall. You can diff --git a/doc/8-advanced-topics.md b/doc/8-advanced-topics.md index a123da3a5..afb60111f 100644 --- a/doc/8-advanced-topics.md +++ b/doc/8-advanced-topics.md @@ -317,7 +317,7 @@ The other way around you can create objects dynamically using your own global fu Tips when implementing functions: -* Use [log()](18-library-reference.md#global-functions) to dump variables. You can see the output +* Use [log()](18-library-reference.md#global-functions-log) to dump variables. You can see the output inside the `icinga2.log` file depending in your log severity * Use the `icinga2 console` to test basic functionality (e.g. iterating over a dictionary) * Build them step-by-step. You can always refactor your code later on. @@ -490,7 +490,7 @@ writing your own global [functions](17-language-reference.md#functions). You can call them inside `assign where` and `ignore where` expressions for [apply rules](3-monitoring-basics.md#using-apply-expressions) or [group assignments](3-monitoring-basics.md#group-assign-intro) just like -any other global functions for example [match](18-library-reference.md#global-functions). +any other global functions for example [match](18-library-reference.md#global-functions-match). The following example requires the host `myprinter` being added to the host group `printers-lexmark` but only if the host uses -- 2.40.0