Error when using check_command for the check_curl plugin

Hi!

I needed to perform a check using curl requests to a website’s API.
Could you tell me how to use the check_curl module in Icinga?

If I add the command to service:

apply Service "balance" {
  check_command = "curl"
  vars.curl_url = ...
  ...
}

I get the following error:

[2025-03-15 17:43:29 +0300] critical/config: Error: Validation failed for object 'sv.example.com!balance' of type 'Service'; Attribute 'check_command': Object 'curl' of type 'CheckCommand' does not exist.
Location: in /etc/icinga2/zones.d/x64.by/sv.example.com.conf: 47:3-47:24
/etc/icinga2/zones.d/x64.by/sv.example.com.conf(45): 
/etc/icinga2/zones.d/x64.by/sv.example.com.conf(46): apply Service "balance" {
/etc/icinga2/zones.d/x64.by/sv.example.com.conf(47):   check_command = "curl"
                                                       ^^^^^^^^^^^^^^^^^^^^^^

Also I tried entering check-curl and check_curl, but it didn’t work.

  • Version used: r2.14.5-1
  • Operating System and version: Debian 12

To me it looks like it was committed

commit ba200f74e199f361ce6a1c6a6741454687f4eb24
Author: Lorenz Kästle <lorenz.kaestle@netways.de>
Date:   Fri Aug 30 12:25:27 2024 +0200

    Add check_curl to ITL (#9205)

but not released

git tag --contains ba200f74e199f361ce6a1c6a6741454687f4eb24

However

git branch --contains ba200f74e199f361ce6a1c6a6741454687f4eb24
* master

but it is not included in 2.14.5

grep curl /usr/share/icinga2/include/command-plugins.conf

Hence, you need to create (temporary) the command object yourself. If you want to use the offical code:

object CheckCommand "curl" {
        import "ipv4-or-ipv6"

        command = [ PluginDir + "/check_curl" ]

        arguments += {
                "--extra-opts" = {
                        value = "$curl_extra_opts$"
                        description = "Read options from an ini file"
                }
                "-H" = {
                        value = "$curl_vhost$"
                        description = "Host name argument for servers using host headers (virtual host). Append a port to include it in the header (eg: example.com:5000)"
                }
                "-I" = {
                        value = "$curl_ip$"
                        set_if = {{ string(macro("$curl_ip$")) != "" }}
                        description = "IP address or name (use numeric address if possible to bypass DNS lookup)."
                }
                "-p" = {
                        value = "$curl_port$"
                        description = "Port number (default: 80)"
                }
                "-4" = {
                        set_if = "$curl_ipv4$"
                        description = "Force `check_curl` to use IPv4 instead of choosing automatically"
                }
                "-6" = {
                        set_if = "$curl_ipv6$"
                        description = "Force `check_curl` to use IPv6 instead of choosing automatically"
                }
                "(-S w/ value)" = {
                        set_if = {{ macro("$curl_tls$") && string(macro("$curl_tls_version$")) != "" }}
                        key = "-S"
                        value = "$curl_tls_version$"
                        description = "Connect via SSL. Port defaults to 443. VERSION is optional, and prevents auto-negotiation"
                }
                "(-S w/o value)" = {
                        set_if = {{ macro("$curl_tls$") && string(macro("$curl_tls_version$")) == "" }}
                        key = "-S"
                        description = "Connect via SSL. Port defaults to 443. VERSION is optional, and prevents auto-negotiation"
                }
                "--sni" = {
                        set_if = "$curl_sni$"
                        description = "Enable SSL/TLS hostname extension support (SNI). Default if TLS version > 1.0"
                }
                "-C" = {
                        value = "$curl_certificate_valid_days_min_warning$,$curl_certificate_valid_days_min_critical$"
                        description = "Minimum number of days a certificate has to be valid."
                }
                "--continue-after-certificate" = {
                        value = "$curl_continue_after_certificate$"
                        description = "Allows the HTTP check to continue after performing the certificate check. Does nothing unless -C is used."
                }
                "-J" = {
                        value = "$curl_client_certificate_file$"
                        description = "Name of file that contains the client certificate (PEM format) to be used in establishing the SSL session"
                }
                "-K" = {
                        value = "$curl_client_certificate_key_file$"
                        description = "Name of file containing the private key (PEM format) matching the client certificate"
                }
                "--ca-cert" = {
                        value = "$curl_ca_cert_file$"
                        description = "CA certificate file to verify peer against"
                }
                "-D" = {
                        set_if = "$curl_verify_peer_cert$"
                        description = "Verify the peer's SSL certificate and hostname"
                }
                "-e" = {
                        value = "$curl_expect_string$"
                        description = "Comma-delimited list of strings, at least one of them is expected in the first (status) line of the server response (default: HTTP/), If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)"
                }
                "-d" = {
                        value = "$curl_expect_header_string$"
                        description = "String to expect in the response headers"
                }
                "-s" = {
                        value = "$curl_expect_content_string$"
                        description = "String to expect in the content"
                }
                "-u" = {
                        value = "$curl_url$"
                        description = "URL to GET or POST (default: /)"
                }
                "-P" = {
                        value = "$curl_post_data$"
                        description = "URL encoded http POST data"
                }
                "-j" = {
                        value = "$curl_http_method$"
                        description = "Set HTTP method (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"
                }
                "-N" = {
                        value = "$curl_no_body$"
                        description = "Don't wait for document body: stop reading after headers. (Note that this still does an HTTP GET or POST, not a HEAD.)"
                }
                "-M" = {
                        value = "$curl_max_age$"
                        description = "Warn if document is more than SECONDS old. the number can also be of the form '10m' for minutes, '10h' for hours, or '10d' for days."
                }
                "-T" = {
                        value = "$curl_content_type$"
                        description = "specify Content-Type header media type when POSTing"
                }
                "-l" = {
                        value = "$curl_linespan$"
                        description = "Allow regex to span newlines (must precede -r or -R)"
                }
                "-r" = {
                        value = "$curl_ereg$"
                        description = "Search page for regex STRING"
                }
                "-R" = {
                        value = "$curl_eregi$"
                        description = "Search page for case-insensitive regex STRING"
                }
                "--invert-regex" = {
                        set_if = "$curl_invert_regex$"
                        description = "When using regex, return CRITICAL if found, OK if not"
                }
                "--state-regex" = {
                        value = "$curl_state_regex$"
                        description = "Return STATE if regex is found, OK if not"
                }
                "-a" = {
                        value = "$curl_authorization$"
                        description = "Username:password on sites with basic authentication"
                }
                "-b" = {
                        value = "$curl_proxy_authorization$"
                        description = "Username:password on proxy-servers with basic authentication"
                }
                "-A" = {
                        value = "$curl_user_agent$"
                        description = "String to be sent in http header as 'User Agent'"
                }
                "-k" = {
                        value = "$curl_header$"
                        repeat_key = true
                        description = "Any other tags to be sent in http header. Use multiple times for additional headers"
                }
                "-E" = {
                        set_if = "$curl_extended_perfdata$"
                        description = "Print additional performance data"
                }
                "-B" = {
                        set_if = "$curl_show_body$"
                        description = "Print body content below status line"
                }
                "-L" = {
                        set_if = "$curl_link$"
                        description = "Wrap output in HTML link (obsoleted by urlize)"
                }
                "-f" = {
                        value = "$curl_onredirect$"
                        description = "Options: <ok|warning|critical|follow|sticky|stickyport|curl> How to handle redirected pages."
                }
                "--max-redirs" = {
                        value = "$curl_max_redirs$"
                        description = "Maximal number of redirects (default: 15)"
                }
                "-m" = {
                        value = "$curl_pagesize$"
                        description = "Minimum page size required (bytes) : Maximum page size required (bytes)"
                }
                "--http-version" = {
                        value = "$curl_http_version$"
                        description = "Connect via specific HTTP protocol. 1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)"
                }
                "--enable-automatic-decompression" = {
                        set_if = "$curl_enable_automatic_decompression$"
                        description = "Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING)."
                }
                "--haproxy-protocol" = {
                        set_if = "$curl_haproxy_protocol$"
                        description = "Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL)"
                }
                "--cookie-jar" = {
                        value = "$curl_cookie_jar_file$"
                        description = "Store cookies in the cookie jar file and send them out when requested."
                }
                "-w" = {
                        value = "$curl_warning$"
                        description = "Response time to result in warning status (seconds)"
                }
                "-c" = {
                        value = "$curl_critical$"
                        description = "Response time to result in critical status (seconds)"
                }
                "-t" = {
                        value = "$curl_timeout$"
                        description = "Seconds before connection times out (default: 10)"
                }
        }

        vars.curl_ip = "$check_address$"
        vars.curl_link = false
        vars.curl_invert_regex = false
        vars.curl_show_body = false
        vars.curl_extended_perfdata = false
        vars.check_ipv4 = "$curl_ipv4$"
        vars.check_ipv6 = "$curl_ipv6$"
}
2 Likes

@rsx
Thank you, you solved my problem that I had been struggling with for several days!

Sorry, this shouldn’t have happened. Usually the docs are being built for the latest release, but due to some error the docs were built based on the master branch. This is fixed now.

If you want to use the check_curl check command, please include it manually as @rsx advised. That’s how I am using them, btw.