Getting a list of hosts inside config

Hey,

Why can’t I do the following?

for (h in get_objects(Host)) {
  object Service "Service_"+h.__name {

get_objects(Host) does not seem to return anything.


The reason why I want to do this is: I have a variable inside the host definition which is an array of dictionaries.

 [
 {
 ...
 },
 {
 ...
 }
 ]

If I define the Services like this:

apply Service "blubb_" for (el in host.vars.check) {

then the internal service name will contain the entire dictionary (el). This breaks PNP for example (won’t generate graphs).

Either I have to change the data structures everywhere, or I need to be able to set a simpler name somehow. Therefore my attempt to generate the objects “by hand” and not use “apply”…

Any idea?
Thanks.

Honestly I fail to understand what you’re trying to describe/achieve, sorry.
Can you post the real host’s custom variable (the full array with dictionary as you mentioned)?
And also describe what your ultimate goal is.

You might also want to have a look at the “Advanced Use of Apply Rules” section where examples show how to make use of dictionaries inside the custom variables: https://icinga.com/docs/icinga2/latest/doc/08-advanced-topics/#advanced-use-of-apply-rules

1 Like

Mainly, I was simply wondering why I using

for (h in get_objects(Host)) {
...

just like that in the configuration file (not inside an object or a function) produces no results.

This function will only evaluate after all config objects have been loaded as items and then committed into objects by the config compiler. Before that, within the static DSL code, it cannot access any objects. That being said, these object accessor functions are only available when evaluated at runtime e.g. inside lambda functions evaluated by command parameter resolving.

There’s ideas on GitHub to allow these methods being called “after all config objects have been loaded”, but nothing definite planned as features.

As @Napsty suggested, use apply for rules instead for solving this problem.

Cheers,
Michael

1 Like

Yep thanks, I figured that much in the end :slight_smile:

The solution to my actual problem (for which I was trying to find workarounds) was to change everything to using dictionaries to build the service list. I can’t recommend to anyone using an array like I did in my example, because as I noted, if the individual array elements are themselves dictionaries then all hell might break loose, at least in the addons. Using a dictionary as the high-level variable is safer because the key can’t be anything complex. (It is the key that is used by default in the internal service name.)

1 Like

Here’s the GitHub feature request in case you’d like to subscribe: https://github.com/Icinga/icinga2/issues/3520

1 Like

Ok, thanks.
But wouldn’t it make sense to output an error, or at least some kind of warning, since obviously this can never work? Instead, the config is just validated ok like that.

It is tremendously hard to detect in which scope this function gets called in the way the config compiler is implemented. Also, it only applies to some functions, others are totally valid being called. Basically the DSL expects that the person implementing it, also knows about the availability and scopes where being invoked. I truly understand that this isn’t for beginners, on the other hand, loops are considered a pretty much advanced feature.

TL;DR - I don’t know how to make it more convenient other than writing documentation and helping users here :slight_smile:

1 Like