mirror of https://github.com/Icinga/icinga2.git
Documentation: Add function usage examples to advanced topics
Includes typeof() examples, referenced to command variable scopes and examples from community support. fixes #9297 fixes #9310 fixes #9311
This commit is contained in:
parent
ca674da0d2
commit
909467574c
|
@ -208,6 +208,166 @@ Use the `period` attribute to assign time periods to
|
||||||
period = "workhours"
|
period = "workhours"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## <a id="use-functions-object-config"></a> Use Functions in Object Configuration
|
||||||
|
|
||||||
|
There is a limited scope where functions can be used as object attributes such as:
|
||||||
|
|
||||||
|
* As value for [Custom Attributes](3-monitoring-basics.md#custom-attributes-functions)
|
||||||
|
* Returning boolean expressions for [set_if](5-advanced-topics.md#use-functions-command-arguments-setif) inside command arguments
|
||||||
|
* Returning a [command](5-advanced-topics.md#use-functions-command-attribute) array inside command objects
|
||||||
|
|
||||||
|
The other way around you can create objects dynamically using your own global functions.
|
||||||
|
|
||||||
|
> **Note**
|
||||||
|
>
|
||||||
|
> Functions called inside command objects share the same global scope as runtime macros.
|
||||||
|
> Therefore you can access host custom attributes like `host.vars.os`, or any other
|
||||||
|
> object attribute from inside the function definition used for [set_if](5-advanced-topics.md#use-functions-command-arguments-setif) or [command](5-advanced-topics.md#use-functions-command-attribute).
|
||||||
|
|
||||||
|
Tips when implementing functions:
|
||||||
|
|
||||||
|
* Use [log()](20-library-reference.md#global-functions) 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.
|
||||||
|
|
||||||
|
### <a id="use-functions-command-arguments-setif"></a> Use Functions in Command Arguments set_if
|
||||||
|
|
||||||
|
The `set_if` attribute inside the command arguments definition in the
|
||||||
|
[CheckCommand object definition](6-object-types.md#objecttype-checkcommand) is primarly used to
|
||||||
|
evaluate whether the command parameter should be set or not.
|
||||||
|
|
||||||
|
By default you can evaluate runtime macros for their existance, and if the result is not an empty
|
||||||
|
string the command parameter is passed. This becomes fairly complicated when want to evaluate
|
||||||
|
multiple conditions and attributes.
|
||||||
|
|
||||||
|
The following example was found on the community support channels. The user had defined a host
|
||||||
|
dictionary named `compellent` with the key `disks`. This was then used inside service apply for rules.
|
||||||
|
|
||||||
|
object Host "dict-host" {
|
||||||
|
check_command = "check_compellent"
|
||||||
|
vars.compellent["disks"] = {
|
||||||
|
file = "/var/lib/check_compellent/san_disks.0.json",
|
||||||
|
checks = ["disks"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The more significant problem was to only add the command parameter `--disk` to the plugin call
|
||||||
|
when the dictionary `compellent` contains the key `disks`, and omit it if not found.
|
||||||
|
|
||||||
|
By defining `set_if` as [abbreviated lambda function](19-language-reference.md#nullary-lambdas)
|
||||||
|
and evaluating the host custom attribute `compellent` containing the `disks` this problem was
|
||||||
|
solved like this:
|
||||||
|
|
||||||
|
object CheckCommand "check_compellent" {
|
||||||
|
import "plugin-check-command"
|
||||||
|
command = [ "/usr/bin/check_compellent" ]
|
||||||
|
arguments = {
|
||||||
|
"--disks" = {
|
||||||
|
set_if = {{
|
||||||
|
var host_vars = host.vars
|
||||||
|
log(host_vars)
|
||||||
|
var compel = host_vars.compellent
|
||||||
|
log(compel)
|
||||||
|
compel.contains("disks")
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
This implementation uses the dictionary type method [contains](20-library-reference.md#dictionary-contains)
|
||||||
|
and will fail if `host.vars.compellent` is not of the type `Dictionary`.
|
||||||
|
Therefore you can extend the checks using the [typeof](19-language-reference.md#types) function.
|
||||||
|
|
||||||
|
You can test the types using the `icinga2 console`:
|
||||||
|
|
||||||
|
# icinga2 console
|
||||||
|
Icinga (version: v2.3.0-193-g3eb55ad)
|
||||||
|
<1> => srv_vars.compellent["check_a"] = { file="outfile_a.json", checks = [ "disks", "fans" ] }
|
||||||
|
null
|
||||||
|
<2> => srv_vars.compellent["check_b"] = { file="outfile_b.json", checks = [ "power", "voltages" ] }
|
||||||
|
null
|
||||||
|
<3> => typeof(srv_vars.compellent)
|
||||||
|
type 'Dictionary'
|
||||||
|
<4> =>
|
||||||
|
|
||||||
|
The more programmatic approach for `set_if` could look like this:
|
||||||
|
|
||||||
|
"--disks" = {
|
||||||
|
set_if = {{
|
||||||
|
var srv_vars = service.vars
|
||||||
|
if(len(srv_vars) > 0) {
|
||||||
|
if (typeof(srv_vars.compellent) == Dictionary) {
|
||||||
|
return srv_vars.compellent.contains("disks")
|
||||||
|
} else {
|
||||||
|
log(LogInformationen, "checkcommand set_if", "custom attribute compellent_checks is not a dictionary, ignoring it.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log(LogWarning, "checkcommand set_if", "empty custom attributes")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### <a id="use-functions-command-attribute"></a> Use Functions as Command Attribute
|
||||||
|
|
||||||
|
This comes in handy for [NotificationCommands](6-object-types.md#objecttype-notificationcommand)
|
||||||
|
or [EventCommands](6-object-types.md#objecttype-eventcommand) which does not require
|
||||||
|
a returned checkresult including state/output.
|
||||||
|
|
||||||
|
The following example was taken from the community support channels. The requirement was to
|
||||||
|
specify a custom attribute inside the notification apply rule and decide which notification
|
||||||
|
script to call based on that.
|
||||||
|
|
||||||
|
object User "short-dummy" {
|
||||||
|
}
|
||||||
|
|
||||||
|
object UserGroup "short-dummy-group" {
|
||||||
|
assign where user.name == "short-dummy"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply Notification "mail-admins-short" to Host {
|
||||||
|
import "mail-host-notification"
|
||||||
|
command = "mail-host-notification-test"
|
||||||
|
user_groups = [ "short-dummy-group" ]
|
||||||
|
vars.short = true
|
||||||
|
assign where host.vars.notification.mail
|
||||||
|
}
|
||||||
|
|
||||||
|
The solution is fairly simple: The `command` attribute is implemented as function returning
|
||||||
|
an array required by the caller Icinga 2.
|
||||||
|
The local variable `mailscript` sets the default value for the notification scrip location.
|
||||||
|
If the notification custom attribute `short` is set, it will override the local variable `mailscript`
|
||||||
|
with a new value.
|
||||||
|
The `mailscript` variable is then used to compute the final notification command array being
|
||||||
|
returned.
|
||||||
|
|
||||||
|
You can omit the `log()` calls, they only help debugging.
|
||||||
|
|
||||||
|
object NotificationCommand "mail-host-notification-test" {
|
||||||
|
import "plugin-notification-command"
|
||||||
|
command = {{
|
||||||
|
log("command as function")
|
||||||
|
var mailscript = "mail-host-notification-long.sh"
|
||||||
|
if (notification.vars.short) {
|
||||||
|
mailscript = "mail-host-notification-short.sh"
|
||||||
|
}
|
||||||
|
log("Running command")
|
||||||
|
log(mailscript)
|
||||||
|
|
||||||
|
var cmd = [ SysconfDir + "/icinga2/scripts/" + mailscript ]
|
||||||
|
log(LogCritical, "me", cmd)
|
||||||
|
return cmd
|
||||||
|
}}
|
||||||
|
|
||||||
|
env = {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## <a id="access-object-attributes-at-runtime"></a> Access Object Attributes at Runtime
|
## <a id="access-object-attributes-at-runtime"></a> Access Object Attributes at Runtime
|
||||||
|
|
||||||
The [Object Accessor Functions](20-library-reference.md#object-accessor-functions)
|
The [Object Accessor Functions](20-library-reference.md#object-accessor-functions)
|
||||||
|
|
Loading…
Reference in New Issue