Example for a check_by_ssh using the Director

Hi there,
is there someone who has an example for a check_by_ssh-Check created with the director? I found some input but nothing really works, everytime getting some errors while deploying the configuration:

2019-08-28 10:39:58 +0200] critical/config: Error: syntax error, unexpected $undefined, expecting }} (T_NULLARY_LAMBDA_END)
Location: in [stage]/zones.d/director-global/commands.conf: 502:13-502:13
[stage]/zones.d/director-global/commands.conf(500):         }
[stage]/zones.d/director-global/commands.conf(501):         "-C" = {{
[stage]/zones.d/director-global/commands.conf(502):             $by_ssh_command$
                                                                ^
[stage]/zones.d/director-global/commands.conf(503):         }}
[2019-08-28 10:36:12 +0200] critical/config: Error: syntax error, unexpected / (T_DIVIDE_OP), expecting }} (T_NULLARY_LAMBDA_END)
Location: in [stage]/zones.d/director-global/commands.conf: 502:13-502:13
[stage]/zones.d/director-global/commands.conf(500):         }
[stage]/zones.d/director-global/commands.conf(501):         "-C" = {{
[stage]/zones.d/director-global/commands.conf(502):             /usr/lib/nagios/plugins/check_users -w $users_wgreater$ -c $users_cgreater$
                                                                ^
[stage]/zones.d/director-global/commands.conf(503):         }}

Also I found the following articel which seems to be a really good way, but I have no idea how to do something like that using the director:

Would be great if someone has an example or a good working solution.

Best regards Alicia

Hi,

can you please share the steps done inside the Director, including screenshots? That command looks “hand made” with DSL function code. Also, please attach the full rendered config from the commands.conf file.

Cheers,
Michael

Hi,

sorry, I had to delete it to deploy something else and now I can not reproduce it. I’m not sure what I habe made different this time, now I got an error while executen:

Error: Error while evaluating expression: std::bad_cast
Location: in /usr/share/icinga2/include/command-plugins.conf: 2179:16-2179:52
/usr/share/icinga2/include/command-plugins.conf(2177): 
/usr/share/icinga2/include/command-plugins.conf(2178):    var escaped_args = []
/usr/share/icinga2/include/command-plugins.conf(2179):    for (arg in resolve_arguments(command, arguments)) {
                                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/usr/share/icinga2/include/command-plugins.conf(2180):     escaped_args.add(escape_shell_arg(arg))
/usr/share/icinga2/include/command-plugins.conf(2181):    }

I first tried it with the two variables defined in /usr/share/icinga2/include/command-plugins.conf:


(tried $by_ssh_arguments$ as string and as array)

Because of the error I tried it with a custom variable vars.command because I’m not sure what the synthax in the command-plugin.conf means:

"-C" = {{
                        var command = macro("$by_ssh_command$")
                        var arguments = macro("$by_ssh_arguments$")

                        if (typeof(command) == String && !arguments) {
                                return command
                        }

                        var escaped_args = []
                        for (arg in resolve_arguments(command, arguments)) {
                                escaped_args.add(escape_shell_arg(arg))
                        }
                        return escaped_args.join(" ")
                }}

grafik

and got the same error.

So it seems like I don’t understand this all and could need an example of someone who has already done something like that.

Thanks, Alicia

Puh, that’s deep down. I’m on my ipad now, so just a short hint: resolve_arguments() expects specific argument value types (see the docs). It seems that either command or arguments is of the wrong type. You might want to add checks with typeof(command) == Array and log an error and return early if that is not the case.

Cheers,
Michael

Thanks for your reply but I’m sorry, I don’t get it…

It seems to be an Array but if I’m honest I don’t really get how I can set exactly that array. I tried it with defining $by_ssh_command$ and $by_ssh_arguments$ as array and also as strings (and every possible combination) but without any difference. I tried to find out what the macro function exactly does but only found a short part in the documentation like " In addition to these variables the macro function can be used to retrieve the value of arbitrary macro expressions" what not really helps me.

Seems like I have to visit the next Director Workshop :see_no_evil:

Maybe @mfrosch can you help a bit further, in this specific region I lack the knowledge. I’m currently debugging Nessus scan crashes for 2.11 which really needs to be finished :kissing_heart:

Not sure about the current status of your config.

My blog post is not really reproducible in Director, since the DSL trickery can’t be done with vars there.

Generally by_ssh is built to do this - which is not possible like this in Director.

apply Service "users" {
  import "generic-service"
  check_command = "by_ssh"
  vars.users_wgreater = 3
  vars.users_cgreater = 5
  vars.by_ssh_command = [ "/usr/lib/nagios/plugins/check_users" ]
  vars.by_ssh_arguments = {
    "-w" = "$users_wgreater$"
    "-c" = "$users_cgreater$"
  }
  // assign where ...
}

or this - which works in Director

apply Service "users" {
  import "generic-service"
  check_command = "by_ssh"
  vars.by_ssh_command = "/usr/lib/nagios/plugins/check_users -w 4 -c 5"
  // assign where ...
}

by_ssh_arguments are meant to work like arguments in any normal CheckCommand, they must be a Dictionary, and if used the command must be an array.

Question is: Do you just want to specify a command line for the remote side, or whats the plan?

1 Like

this is what I tried…

Yes, a simple command line would be enough, at the moment it is only an idea for very old OS which we can not monitor by agent.

How can I define by_ssh_arguments as Dictionary? Maybe this is the important fact, but I can not find some option for this in the Director?

And something more I have forgotten: In a "normal CheckCommand" I everytime could easy define the arguments as fields an use them, but in that special case there is not defined one variable for -C or I only do not understand it :smiley:

This can only be done via commands, where the Icinga DSL is possible.

One could build a by_ssh variant of each individual check, currently have no time to test this.

The easiest approach for you would be:

apply Service "users" {
  import "generic-service"
  check_command = "by_ssh"
  vars.users_wgreater = 3
  vars.users_cgreater = 5
  vars.by_ssh_command = "/usr/lib/nagios/plugins/check_users -w $users_wgreater$ -c $users_cgreater$"
  // assign where ...
}
1 Like

Thank you Markus,

this works. I will make my documentation and after it I will post my full solution for anybody who seeks a way to do this.

Best regards Alicia

1 Like

Here my Director Configuration:
Added a new datafield by_ssh_commandas string

Added the field by_ssh_command to the external command by_ssh

Created a Service for one check by ssh and filled the by_ssh_command with variables for the arguments for the by ssh used command (i.e. check_users)

Added the fields for the used command to the service

Hope this will help someone.

2 Likes