CodeBiene
(Code Biene)
February 15, 2023, 1:41pm
1
Hi!
At the moment I’m completely messed up which syntax I’ve to use in a function to get values of variables based on some conditions and how to return it as a string.
icinga2 - The Icinga 2 network monitoring daemon (version: r2.13.3-1)
The function “use_ext_IP” should return either the external IP address of a router, if the host variable “vars.address_ext” isn’t empty and if … or the host variable address.
The service has state ok and delivers exptected values, but as display_name I see “Service: Object of type ‘Function’ …”. And I don’t know which IP address was used.
object Host “rt-lte-01” {
address = “10.10.10.10”
vars.address_ext = “30.30.30.30”
vars.connection_type = “LTE”
…
}
apply Service “snmp-ext” to Host {
check_command = “snmp-statistic-ext”
vars.snmp_oid = “1.3.6.1.4.1.1.2.3.4.5.6.7.8.9”
display_name = use_ext_IP() # or {{ use_ext_IP() }}
vars.snmp_host = use_ext_IP()
…
assign where host.name == “rt-lte-01”
}
function use_ext_IP() {
var snmp_host = {{ host.address }} # or “$address$” or macro(“$address$”)
if ( {{ connection_type }} == “LTE” ) {
if ( “$address_ext$” != “” ) {
if ( “$hostname$” == “rt-lte-01” ) {
snmp_host = {{ vars.address_ext }}
}
}
}
return snmp_host
}
object CheckCommand “snmp-statistic-ext” {
command = [ PluginDir + “/check_snmp” ]
arguments = {
“-H” = “$snmp_host$”
“-o” = “$snmp_oid$”
“-l” = {
set_if = {{ “$snmp_label$” != “” }}
value = “$snmp_label$”
}
…
}
}
rsx
(Roland Sommer)
February 16, 2023, 7:51am
2
Hi & welcome,
You don’t need an external function here. You can directly check address_ext
within your service object like this:
if (host.vars.address_ext) {
display_name = host.vars.address_ext
vars.snmp_host = host.vars.address_ext
} else {
display_name = host.address
vars.snmp_host = host.address
}
And instead of assigning a host directly, you could (re)use the host variable like this:
assign where host.vars.connection_type == “LTE”
CodeBiene
(Code Biene)
February 16, 2023, 8:00am
3
Hi Roland,
thanks for your answer.
Will the syntax you proposed also work in a function?
I’ll give it a try.
The simple reason to use a function for that is, that I’ve several services where I don’t want to repeat the if else structure, especially because I could make changes in the future and add additional services.
Kind regards,
Peter
CodeBiene
(Code Biene)
February 16, 2023, 8:44am
4
Hi Roland,
within a function your proposed syntax don’t work.
[2023-02-16 09:38:35 +0100] critical/config: Error: Error while evaluating expression: Tried to access undefined script variable 'host'
Location: in /etc/icinga2/conf.d/services/cisco-router.conf: 125:19-125:22
/etc/icinga2/conf.d/services/cisco-router.conf(125): var snmp_host = host.address
^^^^
Kind regards,
Peter
rivad
(Dominik)
February 16, 2023, 8:49am
5
I think you need to wrap it in a macro()
like:
var snmp_host = macro("$address$")
https://icinga.com/docs/icinga-2/latest/doc/18-library-reference/#macro
CodeBiene
(Code Biene)
February 16, 2023, 9:06am
6
Hi Dominik,
thanks for your answer, but it still gives an error.
[2023-02-16 10:00:13 +0100] critical/config: Error: Argument is not a callable object.
Location: in /etc/icinga2/conf.d/services/cisco-router.conf: 124:19-124:36
/etc/icinga2/conf.d/services/cisco-router.conf(122): function use_ext_IP() {
/etc/icinga2/conf.d/services/cisco-router.conf(123): # invalid syntax: "$address$", host.address, {{ host.address }}
/etc/icinga2/conf.d/services/cisco-router.conf(124): var snmp_host = macro("$address$")
^^^^^^^^^^^^^^^^^^
Kind regards,
Peter
CodeBiene
(Code Biene)
February 16, 2023, 9:24am
7
Hi!
Within my function (see first post) I don’t get errors for these syntaxes:
var snmp_host = {{ host.address }}
var snmp_host = this.host.address
But I don’t have a clue which one does what and which one to use when.
Kind regards,
Peter
rsx
(Roland Sommer)
February 16, 2023, 10:51am
8
You could use a template instead of a function e.g.:
template Service "ipselect" {
if (host.vars.address_ext) {
display_name = host.vars.address_ext
vars.snmp_host = host.vars.address_ext
} else {
display_name = host.address
vars.snmp_host = host.address
}
}
and use it in any service object with import
:
import “ipselect”
1 Like
CodeBiene
(Code Biene)
February 17, 2023, 2:56pm
9
Hi Roland,
thanks for your hint.
With such a service template I could solve it.
Kind regards,
Peter