voxpupuli / puppet-icinga2

Puppet module to manage Icinga 2
https://forge.puppet.com/icinga/icinga2
Apache License 2.0
61 stars 94 forks source link

user / users became a reserved keyword? Not stringified in final Icinga2 config #703

Closed Napsty closed 2 years ago

Napsty commented 2 years ago

Since puppet-icinga2 module was updated to the latest version a couple of days ago, we see issues related to "users" and "user" keywords used in configs.

Example 1: users as keyword in check command

A check "users" is applied to all the Linux hosts. Puppet config (YAML style):

  users:
    apply: true
    assign:
      - "host.vars.os == Linux"
    check_command: users
    command_endpoint: host.vars.client_endpoint
    import:
      - generic-service
    service_name: users
    target: /etc/icinga2/conf.d/services.conf
    zone: master

This results in the following config on the Icinga 2 servers once Puppet agent ran:

apply Service "users" {
  import "generic-service"

  check_command = users
  zone = "master"
  command_endpoint = host.vars.client_endpoint
  assign where host.vars.os == "Linux"
}

And the corresponding error:

Jun 20 17:41:42 icinga2 safe-reload[1792053]: [2022-06-20 17:41:42 +1000] critical/config: Error: Error while evaluating expression: Tried to access undefined script variable 'users'
Jun 20 17:41:42 icinga2 safe-reload[1792053]: Location: in /etc/icinga2/conf.d/services.conf: 272:19-272:23
Jun 20 17:41:42 icinga2 safe-reload[1792053]: /etc/icinga2/conf.d/services.conf(270):   import "generic-service"
Jun 20 17:41:42 icinga2 safe-reload[1792053]: /etc/icinga2/conf.d/services.conf(271):
Jun 20 17:41:42 icinga2 safe-reload[1792053]: /etc/icinga2/conf.d/services.conf(272):   check_command = users
Jun 20 17:41:42 icinga2 safe-reload[1792053]: 

Example 2: user keyword used as variable value

Here we have a similar situation where this time the keyword "user" is used as a variable value, used for a ipmi check. In the host definition we use:

    vars:
      client_endpoint: "name"
      ipmi_address: "10.10.10.10"
      ipmi_username: "ipmi"
      ipmi_password: "secret"
      ipmi_privilege_level: "user"
      ipmi_exclude_sensor_id: 116

This results in the following Host object on the Icinga 2 server:

object Host "brokenserver" {
[...]
  vars.ipmi_address = "10.10.10.10"
  vars.ipmi_password = "secret"
  vars.ipmi_username = "ipmi"
  vars.client_endpoint = name
  vars.ipmi_privilege_level = user
  vars.ipmi_exclude_sensor_id = 116

This breaks the config parser on the Icinga2 server:

[2022-06-24 17:26:17 +1000] critical/config: Error: Error while evaluating expression: Tried to access undefined script variable 'user'
Location: in /etc/icinga2/conf.d/hosts.conf: 215:31-215:34
/etc/icinga2/conf.d/hosts.conf(213):   vars.procs_critical = 600
/etc/icinga2/conf.d/hosts.conf(214):   vars.client_endpoint = name
/etc/icinga2/conf.d/hosts.conf(215):   vars.ipmi_privilege_level = user
                                                                   ^^^^
/etc/icinga2/conf.d/hosts.conf(216):   vars.ipmi_exclude_sensor_id = 116
/etc/icinga2/conf.d/hosts.conf(217): }

We've tried to use several workarounds to enforce a string on the "user" or "users" keywords, but none worked. We tried: '"users"', "'users'", ""users"", '"users"' but none worked (causes another config error because of a non-valid output).

Unfortunately I don't know which version of puppet-icinga2 was used before, but it has worked before the module upgrade.

Expected Behavior

We can use "users" or "user" as values.

Current Behavior

Looks like "users" and "user" has become a reserved keyword and it cannot be used as value anymore? Breaks resulting Icinga2 config.

Your Environment

lbetz commented 2 years ago

The solution is right at the beginning of section 'How configuration is paresed' (https://github.com/icinga/puppet-icinga2#how-configuration-is-parsed).

Napsty commented 2 years ago

Thanks for the quick answer and hint Lennart. Will try!

lbetz commented 2 years ago

But users is not a reserved word and should be quotet by default. Constants, reserved words and what is used as variables in apply for loops are not quotet.

Napsty commented 2 years ago

It's interesting. This one works:

service_name: "users"

But this one doesn't:

check_command: "users"

and results in:

apply Service "users" {
  import "generic-service"

  check_command = users
  zone = "master"
  command_endpoint = host.vars.client_endpoint
  assign where host.vars.os == "Linux"
}

Using the -: on the check_command does the job:

  users:
    apply: true
    assign:
      - "host.vars.os == Linux"
    check_command: -:"users"
    command_endpoint: host.vars.client_endpoint
    import:
      - generic-service
    service_name: users
    target: /etc/icinga2/conf.d/services.conf
    zone: master

Thank you for your help!