I’m trying to set up a check using check_http that checks a set of pages on a webserver based on a custom array attached to each host object. While the number of checks expands to match the number of array elements, the check command seems to include all of them (so all checks are the same).
As a result of all array elements being added to the command the check looks like this:
Whereas I’d expect two checks like this: '/usr/lib/nagios/plugins/check_http' '-H' 'sub.example.org' '-I' '172.16.4.65' '-S' '-u' '/GiveMeA404'
and '/usr/lib/nagios/plugins/check_http' '-H' 'sub.example.org' '-I' '172.16.4.65' '-S' '-u' '/'
I don’t understand why Icinga is expanding the config to create the correct number of checks, yet the check command isn’t being expanded in the same way. The service template config is below.
Any advice would be gratefully appreciated. I’ve seen the fields interface array example but it stops short of explaining how to use the configuration.
Apologies, you’re correct. I’ve edited my original post to correct it.
Service apply rule - zones.d/director-global/service_apply.conf
apply Service "Webpage check for " for (config in host.vars.Pages_to_check) {
import "webpage-check"
assign where host.vars.Pages_to_check
import DirectorOverrideTemplate
}
Example host showing the array - zones.d/master/hosts.conf
Icinga doesn’t expand an array to multiple checks by just giving it an array for a variable.
After your apply for rule is through, you’ll end up with two services where one has /GiveMeA404 the other one / as value of the config variable. You’ll have to use this in your Service definition.
A general tip: Normally you don’t have to change the CheckCommands from the ITL. If you have to do, think twice if you didn’t just go the wrong way. (But if you really have to, your solution of inheriting the command is still the best)
Thank you both for your replies. Icinga2 is still quite new to me, so apologies if I ask a lot of (possibly obvious) questions. There’s been a few changes to the environment over lunch, so I’m pasting the up-to-date version.
@twidhalm - if I understand you correctly, the apply rule takes the array defined in the apply for box (so Pages_to_check in the config below) and puts that array into $config$. I should then use $config$ in my arguments list on the command? Icinga does a for each on the elements of the $config$ array. Have I got that correct?
Using $config$ instead gives me
“Error: Non-optional macro ‘config’ used in argument ‘-u’ is missing.”
I only created a new command (rather than using the provided check_http) because I couldn’t see how to add fields / arguments to the check. Suspect I’m missing something so any guidance appreciated.
@anon66228339 - by full service I’m assuming you mean the service with all of its imports? If so:
apply Service "Webpage check for " for (config in host.vars.Pages_to_check) {
import "https_webpage-check"
assign where host.vars.Pages_to_check
import DirectorOverrideTemplate
}
template Service "https_webpage-check" {
check_command = "HTTPS_PageCheck"
}
object CheckCommand "HTTPS_PageCheck" {
import "plugin-check-command"
import "http"
arguments += {
"-H" = "$Web_DNS_name$"
"-S" = {}
"-u" = {
required = true
value = "$Pages_to_check$"
}
}
}
You might want to check this howto, specifically the first screenshot where you navigate into the external imported CheckCommand and pick the Fields tab on the right.
In terms of the other question, the apply for rule generated passes the config loop variable to the service apply rule.
In its context, it is missing to set the custom variable Pages_to_check expected from your CheckCommand object below.
In the DSL this would look like this
apply Service "Webpage check for " for (config in host.vars.Pages_to_check) {
import "https_webpage-check"
vars.Pages_to_check = config //added, config is the loop value from host.vars.Pages_to_check
assign where host.vars.Pages_to_check
import DirectorOverrideTemplate
}
Now your task is to figure out how this can be done in the interface, can you share a screenshot of what you’ve done thus far?
OK, think I’m getting myself very confused here. Thank you all for your guidance so far and @dnsmichi for the link to that howto - that’s explained adding fields to checks nicely. I think I’ll need to specify my own command though as I need to say “this argument is populated with this field”.
To use the custom array on the host I’ve been following this tutorial. I’ve just tried to start from scratch but have got myself into a right mess. Screenshots etc. below.
Command
I’ve got a command, HTTP_Page_Check, based on HTTP, which I apply arguments to for -H (hostname) and -u (URL to check, relative to -H):
apply Service "HTTP webpage check for " for (config in host.vars.HTTP_Pages_To_Check) {
import "http-webpage-check"
assign where host.vars.HTTP_Pages_To_Check
import DirectorOverrideTemplate
}
The above configuration gives an error o the service (which seems to be correctly applied to various hosts):
Error: Non-optional macro ‘config’ used in argument ‘-u’ is missing.
I don’t understand why $config$ is missing. What am I doing wrong please?
$config$ is a special macro introduced by the Director when using apply rules with for loops. I don’t know much about its specific rendering, but reading the tutorial you’ve linked, your generated apply rule is missing a field.
apply Service "Check SSL certificate for " for (config in host.vars.ssl_domains) {
import "Check SSL certificates"
assign where host.vars.ssl_domains
vars.config = config //this one
import DirectorOverrideTemplate
}
Meaning to say, the apply rule is missing the custom property config sourcing from your http pages to check.
Though, the host object holds that array, right? Maybe you can add the current config object for Webserver?
Besides, which Director version are you using now?
Sorry, lots of things happening at work at the moment so I’ve not had opportunity to look into this further. Hopefully next week! Hope you had a good vacation.
Current Director version is 1.6.2 which is the latest release.
Yes, the host holds the HTTP pages array. I haven’t seen an existing object for Webserver though?
This requires the two fields http_web_dns_name and http_page to be defined as data field for this newly created CheckCommand. These fields should then be populated by service sets.
The apply for rule resulting from this should look like this:
apply Service "Webpage check for " for (config in host.vars.Pages_to_check) {
import "https_webpage-check"
//custom variables as data field attributes
vars.http_web_dns_name = host.name //or something else
vars.http_page = config //holds a single value, 1. iteration "/GiveMeA404" 2. iteration "/"
assign where host.vars.Pages_to_check
import DirectorOverrideTemplate
}
I’m not sure though how to configure that in the Director.