Icinga 2 command definitions can seem daunting at first. This blog post provides a quick introduction to some of the concepts you need to be familiar with when writing your own command definitions.

In their most basic form command definitions need a command line:

object CheckCommand "my_http" {
  import "plugin-check-command"

  command = [ PluginDir + "/check_http" ]
}

The “plugin-check-command” template tells Icinga how to execute commands, i.e. by executing an external plugin. There are a few other “*-check-command” templates but for virtually all of your own check commands you’ll need to use “plugin-check-command”.

The check_http plugin needs at least one more argument to work:

$ /opt/local/libexec/nagios/check_http -I 127.0.0.1
HTTP OK: HTTP/1.1 200 OK - 342 bytes in 0.001 second response time |time=0.001344s;;;0.000000 size=342B;;;0

We can add this argument to our check command like this:

object CheckCommand "my_http" {
  import "plugin-check-command"

  command = [ PluginDir + "/check_http" ]

  arguments = {
    "-I" = {
      value = "$my_http_address$"
      description = "IP address or name."
      required = true
    }
  }

  vars.my_http_address = "$address$"
}

The ‘required’ option tells Icinga to verify that the user specified a value for this argument.

We’re prefixing our custom attributes (my_http_address) with the name of the CheckCommand. This allows us to override specific custom attributes for HTTP checks on a per-host or per-service basis. If all
commands had the same custom attribute names (e.g. ‘timeout’) this wouldn’t be possible:

object Host "test" {
  ...

  // This affects all services on this host which use the my_http command
  vars.my_http_address = "127.0.0.1"
}

In our next step we’re going to add a few optional arguments. The check_http plugin lets us specify the ‘Host’ header and the URL that should be used. Adding optional arguments is rather simple:

    "-H" = {
      value = "$my_http_vhost$"
      description = "Host name argument for servers using host headers"
    }
    "-u" = {
      value = "$my_http_url$"
      description = "URL to GET or POST (default: /)"
    }

When Icinga encounters a command argument which uses an unresolvable macro (for example, because the user didn’t set a value for vars.my_http_vhost in their command, service or host) the entire argument is omitted.

Icinga can also add arguments only when certain conditions are met. In the next example I’m adding a new option ‘–sni’ which is only added when the custom attribute my_http_sni is set to true:

    "--sni" = {
      description = "Enable SSL/TLS hostname extension support (SNI)"
      set_if = "$my_http_sni$"
    }

Note that the ‘–sni’ option does not take an argument. Therefore we don’t need the ‘value’ attribute for this argument.

When the ‘my_http_sni’ custom attribute isn’t set at all Icinga defaults to not adding the argument.

There are a few more advanced topics for command arguments which aren’t covered in this blog post:

  • Ordering arguments
  • Using arrays for custom variables (with repeat_key/skip_key)
  • Using functions for set_if/value
  • Specifying an alternative ‘key’

I might write another blog post at a later point in time which deals with those features. In the meantime these things are explained in the documentation.

Gunnar Beutner

Autor: Gunnar Beutner

Vor seinem Eintritt bei NETWAYS arbeitete Gunnar bei einem großen deutschen Hostingprovider, wo er bereits viel Erfahrung in der Softwareentwicklung für das Servermanagement sammeln konnte. Bei uns kümmert er sich vor allem um verschiedene Kundenprojekte, aber auch eigene Tools wie inGraph oder Icinga2.