Object service with loop over dictionary

Hi,

I am trying to create object Service with inner loop over variable. Service must be executed locally.

It’s clearly stated in the documentation how to iterate over variable within apply Service statement but it’s always applied for Service executed remotely (in term of Top Down cluster it’s command endpoint scenario).

The most successful example, I was able to create, is attached bellow (most successful means the validation passed with warnings). With the example below the services won’t appear in WebUI and the cofig validation yield that the service won’t fit anywhere…

Please, is there anyone who knows the general solution for the topic?

Thank you in advance.

Example:

object CheckCommand "some_command" {
  command = [PluginDir + "/some_command"]

  arguments = {
    "--first" = {
     value = "$first_arg$"
    }
    "--second" = {
     value = "$second_args$"
    }
  }
} 

object Host "test.example" {
  import "generic-host"
  address = "test.example"
  vars.os = "Linux"
  vars.distro = "Debian"
  vars.agent_type = "Icinga"
  vars.agent_endpoint = "test.example"
  zone = "master"

  vars.first = ["a", "b", "c"]
}

apply Service "some_service" for (value in host.vars.first) { 
    import "generic-service"
    display_name = "name"
    host_name = "test.example"
    check_command = "some_command"

    vars.first = value
    vars.second = "4000"

  assign where host.vars.address == "test.example"
}

Environment:

  • Icinga2* - 2.13.3-1
  • Icinga2web* - 2.8.2-1
  • OS: Debian 10 - Buster
  • Icinga2 validation passed with warning: Apply rule “some_service” for type Service does not match anywhere!
  • Plugin is self-made

Hi @gitm1993

address is not a custom variable. If you want to match the host address use host.address.

Edit: you can just leave out the assign rule here. Icinga2 evalutes the ‘apply for’ rule for all host objects with the custom variable first set in this case.

Kind regards

1 Like

Hi ritzgu,

thanks for reply and good point with assignment. I’ve fixed the problem and it’s working. It seem I didn’t get the apply Service for definition.

Below is my thought process and working example for sake of completeness.


I’ve removed the assignment as it shouldn’t be needed.

Service definition:

apply Service "some_service" for (value in host.vars.first) { 
    import "generic-service"
    display_name = "name"
    host_name = "test.example"
    check_command = "some_command"

    vars.first = value
    vars.second = "4000"
}

The result was that Icinga was trying to execute check on the master node even the fact the variables were present only in satellite object host configuration and the configuration files was properly propagated.

Seemed to me like apply Service rule works only for remote execution and because of the missing agent_endpoint variable the check is executed locally on master.

I’ve added the agent_endpoint variable and removed the host_name variable.

And that is the correct setup.

apply Service "some_service" for (value in host.vars.first) { 
    import "generic-service"
    display_name = "name"
    check_command = "some_command"

    vars.first = value
    vars.second = "4000"
 
   command_endpoint = host.vars.agent_endpoint
}

Icinga creates the service check only for the those nodes that their “first” variable (IP address which is the real world variable I use to feed the script) is iterated in the “for” loop. Of course it make sense in case the “first” variable is present only in configuration files for specific nodes but in my case the “first” variable is list with IP addresses presented only in configuration file for satellite. So, Icinga is able to match the looped IP addresses and remote nodes.

Well the Icinga is more clever than I thought or I misunderstood documentation.