Local function is invalid with 2.11

Hi,

we try to migrate our config to 2.11. We use some functions for transforming values.

in file zones.d/master/server/services.conf

function remove_trailing_percentage(val) {
  string_val = val.to_string()
  cropped = string_val.substr(0, string_val.find("%"))
  return cropped
}

function get_linux_warn_load_by_core(core) {
  warn_one = core * 8
  warn_five = core * 5
  warn_fifteen = core * 4
  return warn_one + "," + warn_five + "," + warn_fifteen
}

function get_linux_crit_load_by_core(core) {
  crit_one = core * 10
  crit_five = core * 8
  crit_fifteen = core * 5
  return crit_one + "," + crit_five + "," + crit_fifteen
}

which is then used in the same file like

apply Service "linux-memory" {
  import "generic-service-linux-ssh"
  
  display_name = "RAM-Auslastung"
  check_command = "by_ssh_linux_memory"

  if(host.vars.linux_memory_warn && host.vars.linux_memory_crit) {
	vars.by_ssh_memory_warn = host.vars.linux_memory_warn
	vars.by_ssh_memory_crit = host.vars.linux_memory_crit
  }

  if(host.vars.linux_distribution == "sles" || host.vars.linux_distribution == "centos7") {
    if(host.vars.linux_memory_warn && host.vars.linux_memory_crit) {
      vars.by_ssh_memory_warn = remove_trailing_percentage(host.vars.by_ssh_memory_warn)
      vars.by_ssh_memory_crit = remove_trailing_percentage(host.vars.by_ssh_memory_crit)
    } else {
      vars.by_ssh_memory_warn = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_warn)
      vars.by_ssh_memory_crit = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_crit)
    }
  }

  assign where host.vars.os == "Linux"
  ignore where host.name == NodeName
}

apply Service "linux-load" {
  import "generic-service-linux-ssh"

  display_name = "Auslastung"
  check_command = "by_ssh_linux_load"

  if(host.vars.linux_load_warn && host.vars.linux_load_crit) {
    vars.by_ssh_load_warn = host.vars.linux_load_warn
	  vars.by_ssh_load_crit = host.vars.linux_load_crit
  } else if(host.vars.cpu.cores) {
    vars.by_ssh_load_warn = get_linux_warn_load_by_core(host.vars.cpu.cores)
    vars.by_ssh_load_crit = get_linux_crit_load_by_core(host.vars.cpu.cores)
  }

  assign where host.vars.os == "Linux"
  ignore where host.name == NodeName || host.vars.virt.guest_type == "container"
}

Right now, this fails with the following error but worked before:

[2019-12-04 10:35:56 +0000] information/cli: Icinga application loader (version: r2.11.2-1)
[2019-12-04 10:35:56 +0000] information/cli: Loading configuration file(s).
[2019-12-04 10:35:56 +0000] information/ConfigItem: Committing config item(s).
[2019-12-04 10:35:56 +0000] warning/Zone: The Zone object 'Skype-Servers' has more than two endpoints. Due to a known issue this type of configuration is strongly discouraged and may cause Icinga to use excessive amounts of CPU time.
[2019-12-04 10:35:56 +0000] warning/Zone: The Zone object 'Windows' has more than two endpoints. Due to a known issue this type of configuration is strongly discouraged and may cause Icinga to use excessive amounts of CPU time.
[2019-12-04 10:35:56 +0000] warning/ApiListener: Attribute 'key_path' for object 'api' of type 'ApiListener' is deprecated and should not be used.
[2019-12-04 10:35:56 +0000] warning/ApiListener: Attribute 'ca_path' for object 'api' of type 'ApiListener' is deprecated and should not be used.
[2019-12-04 10:35:56 +0000] warning/ApiListener: Attribute 'cert_path' for object 'api' of type 'ApiListener' is deprecated and should not be used.
[2019-12-04 10:35:56 +0000] warning/ApiListener: Copying '/etc/icinga2/pki/srv-im-icinga2.crt' certificate file to '/var/lib/icinga2/certs//srv-im-icinga2.crt'
[2019-12-04 10:35:56 +0000] warning/ApiListener: Copying '/etc/icinga2/pki/srv-im-icinga2.key' certificate file to '/var/lib/icinga2/certs//srv-im-icinga2.key'
[2019-12-04 10:35:56 +0000] warning/ApiListener: Copying '/etc/icinga2/pki/ca.crt' certificate file to '/var/lib/icinga2/certs//ca.crt'
[2019-12-04 10:35:56 +0000] warning/ApiListener: Please read the upgrading documentation for v2.8: https://icinga.com/docs/icinga2/latest/doc/16-upgrading-icinga-2/
[2019-12-04 10:35:56 +0000] information/ApiListener: My API identity: srv-im-icinga2
[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'get_linux_warn_load_by_core'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 301:29-301:76
/etc/icinga2/zones.d/master/server/services.conf(299):    vars.by_ssh_load_crit = host.vars.linux_load_crit
/etc/icinga2/zones.d/master/server/services.conf(300):   } else if(host.vars.cpu.cores) {
/etc/icinga2/zones.d/master/server/services.conf(301):     vars.by_ssh_load_warn = get_linux_warn_load_by_core(host.vars.cpu.cores)
                                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(302):     vars.by_ssh_load_crit = get_linux_crit_load_by_core(host.vars.cpu.cores)
/etc/icinga2/zones.d/master/server/services.conf(303):   }

[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'remove_trailing_percentage'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 228:33-228:124
/etc/icinga2/zones.d/master/server/services.conf(226):       vars.by_ssh_memory_crit = remove_trailing_percentage(host.vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(227):     } else {
/etc/icinga2/zones.d/master/server/services.conf(228):       vars.by_ssh_memory_warn = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_warn)
                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(229):       vars.by_ssh_memory_crit = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(230):     }

[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'remove_trailing_percentage'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 228:33-228:124
/etc/icinga2/zones.d/master/server/services.conf(226):       vars.by_ssh_memory_crit = remove_trailing_percentage(host.vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(227):     } else {
/etc/icinga2/zones.d/master/server/services.conf(228):       vars.by_ssh_memory_warn = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_warn)
                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(229):       vars.by_ssh_memory_crit = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(230):     }

[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'remove_trailing_percentage'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 228:33-228:124
/etc/icinga2/zones.d/master/server/services.conf(226):       vars.by_ssh_memory_crit = remove_trailing_percentage(host.vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(227):     } else {
/etc/icinga2/zones.d/master/server/services.conf(228):       vars.by_ssh_memory_warn = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_warn)
                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(229):       vars.by_ssh_memory_crit = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(230):     }

[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'remove_trailing_percentage'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 228:33-228:124
/etc/icinga2/zones.d/master/server/services.conf(226):       vars.by_ssh_memory_crit = remove_trailing_percentage(host.vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(227):     } else {
/etc/icinga2/zones.d/master/server/services.conf(228):       vars.by_ssh_memory_warn = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_warn)
                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(229):       vars.by_ssh_memory_crit = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(230):     }

[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'remove_trailing_percentage'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 228:33-228:124
/etc/icinga2/zones.d/master/server/services.conf(226):       vars.by_ssh_memory_crit = remove_trailing_percentage(host.vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(227):     } else {
/etc/icinga2/zones.d/master/server/services.conf(228):       vars.by_ssh_memory_warn = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_warn)
                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(229):       vars.by_ssh_memory_crit = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(230):     }

[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'get_linux_warn_load_by_core'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 301:29-301:76
/etc/icinga2/zones.d/master/server/services.conf(299):    vars.by_ssh_load_crit = host.vars.linux_load_crit
/etc/icinga2/zones.d/master/server/services.conf(300):   } else if(host.vars.cpu.cores) {
/etc/icinga2/zones.d/master/server/services.conf(301):     vars.by_ssh_load_warn = get_linux_warn_load_by_core(host.vars.cpu.cores)
                                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(302):     vars.by_ssh_load_crit = get_linux_crit_load_by_core(host.vars.cpu.cores)
/etc/icinga2/zones.d/master/server/services.conf(303):   }

[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'remove_trailing_percentage'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 228:33-228:124
/etc/icinga2/zones.d/master/server/services.conf(226):       vars.by_ssh_memory_crit = remove_trailing_percentage(host.vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(227):     } else {
/etc/icinga2/zones.d/master/server/services.conf(228):       vars.by_ssh_memory_warn = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_warn)
                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(229):       vars.by_ssh_memory_crit = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(230):     }

[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'remove_trailing_percentage'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 228:33-228:124
/etc/icinga2/zones.d/master/server/services.conf(226):       vars.by_ssh_memory_crit = remove_trailing_percentage(host.vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(227):     } else {
/etc/icinga2/zones.d/master/server/services.conf(228):       vars.by_ssh_memory_warn = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_warn)
                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(229):       vars.by_ssh_memory_crit = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(230):     }

[2019-12-04 10:35:58 +0000] critical/config: Error: Invalid field access (for value of type 'Service'): 'remove_trailing_percentage'
Location: in /etc/icinga2/zones.d/master/server/services.conf: 228:33-228:124
/etc/icinga2/zones.d/master/server/services.conf(226):       vars.by_ssh_memory_crit = remove_trailing_percentage(host.vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(227):     } else {
/etc/icinga2/zones.d/master/server/services.conf(228):       vars.by_ssh_memory_warn = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_warn)
                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/master/server/services.conf(229):       vars.by_ssh_memory_crit = remove_trailing_percentage(get_check_command("by_ssh_linux_memory").vars.by_ssh_memory_crit)
/etc/icinga2/zones.d/master/server/services.conf(230):     }

[2019-12-04 10:35:58 +0000] critical/config: 10 errors
[2019-12-04 10:35:58 +0000] critical/cli: Config validation failed. Re-run with 'icinga2 daemon -C' after fixing the config.

Were there some change in 2.11 regarding accessing object fields?

Best regards,
Hendrik

Hi,

I see. The functions are registered in the local file scope, but in order to process them, they need to be globally registered to being called from object scopes. I don’t know which change in 2.11 enforces this now, but before this behaviour with local functions was undefined.

I’d suggest moving the functions into a dedicated file, e.g. zones.d/global-templates/functions.conf and register them in the global config compiler scope like this:

globals.remove_trailing_percentage = function(val) {
  string_val = val.to_string()
  cropped = string_val.substr(0, string_val.find("%"))
  return cropped
}

globals.get_linux_warn_load_by_core = function(core) {
  warn_one = core * 8
  warn_five = core * 5
  warn_fifteen = core * 4
  return warn_one + "," + warn_five + "," + warn_fifteen
}

globals.get_linux_crit_load_by_core = function(core) {
  crit_one = core * 10
  crit_five = core * 8
  crit_fifteen = core * 5
  return crit_one + "," + crit_five + "," + crit_fifteen
}

More concrete explanations for registering functions can be found here.

Cheers,
Michael

1 Like