Hi,
AFAIK we had this discussion in another topic already, where I had suggested to hide these things in host templates. With importing the host templates into specific hosts, you can create generic apply rules.
Templates and Apply
template Host "basic-host" {
check_command = "hostalive"
}
template Host "windows-host-service-A" {
vars.service = "A"
}
template Host "windows-host-service-B" {
vars.service = "B"
}
template Host "windows-host-service-all" {
import "windows-host-service-A"
import "windows-host-service-B"
}
object Host "host-A" {
import "base-host"
import "windows-host-service-A"
}
object Host "host-B" {
import "base-host"
import "windows-host-service-B"
}
object Host "host-all" {
import "base-host"
import "windows-host-service-all"
}
Base on the template tree, you’ll automatically get certain attributes and the imported templates stored in the templates attribute.
This detail can be used to create generic service apply rules.
apply Service "service-A" {
check_command = "service-windows"
vars.service_win_service = host.vars.service //access the host custom vars
command_endpoint = host.vars.client_endpoint
assign where host.vars.service == "A" && host.vars.client_endpoint
}
apply Service "service-B" {
check_command = "service-windows"
vars.service_win_service = host.vars.service //access the host custom vars
command_endpoint = host.vars.client_endpoint
assign where host.vars.service == "B" && host.vars.client_endpoint
}
Advanced: Apply for
Based on the example above, you can use an array with service names hidden in the host template tree.
The idea is to only have one apply for rule, and the hosts as information provider with host.vars.services. Bonus: Arrays can be extended from template inheritance.
template Host "basic-host" {
check_command = "hostalive"
}
template Host "windows-host-service-A" {
vars.services += [ "A" ] //note the additive assignment operator, and also adding a new array element
}
template Host "windows-host-service-B" {
vars.services += [ "B" ] //note the additive assignment operator, and also adding a new array element
}
template Host "windows-host-service-all" {
import "windows-host-service-A"
import "windows-host-service-B"
}
object Host "host-A" {
import "base-host"
import "windows-host-service-A"
}
object Host "host-B" {
import "base-host"
import "windows-host-service-B"
}
object Host "host-all" {
import "base-host"
import "windows-host-service-all"
}
This technique uses a little DSL trick: Whether services is initialized as array already, it adds a new array element with the additive assignment operator +=. If the value was previously undefined, the added array element initializes this variable as array, with one element.
The resulting host objects now either have one array element with A or B, and the host-all object has [ "A", "B" ].
You can test such things in the debug console:
$ icinga2 console
Icinga 2 (version: v2.10.5-854-gf72ef9360)
Type $help to view available commands.
<1> => var services
null
<2> => services
null
<3> => services += [ "A" ]
null
<4> => services
[ "A" ]
<5> => services += [ "B" ]
null
<6> => services
[ "A", "B" ]
This detail can be used to build an apply for loop over this host scoped custom variable array.
apply for "service-" (s in host.vars.services) {
check_command = "service-windows"
vars.service_win_service = s //take the loop iteration variable value
command_endpoint = host.vars.client_endpoint
assign where host.vars.client_endpoint //In addition to host.vars.services being not empty, this condition must be met as well.
}
Specific notes, excerpt from the docs:
-
service- + the loop iteration variable value for s results in the final name
-
host.vars.services contains the array elements as service name strings
-
s can be used inside the apply for context, e.g. to create the display_name or, more importantly, to assign it to a custom variable required as parameter.
- the apply for loop will only be evaluated if
host.vars.services contains 1+ elements. In addition to creating service objects, the client_endpoint custom variable must also be set. This is checked again with assign where.
Note: I did not test the above, may contain minor typos. You’ll get the idea though.
Cheers,
Michael