Set current host/service variables from within a check function (which can be retrieved by REST api)

Dear Icinga team.

I’m trying to find a solution so that a check-function can initialize, set a service variable which can be seen outside the function, that is be visible to REST api query and Icinga Web console.
Is there a way to initialize the variable condition_text for host/service as i try to describe in below code pragma ?
There might be namespace/scope issue or i simply miss the working variable accessor …
Any hint would be highly welcome.
Best regards
Michael


apply Service "irpc-scenario-" for ( instance => conf  in host.vars.scenarios ) {
  check_command = "dummy"
  /* preset condition variables */
  vars.condition_state=0
  vars.condition_text="No condition is not met"
  oPtrServiceSelf = get_service(host.name, service.name )
  vars.dummy_state = {{
        oPtrServiceSelf = get_service(host.name, service.name )
        ... doing a lot...
        /* Try to update a service variable to indicate that condition is met*/
        if (lCondition) {
              this.vars.condition_text="Yes, that condition was found TRUE"
              this.vars.condition_state=1
              /* also tried 
              vars.condition_text="Yes, that condition was found TRUE"
              vars.condition_state=1
              */
              /* also tried 
              oPtrServiceSelf.vars.condition_text="Yes, that condition was found TRUE"
              oPtrServiceSelf.vars.condition_state=1
              */
        }
  }}
 ...
assign where host.vars.scenarios

}

There’s no safe way of doing this inside the DSL, nothing will trigger events like known from a real REST API call. If you would go that route, the daemon could easily crash because of missing input sanitizers. You can and should access objects to calculate something at runtime, and use the returned value for your check parameters or outputs. Your direction is a dangerous one and I don’t think we will add such things to the core DSL.

Cheers,
Michael

Hi Michael.
Thanks a lot for the guidance, i’ll take your advice serious and will not follow that way.
Maybe my hint to REST was a bit misleading as i only want to express that any assignment inside a lambda function is somehow working but obviously cannot update a service vars attribute.
Actually I’ve found way which seem to work as i just let a Lambda function calculate a service vars attribute.

template Service "irpc-scenario" {
  vars.dummy_state = {{
        return scenario_conditionmatrix(get_service(host.name, service.name ), macro("$condition_matrix$"), "state" )
    }}

  vars.dummy_text = {{
        return scenario_conditionmatrix(get_service(host.name, service.name ), macro("$condition_matrix$"), "text"  )
    }}

  vars.metadata_application = {{
        return scenario_conditionmatrix(get_service(host.name, service.name ), macro("$condition_matrix$"), "application" )
    }}

}

Unfortunately the scenario_conditionmatrix function is a bit costly and i’m looking for an option not to have the need to call this function three times but only once. So far i didn’t found a working solution.
The idea is to let the function return an array-pointer holding all results need in one shot and then have the results assigned in the service…
My last try (is not working and) looks like:

template Service "irpc-scenario" {
 /* pass self object-reference and condition_matrix ...*/
  vars.dummy_result=scenario_conditionmatrix(get_service(vars.host_name, vars.name ), vars.condition_matrix)
  vars.dummy_state=vars.dummy_result[0]
  vars.dummy_text=vars.dummy_result[1]
  vars.metdata_application=vars.dummy_result[2]
}

Do you have any idea , solution ?
Thx again for the helful comments on my topics.
Best regards
Michael

Hi,

currently there’s no way to “generate” vars from a function in order to not call those functions that often. A similar problem is with the cluster checks described in the docs. I’m not sure if it is possible to change vars into the Dictionary and Function object type - many underlaying code parts would be affected by this, and I’m not sure about the impact.

There’s also ideas to allow DSL-alike check result calculations and what not, but that also requires code changes and new features. I don’t think that this will become reality in 2019 though.

Right now, I don’t see a way rather than calling everything in their specific scope - and to avoid the many custom variables. It may be a better option to pre-fill them from an external script.

Cheers,
Michael