diff --git a/components/livestatus/hoststable.cpp b/components/livestatus/hoststable.cpp index e3faadc0d..1b71cce29 100644 --- a/components/livestatus/hoststable.cpp +++ b/components/livestatus/hoststable.cpp @@ -295,7 +295,7 @@ Value HostsTable::NotesExpandedAccessor(const Value& row) resolvers.push_back(std::make_pair("host", host)); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - return MacroProcessor::ResolveMacros(host->GetNotes(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd); + return MacroProcessor::ResolveMacros(host->GetNotes(), resolvers, CheckResult::Ptr()); } Value HostsTable::NotesUrlAccessor(const Value& row) @@ -319,7 +319,7 @@ Value HostsTable::NotesUrlExpandedAccessor(const Value& row) resolvers.push_back(std::make_pair("host", host)); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - return MacroProcessor::ResolveMacros(host->GetNotesUrl(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd); + return MacroProcessor::ResolveMacros(host->GetNotesUrl(), resolvers); } Value HostsTable::ActionUrlAccessor(const Value& row) @@ -343,7 +343,7 @@ Value HostsTable::ActionUrlExpandedAccessor(const Value& row) resolvers.push_back(std::make_pair("host", host)); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - return MacroProcessor::ResolveMacros(host->GetActionUrl(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd); + return MacroProcessor::ResolveMacros(host->GetActionUrl(), resolvers); } Value HostsTable::PluginOutputAccessor(const Value& row) @@ -399,7 +399,7 @@ Value HostsTable::IconImageExpandedAccessor(const Value& row) resolvers.push_back(std::make_pair("host", host)); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - return MacroProcessor::ResolveMacros(host->GetIconImage(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd); + return MacroProcessor::ResolveMacros(host->GetIconImage(), resolvers); } Value HostsTable::IconImageAltAccessor(const Value& row) diff --git a/components/livestatus/servicestable.cpp b/components/livestatus/servicestable.cpp index 52b1a19d4..450def9ab 100644 --- a/components/livestatus/servicestable.cpp +++ b/components/livestatus/servicestable.cpp @@ -315,7 +315,7 @@ Value ServicesTable::NotesExpandedAccessor(const Value& row) resolvers.push_back(std::make_pair("host", service->GetHost())); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - return MacroProcessor::ResolveMacros(service->GetNotes(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd); + return MacroProcessor::ResolveMacros(service->GetNotes(), resolvers); } Value ServicesTable::NotesUrlAccessor(const Value& row) @@ -340,7 +340,7 @@ Value ServicesTable::NotesUrlExpandedAccessor(const Value& row) resolvers.push_back(std::make_pair("host", service->GetHost())); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - return MacroProcessor::ResolveMacros(service->GetNotesUrl(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd); + return MacroProcessor::ResolveMacros(service->GetNotesUrl(), resolvers); } Value ServicesTable::ActionUrlAccessor(const Value& row) @@ -365,7 +365,7 @@ Value ServicesTable::ActionUrlExpandedAccessor(const Value& row) resolvers.push_back(std::make_pair("host", service->GetHost())); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - return MacroProcessor::ResolveMacros(service->GetActionUrl(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd); + return MacroProcessor::ResolveMacros(service->GetActionUrl(), resolvers); } Value ServicesTable::IconImageAccessor(const Value& row) @@ -390,7 +390,7 @@ Value ServicesTable::IconImageExpandedAccessor(const Value& row) resolvers.push_back(std::make_pair("host", service->GetHost())); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - return MacroProcessor::ResolveMacros(service->GetIconImage(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd); + return MacroProcessor::ResolveMacros(service->GetIconImage(), resolvers); } Value ServicesTable::IconImageAltAccessor(const Value& row) diff --git a/doc/5-icinga-template-library.md b/doc/5-icinga-template-library.md index e82543681..a225e5f3b 100644 --- a/doc/5-icinga-template-library.md +++ b/doc/5-icinga-template-library.md @@ -23,13 +23,13 @@ Custom Attributes: Name | Description ----------------|-------------- -address | **Required.** The host's address. -wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. -wpl | **Optional.** The packet loss warning threshold in %. Defaults to 5. -crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. -cpl | **Optional.** The packet loss critical threshold in %. Defaults to 15. -packets | **Optional.** The number of packets to send. Defaults to 5. -timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). +ping_address | **Optional.** The host's IPv4 address. Defaults to "$address$". +ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. +ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 5. +ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. +ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 15. +ping_packets | **Optional.** The number of packets to send. Defaults to 5. +ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### ping6 @@ -39,13 +39,13 @@ Custom Attributes: Name | Description ----------------|-------------- -address6 | **Required.** The host's IPv6 address. -wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. -wpl | **Optional.** The packet loss warning threshold in %. Defaults to 5. -crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. -cpl | **Optional.** The packet loss critical threshold in %. Defaults to 15. -packets | **Optional.** The number of packets to send. Defaults to 5. -timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). +ping_address | **Optional.** The host's IPv6 address. Defaults to "$address6$". +ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. +ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 5. +ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. +ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 15. +ping_packets | **Optional.** The number of packets to send. Defaults to 5. +ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### hostalive @@ -55,13 +55,13 @@ Custom Attributes: Name | Description ----------------|-------------- -address | **Required.** The host's IPv4 address. -wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 3000.0. -wpl | **Optional.** The packet loss warning threshold in %. Defaults to 80. -crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 5000.0. -cpl | **Optional.** The packet loss critical threshold in %. Defaults to 100. -packets | **Optional.** The number of packets to send. Defaults to 5. -timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). +ping_address | **Optional.** The host's IPv4 address. Defaults to "$address$". +ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 3000. +ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 80. +ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 5000. +ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 100. +ping_packets | **Optional.** The number of packets to send. Defaults to 5. +ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### dummy @@ -71,8 +71,8 @@ Custom Attributes: Name | Description ----------------|-------------- -state | **Optional.** The state. Can be one of 0 (ok), 1 (warning), 2 (critical) and 3 (unknown). Defaults to 0. -text | **Optional.** Plugin output. Defaults to "Check was successful.". +dummy_state | **Optional.** The state. Can be one of 0 (ok), 1 (warning), 2 (critical) and 3 (unknown). Defaults to 0. +dummy_text | **Optional.** Plugin output. Defaults to "Check was successful.". ### passive @@ -82,8 +82,8 @@ Custom Attributes: Name | Description ----------------|-------------- -state | **Optional.** The state. Can be one of 0 (ok), 1 (warning), 2 (critical) and 3 (unknown). Defaults to 3. -text | **Optional.** Plugin output. Defaults to "No Passive Check Result Received.". +dummy_state | **Optional.** The state. Can be one of 0 (ok), 1 (warning), 2 (critical) and 3 (unknown). Defaults to 3. +dummy_text | **Optional.** Plugin output. Defaults to "No Passive Check Result Received.". ### tcp @@ -93,8 +93,8 @@ Custom Attributes: Name | Description ----------------|-------------- -address | **Required.** The host's address. -port | **Required.** The port that should be checked. +tcp_address | **Optional.** The host's address. Defaults to "$address$". +tcp_port | **Required.** The port that should be checked. ### udp @@ -104,48 +104,24 @@ Custom Attributes: Name | Description ----------------|-------------- -address | **Required.** The host's address. -port | **Required.** The port that should be checked. +udp_address | **Optional.** The host's address. Defaults to "$address$". +udp_port | **Required.** The port that should be checked. -### http_vhost +### http Check command object for the `check_http` plugin. Custom Attributes: -Name | Description -----------------|-------------- -vhost | **Required.** The name of the virtual host that should be checked. - -### http_ip - -Check command object for the `check_http` plugin. - -Custom Attributes: - -Name | Description -----------------|-------------- -address | **Required.** The host's address. - -### https_vhost - -Check command object for the `check_http` plugin. - -Custom Attributes: - -Name | Description -----------------|-------------- -vhost | **Required.** The name of the virtual host that should be checked. - -### https_ip - -Check command object for the `check_http` plugin. - -Custom Attributes: - -Name | Description -----------------|-------------- -address | **Required.** The host's address. +Name | Description +-------------------|-------------- +http_address | **Optional.** The host's address. Defaults to "$address". +http_vhost | **Optional.** The virtual host that should be sent in the "Host" header. +http_uri | **Optional.** The request URI. +http_port | **Optional.** The TCP port. Defaults to 80 when not using SSL, 443 otherwise. +http_ssl | **Optional.** Whether to use SSL. Defaults to false. +http_warn_time | **Optional.** The warning threshold. +http_critical_time | **Optional.** The critical threshold. ### smtp @@ -153,9 +129,9 @@ Check command object for the `check_smtp` plugin. Custom Attributes: -Name | Description -----------------|-------------- -address | **Required.** The host's address. +Name | Description +---------------------|-------------- +smtp_address | **Optional.** The host's address. Defaults to "$address$". ### ssmtp @@ -165,8 +141,8 @@ Custom Attributes: Name | Description ----------------|-------------- -address | **Required.** The host's address. -port | **Optional.** The port that should be checked. Defaults to 465. +ssmtp_address | **Required.** The host's address. Defaults to "$address$". +ssmtp_port | **Optional.** The port that should be checked. Defaults to 465. ### ntp_time @@ -176,7 +152,7 @@ Custom Attributes: Name | Description ----------------|-------------- -address | **Required.** The host's address. +ntp_address | **Optional.** The host's address. Defaults to "$address$". ### ssh @@ -186,7 +162,7 @@ Custom Attributes: Name | Description ----------------|-------------- -address | **Required.** The host's address. +ssh_address | **Optional.** The host's address. Defaults to "$address$". ### disk @@ -196,8 +172,8 @@ Custom Attributes: Name | Description ----------------|-------------- -wfree | **Optional.** The free space warning threshold in %. Defaults to 20. -cfree | **Optional.** The free space critical threshold in %. Defaults to 10. +disk_wfree | **Optional.** The free space warning threshold in %. Defaults to 20. +disk_cfree | **Optional.** The free space critical threshold in %. Defaults to 10. ### users @@ -207,10 +183,10 @@ Custom Attributes: Name | Description ----------------|-------------- -wgreater | **Optional.** The user count warning threshold. Defaults to 20. -cgreater | **Optional.** The user count critical threshold. Defaults to 50. +users_wgreater | **Optional.** The user count warning threshold. Defaults to 20. +users_cgreater | **Optional.** The user count critical threshold. Defaults to 50. -### processes +### procs Check command object for the `check_procs` plugin. @@ -218,8 +194,8 @@ Custom Attributes: Name | Description ----------------|-------------- -wgreater | **Optional.** The process count warning threshold. Defaults to 250. -cgreater | **Optional.** The process count critical threshold. Defaults to 400. +procs_wgreater | **Optional.** The process count warning threshold. Defaults to 250. +procs_cgreater | **Optional.** The process count critical threshold. Defaults to 400. ### swap @@ -229,8 +205,8 @@ Custom Attributes: Name | Description ----------------|-------------- -wfree | **Optional.** The free swap space warning threshold in %. Defaults to 50. -cfree | **Optional.** The free swap space critical threshold in %. Defaults to 25. +swap_wfree | **Optional.** The free swap space warning threshold in %. Defaults to 50. +swap_cfree | **Optional.** The free swap space critical threshold in %. Defaults to 25. ### load @@ -240,12 +216,12 @@ Custom Attributes: Name | Description ----------------|-------------- -wload1 | **Optional.** The 1-minute warning threshold. Defaults to 5. -wload5 | **Optional.** The 5-minute warning threshold. Defaults to 4. -wload15 | **Optional.** The 15-minute warning threshold. Defaults to 3. -cload1 | **Optional.** The 1-minute critical threshold. Defaults to 10. -cload5 | **Optional.** The 5-minute critical threshold. Defaults to 6. -cload15 | **Optional.** The 15-minute critical threshold. Defaults to 4. +load_wload1 | **Optional.** The 1-minute warning threshold. Defaults to 5. +load_wload5 | **Optional.** The 5-minute warning threshold. Defaults to 4. +load_wload15 | **Optional.** The 15-minute warning threshold. Defaults to 3. +load_cload1 | **Optional.** The 1-minute critical threshold. Defaults to 10. +load_cload5 | **Optional.** The 5-minute critical threshold. Defaults to 6. +load_cload15 | **Optional.** The 15-minute critical threshold. Defaults to 4. ### snmp @@ -255,9 +231,9 @@ Custom Attributes: Name | Description ----------------|-------------- -address | **Required.** The host's address. -oid | **Required.** The SNMP OID. -community | **Optional.** The SNMP community. Defaults to "public". +snmp_address | **Optional.** The host's address. Defaults to "$address$". +snmp_oid | **Required.** The SNMP OID. +snmp_community | **Optional.** The SNMP community. Defaults to "public". ### snmp-uptime @@ -267,9 +243,9 @@ Custom Attributes: Name | Description ----------------|-------------- -address | **Required.** The host's address. -oid | **Optional.** The SNMP OID. Defaults to "1.3.6.1.2.1.1.3.0". -community | **Optional.** The SNMP community. Defaults to "public". +snmp_address | **Optional.** The host's address. Defaults to "$address$". +snmp_oid | **Optional.** The SNMP OID. Defaults to "1.3.6.1.2.1.1.3.0". +snmp_community | **Optional.** The SNMP community. Defaults to "public". ### apt diff --git a/etc/CMakeLists.txt b/etc/CMakeLists.txt index b6994d7d7..93f642d3d 100644 --- a/etc/CMakeLists.txt +++ b/etc/CMakeLists.txt @@ -33,7 +33,7 @@ install_if_not_exists(icinga2/conf.d/hosts/localhost/http.conf ${CMAKE_INSTALL_S install_if_not_exists(icinga2/conf.d/hosts/localhost/icinga.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost) install_if_not_exists(icinga2/conf.d/hosts/localhost/kernel.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost) install_if_not_exists(icinga2/conf.d/hosts/localhost/load.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost) -install_if_not_exists(icinga2/conf.d/hosts/localhost/processes.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost) +install_if_not_exists(icinga2/conf.d/hosts/localhost/procs.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost) install_if_not_exists(icinga2/conf.d/hosts/localhost/ssh.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost) install_if_not_exists(icinga2/conf.d/hosts/localhost/swap.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost) install_if_not_exists(icinga2/conf.d/hosts/localhost/users.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost) diff --git a/etc/icinga2/conf.d/hosts/localhost/http.conf b/etc/icinga2/conf.d/hosts/localhost/http.conf index ca9e2270e..07506d223 100644 --- a/etc/icinga2/conf.d/hosts/localhost/http.conf +++ b/etc/icinga2/conf.d/hosts/localhost/http.conf @@ -2,5 +2,5 @@ object Service "http" { import "generic-service" host_name = "localhost" - check_command = "http_ip" + check_command = "http" } diff --git a/etc/icinga2/conf.d/hosts/localhost/processes.conf b/etc/icinga2/conf.d/hosts/localhost/processes.conf deleted file mode 100644 index db0cffc7d..000000000 --- a/etc/icinga2/conf.d/hosts/localhost/processes.conf +++ /dev/null @@ -1,7 +0,0 @@ -object Service "processes" { - import "generic-service" - - host_name = "localhost" - check_command = "processes" -} - diff --git a/etc/icinga2/conf.d/hosts/localhost/procs.conf b/etc/icinga2/conf.d/hosts/localhost/procs.conf new file mode 100644 index 000000000..e62387ecb --- /dev/null +++ b/etc/icinga2/conf.d/hosts/localhost/procs.conf @@ -0,0 +1,7 @@ +object Service "procs" { + import "generic-service" + + host_name = "localhost" + check_command = "procs" +} + diff --git a/itl/command-common.conf b/itl/command-common.conf index b3aa1ec8a..2c50a23a9 100644 --- a/itl/command-common.conf +++ b/itl/command-common.conf @@ -17,58 +17,57 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ -object CheckCommand "ping4" { +template CheckCommand "ping-common" { import "plugin-check-command", command = [ - PluginDir + "/check_ping", - "-4", - "-H", "$address$", - "-w", "$wrta$,$wpl$%", - "-c", "$crta$,$cpl$%", - "-p", "$packets$", - "-t", "$timeout$" - ], + PluginDir + "/check_ping" + ] - vars.wrta = 100 - vars.wpl = 5 - vars.crta = 200 - vars.cpl = 15 - vars.packets = 5 - vars.timeout = 0 + arguments = { + "-H" = "$ping_address$" + "-w" = "$ping_wrta$,$ping_wpl$%" + "-c" = "$ping_crta$,$ping_cpl$%" + "-p" = { + value = "$ping_packets$" + optional = true + } + "-t" = { + value = "$ping_timeout$" + optional = true + } + } + + vars.ping_wrta = 100 + vars.ping_wpl = 5 + vars.ping_crta = 200 + vars.ping_cpl = 15 +} + +object CheckCommand "ping4" { + import "ping-common", + + command += [ "-4" ] + + vars.ping_address = "$address$" } object CheckCommand "ping6" { - import "plugin-check-command", + import "ping-common", - command = [ - PluginDir + "/check_ping", - "-6", - "-H", "$address6$", - "-w", "$wrta$,$wpl$%", - "-c", "$crta$,$cpl$%", - "-p", "$packets$", - "-t", "$timeout$" - ], + command += [ "-6" ] - vars.wrta = 100, - vars.wpl = 5, - - vars.crta = 200, - vars.cpl = 15, - - vars.packets = 5, - vars.timeout = 0 + vars.ping_address = "$address6$" } object CheckCommand "hostalive" { import "ping4" - vars.wrta = 3000.0, - vars.wpl = 80, + vars.ping_wrta = 3000.0, + vars.ping_wpl = 80, - vars.crta = 5000.0, - vars.cpl = 100 + vars.ping_crta = 5000.0, + vars.ping_cpl = 100 } object CheckCommand "dummy" { @@ -76,19 +75,19 @@ object CheckCommand "dummy" { command = [ PluginDir + "/check_dummy", - "$state$", - "$text$" + "$dummy_state$", + "$dummy_text$" ], - vars.state = 0, - vars.text = "Check was successful." + vars.dummy_state = 0, + vars.dummy_text = "Check was successful." } object CheckCommand "passive" { import "dummy", - vars.state = 3, - vars.text = "No Passive Check Result Received." + vars.dummy_state = 3, + vars.dummy_text = "No Passive Check Result Received." } object CheckCommand "tcp" { @@ -96,9 +95,11 @@ object CheckCommand "tcp" { command = [ PluginDir + "/check_tcp", - "-H", "$address$", - "-p", "$port$" + "-H", "$tcp_address$", + "-p", "$tcp_port$" ] + + vars.tcp_address = "$address$" } object CheckCommand "udp" { @@ -106,173 +107,194 @@ object CheckCommand "udp" { command = [ PluginDir + "/check_udp", - "-H", "$address$", - "-p", "$port$" + "-H", "$udp_address$", + "-p", "$udp_port$" ] + + vars.udp_address = "$address$" } -object CheckCommand "http_vhost" { +object CheckCommand "http" { import "plugin-check-command", - command = [ - PluginDir + "/check_http", - "-H", "$vhost$" - ] -} + command = PluginDir + "/check_http" + + arguments = { + "-H" = { + value = "$http_vhost$" + optional = true + } + "-I" = "$http_address$" + "-u" = { + value = "$http_uri$" + optional = true + } + "-p" = { + value = "$http_port$" + optional = true + } + "-S" = { + set_if = "$http_ssl$" + } + "-w" = { + value = "$http_warn_time$" + optional = true + } + "-c" = { + value = "$http_critical_time$" + optional = true + } + } -object CheckCommand "http_ip" { - import "plugin-check-command", - - command = [ - PluginDir + "/check_http", - "-H", "$address$" - ] -} - -object CheckCommand "https_vhost" { - import "plugin-check-command", - - command = [ - PluginDir + "/check_http", - "-H", "$vhost$", "-S" - ] -} - -object CheckCommand "https_ip" { - import "plugin-check-command", - - command = [ - PluginDir + "/check_http", - "-I", "$address$", "-S" - ] + vars.http_address = "$address$" + vars.http_ssl = false } object CheckCommand "smtp" { - import "plugin-check-command", + import "plugin-check-command" - command = [ - PluginDir + "/check_smtp", - "-H", "$address$" - ] + command = PluginDir + "/check_smtp" + + arguments = { + "-H" = "$smtp_address$" + } + + vars.smtp_address = "$address$" } object CheckCommand "ssmtp" { - import "plugin-check-command", + import "plugin-check-command" - command = [ - PluginDir + "/check_ssmtp", - "-H", "$address$", - "-p", "$port$" - ], + command = PluginDir + "/check_ssmtp" - vars.port = 465 + arguments = { + "-H" = "$ssmtp_address$" + "-p" = { + value = "$ssmtp_port$" + optional = true + } + } + + vars.ssmtp_address = "$address$" } object CheckCommand "ntp_time" { - import "plugin-check-command", + import "plugin-check-command" - command = [ - PluginDir + "/check_ntp_time", - "-H", "$address$" - ] + command = PluginDir + "/check_ntp_time" + + arguments = { + "-H" = "$ntp_address$" + } + + vars.ntp_address = "$address$" } object CheckCommand "ssh" { - import "plugin-check-command", + import "plugin-check-command" command = [ PluginDir + "/check_ssh", - "$address$" + "$ssh_address$" ] + + vars.ssh_address = "$address$" } object CheckCommand "disk" { import "plugin-check-command", - command = [ - PluginDir + "/check_disk", - "-w", "$wfree$%", - "-c", "$cfree$%" - ], + command = PluginDir + "/check_disk" - vars.wfree = 20, - vars.cfree = 10, + arguments = { + "-w" = "$disk_wfree$%" + "-c" = "$disk_cfree$%" + } + + vars.disk_wfree = 20 + vars.disk_cfree = 10 } object CheckCommand "users" { import "plugin-check-command", - command = [ - PluginDir + "/check_users", - "-w", "$wgreater$", - "-c", "$cgreater$" - ], + command = PluginDir + "/check_users" - vars.wgreater = 20, - vars.cgreater = 50, + arguments = { + "-w" = "users_wgreater$" + "-c" = "$users_cgreater$" + } + + vars.users_wgreater = 20 + vars.users_cgreater = 50 } -object CheckCommand "processes" { +object CheckCommand "procs" { import "plugin-check-command", - command = [ - PluginDir + "/check_procs", - "-w", "$wgreater$", - "-c", "$cgreater$" - ], + command = PluginDir + "/check_procs" - vars.wgreater = 250, - vars.cgreater = 400, + arguments = { + "-w" = "$procs_wgreater$" + "-c" = "$procs_cgreater$" + } + + vars.procs_wgreater = 250 + vars.procs_cgreater = 400, } object CheckCommand "swap" { import "plugin-check-command", - command = [ - PluginDir + "/check_swap", - "-w", "$wfree$%", - "-c", "$cfree$%" - ], + command = PluginDir + "/check_swap" - vars.wfree = 50, - vars.cfree = 25, + arguments = { + "-w" = "$swap_wfree$%", + "-c" = "$swap_cfree$%" + } + + vars.swap_wfree = 50 + vars.swap_cfree = 25 } object CheckCommand "load" { import "plugin-check-command", - command = [ - PluginDir + "/check_load", - "-w", "$wload1$,$wload5$,$wload15$", - "-c", "$cload1$,$cload5$,$cload15$" - ], + command = PluginDir + "/check_load" - vars.wload1 = 5.0, - vars.wload5 = 4.0, - vars.wload15 = 3.0, + arguments = { + "-w" = "$load_wload1$,$load_wload5$,$load_wload15$" + "-c" = "$load_cload1$,$load_cload5$,$load_cload15$" + } - vars.cload1 = 10.0, - vars.cload5 = 6.0, - vars.cload15 = 4.0 + vars.load_wload1 = 5.0 + vars.load_wload5 = 4.0 + vars.load_wload15 = 3.0 + + vars.load_cload1 = 10.0 + vars.load_cload5 = 6.0 + vars.load_cload15 = 4.0 } object CheckCommand "snmp" { import "plugin-check-command", - command = [ - PluginDir + "/check_snmp", - "-H", "$address$", - "-o", "$oid$", - "-C", "$community$" - ], + command = PluginDir + "/check_snmp" - vars.community = "public" + arguments = { + "-H" = "$snmp_address$", + "-o" = "$snmp_oid$", + "-C" = "$snmp_community$" + } + + vars.snmp_address = "$address$" + vars.snmp_community = "public" } object CheckCommand "snmp-uptime" { import "snmp", - vars.oid = "1.3.6.1.2.1.1.3.0" + vars.snmp_oid = "1.3.6.1.2.1.1.3.0" } object CheckCommand "apt" { @@ -285,15 +307,12 @@ object CheckCommand "apt" { object CheckCommand "icinga" { import "icinga-check-command", - } object CheckCommand "cluster" { import "cluster-check-command", - } object CheckCommand "agent" { import "agent-check-command" } - diff --git a/lib/icinga/CMakeLists.txt b/lib/icinga/CMakeLists.txt index 590ae474a..f18e91257 100644 --- a/lib/icinga/CMakeLists.txt +++ b/lib/icinga/CMakeLists.txt @@ -45,15 +45,13 @@ add_library(icinga SHARED checkable-flapping.cpp checkcommand.cpp checkcommand.th checkresult.cpp checkresult.th cib.cpp command.cpp command.th comment.cpp comment.th compatutility.cpp dependency.cpp dependency.th dependency-apply.cpp domain.cpp domain.th downtime.cpp downtime.th eventcommand.cpp eventcommand.th - externalcommandprocessor.cpp host.cpp host.th hostgroup.cpp hostgroup.th - icingaapplication.cpp icingaapplication.th icingastatuswriter.cpp - icingastatuswriter.th legacytimeperiod.cpp - macroprocessor.cpp macroresolver.cpp notificationcommand.cpp notificationcommand.th - notification.cpp notification.th notification-apply.cpp perfdatavalue.cpp perfdatavalue.th - pluginutility.cpp scheduleddowntime.cpp scheduleddowntime.th scheduleddowntime-apply.cpp - service-apply.cpp checkable-check.cpp checkable-comment.cpp service.cpp service.th - servicegroup.cpp servicegroup.th checkable-notification.cpp timeperiod.cpp timeperiod.th user.cpp user.th - usergroup.cpp usergroup.th icinga-type.cpp + externalcommandprocessor.cpp host.cpp host.th hostgroup.cpp hostgroup.th icingaapplication.cpp + icingaapplication.th icingastatuswriter.cpp icingastatuswriter.th legacytimeperiod.cpp macroprocessor.cpp + notificationcommand.cpp notificationcommand.th notification.cpp notification.th notification-apply.cpp + perfdatavalue.cpp perfdatavalue.th pluginutility.cpp scheduleddowntime.cpp scheduleddowntime.th + scheduleddowntime-apply.cpp service-apply.cpp checkable-check.cpp checkable-comment.cpp service.cpp + service.th servicegroup.cpp servicegroup.th checkable-notification.cpp timeperiod.cpp timeperiod.th + user.cpp user.th usergroup.cpp usergroup.th icinga-type.cpp ) target_link_libraries(icinga ${Boost_LIBRARIES} base config) diff --git a/lib/icinga/command.ti b/lib/icinga/command.ti index ff8d6e6b3..895533d86 100644 --- a/lib/icinga/command.ti +++ b/lib/icinga/command.ti @@ -6,6 +6,7 @@ namespace icinga abstract class Command : DynamicObject { [config] Value command (CommandLine); + [config] Value arguments; [config] Value timeout { default {{{ return 300; }}} }; diff --git a/lib/icinga/icinga-type.conf b/lib/icinga/icinga-type.conf index e648dabd1..b856b7431 100644 --- a/lib/icinga/icinga-type.conf +++ b/lib/icinga/icinga-type.conf @@ -202,6 +202,15 @@ %attribute %array "command" { %attribute %string "*" }, + %attribute %dictionary "arguments" { + %attribute %string "*", + %attribute %dictionary "*" { + %attribute %string "value" + %attribute %string "description" + %attribute %number "optional" + %attribute %string "set_if" + } + }, %attribute %dictionary "env" { %attribute %string "*" }, diff --git a/lib/icinga/macroprocessor.cpp b/lib/icinga/macroprocessor.cpp index 834afc713..896b24713 100644 --- a/lib/icinga/macroprocessor.cpp +++ b/lib/icinga/macroprocessor.cpp @@ -33,7 +33,8 @@ using namespace icinga; Value MacroProcessor::ResolveMacros(const Value& str, const ResolverList& resolvers, - const CheckResult::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn) + const CheckResult::Ptr& cr, String *missingMacro, + const MacroProcessor::EscapeCallback& escapeFn) { Value result; @@ -41,7 +42,7 @@ Value MacroProcessor::ResolveMacros(const Value& str, const ResolverList& resolv return Empty; if (str.IsScalar()) { - result = InternalResolveMacros(str, resolvers, cr, escapeFn); + result = InternalResolveMacros(str, resolvers, cr, missingMacro, escapeFn); } else if (str.IsObjectType()) { Array::Ptr resultArr = make_shared(); Array::Ptr arr = str; @@ -50,7 +51,7 @@ Value MacroProcessor::ResolveMacros(const Value& str, const ResolverList& resolv BOOST_FOREACH(const Value& arg, arr) { /* Note: don't escape macros here. */ - resultArr->Add(InternalResolveMacros(arg, resolvers, cr, EscapeCallback())); + resultArr->Add(InternalResolveMacros(arg, resolvers, cr, missingMacro, EscapeCallback())); } result = resultArr; @@ -150,7 +151,8 @@ bool MacroProcessor::ResolveMacro(const String& macro, const ResolverList& resol } String MacroProcessor::InternalResolveMacros(const String& str, const ResolverList& resolvers, - const CheckResult::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn, int recursionLevel) + const CheckResult::Ptr& cr, String *missingMacro, + const MacroProcessor::EscapeCallback& escapeFn, int recursionLevel) { CONTEXT("Resolving macros for string '" + str + "'"); @@ -179,12 +181,17 @@ String MacroProcessor::InternalResolveMacros(const String& str, const ResolverLi found = true; } - if (!found) - Log(LogWarning, "icinga", "Macro '" + name + "' is not defined."); + if (!found) { + if (!missingMacro) + Log(LogWarning, "icinga", "Macro '" + name + "' is not defined."); + else + *missingMacro = name; + } /* recursively resolve macros in the macro if it was a user macro */ if (recursive_macro) - resolved_macro = InternalResolveMacros(resolved_macro, resolvers, cr, EscapeCallback(), recursionLevel + 1); + resolved_macro = InternalResolveMacros(resolved_macro, + resolvers, cr, missingMacro, EscapeCallback(), recursionLevel + 1); if (escapeFn) resolved_macro = escapeFn(resolved_macro); diff --git a/lib/icinga/macroprocessor.h b/lib/icinga/macroprocessor.h index a6707d3c7..8208a7998 100644 --- a/lib/icinga/macroprocessor.h +++ b/lib/icinga/macroprocessor.h @@ -43,7 +43,8 @@ public: typedef std::vector ResolverList; static Value ResolveMacros(const Value& str, const ResolverList& resolvers, - const CheckResult::Ptr& cr, const EscapeCallback& escapeFn = EscapeCallback()); + const CheckResult::Ptr& cr = CheckResult::Ptr(), String *missingMacro = NULL, + const EscapeCallback& escapeFn = EscapeCallback()); private: MacroProcessor(void); @@ -52,7 +53,8 @@ private: const CheckResult::Ptr& cr, String *result, bool *recursive_macro); static String InternalResolveMacros(const String& str, const ResolverList& resolvers, const CheckResult::Ptr& cr, - const EscapeCallback& escapeFn, int recursionLevel = 0); + String *missingMacro, const EscapeCallback& escapeFn, + int recursionLevel = 0); }; } diff --git a/lib/icinga/macroresolver.cpp b/lib/icinga/macroresolver.cpp deleted file mode 100644 index 830fad6b5..000000000 --- a/lib/icinga/macroresolver.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/****************************************************************************** - * Icinga 2 * - * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License * - * as published by the Free Software Foundation; either version 2 * - * of the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software Foundation * - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * - ******************************************************************************/ - -#include "icinga/macroresolver.h" - -using namespace icinga; diff --git a/lib/icinga/pluginutility.cpp b/lib/icinga/pluginutility.cpp index 265f866b5..4b93fb3c8 100644 --- a/lib/icinga/pluginutility.cpp +++ b/lib/icinga/pluginutility.cpp @@ -26,6 +26,7 @@ #include "base/logger_fwd.h" #include "base/scriptfunction.h" #include "base/utility.h" +#include "base/convert.h" #include "base/process.h" #include "base/objectlock.h" #include @@ -35,6 +36,102 @@ using namespace icinga; +void PluginUtility::ExecuteCommand(const Command::Ptr& commandObj, const Checkable::Ptr& checkable, + const MacroProcessor::ResolverList& macroResolvers, + const boost::function& callback) +{ + Value raw_command = commandObj->GetCommandLine(); + Dictionary::Ptr raw_arguments = commandObj->GetArguments(); + + Value command; + if (!raw_arguments || raw_command.IsObjectType()) + command = MacroProcessor::ResolveMacros(raw_command, macroResolvers, checkable->GetLastCheckResult(), NULL, Utility::EscapeShellArg); + else { + Array::Ptr arr = make_shared(); + arr->Add(raw_command); + command = arr; + } + + if (raw_arguments) { + ObjectLock olock(raw_arguments); + BOOST_FOREACH(const Dictionary::Pair& kv, raw_arguments) { + const String& argname = kv.first; + const Value& arginfo = kv.second; + + bool optional = false; + String argval; + + if (arginfo.IsObjectType()) { + Dictionary::Ptr argdict = arginfo; + argval = argdict->Get("value"); + optional = argdict->Get("optional"); + + String set_if = argdict->Get("set_if"); + + if (!set_if.IsEmpty()) { + String missingMacro; + String set_if_resolved = MacroProcessor::ResolveMacros(set_if, macroResolvers, + checkable->GetLastCheckResult(), &missingMacro); + + if (!missingMacro.IsEmpty() || !Convert::ToLong(set_if_resolved)) + continue; + } + } + else + argval = arginfo; + + String missingMacro; + String argresolved = MacroProcessor::ResolveMacros(argval, macroResolvers, + checkable->GetLastCheckResult(), &missingMacro); + + if (!missingMacro.IsEmpty()) { + if (!optional) { + String message = "Non-optional macro '" + missingMacro + "' used in argument '" + + argname + "' is missing while executing command '" + commandObj->GetName() + + "' for object '" + checkable->GetName() + "'"; + Log(LogWarning, "methods", message); + + if (callback) { + ProcessResult pr; + pr.ExecutionStart = Utility::GetTime(); + pr.ExecutionStart = pr.ExecutionStart; + pr.Output = message; + callback(Empty, pr); + } + + return; + } + + continue; + } + + Array::Ptr command_arr = command; + command_arr->Add(argname); + if (!argval.IsEmpty()) + command_arr->Add(argresolved); + } + } + + Dictionary::Ptr envMacros = make_shared(); + + Dictionary::Ptr env = commandObj->GetEnv(); + + if (env) { + ObjectLock olock(env); + BOOST_FOREACH(const Dictionary::Pair& kv, env) { + String name = kv.second; + + Value value = MacroProcessor::ResolveMacros(name, macroResolvers, checkable->GetLastCheckResult()); + + envMacros->Set(kv.first, value); + } + } + + Process::Ptr process = make_shared(Process::PrepareCommand(command), envMacros); + process->SetTimeout(commandObj->GetTimeout()); + process->Run(boost::bind(callback, command, _1)); +} + ServiceState PluginUtility::ExitStatusToState(int exitStatus) { switch (exitStatus) { diff --git a/lib/icinga/pluginutility.h b/lib/icinga/pluginutility.h index 7d89b4310..f93315167 100644 --- a/lib/icinga/pluginutility.h +++ b/lib/icinga/pluginutility.h @@ -23,6 +23,8 @@ #include "icinga/i2-icinga.h" #include "icinga/service.h" #include "icinga/checkcommand.h" +#include "icinga/macroprocessor.h" +#include "base/process.h" #include "base/dictionary.h" #include "base/dynamicobject.h" #include @@ -38,6 +40,10 @@ namespace icinga class I2_ICINGA_API PluginUtility { public: + static void ExecuteCommand(const Command::Ptr& commandObj, const Checkable::Ptr& checkable, + const MacroProcessor::ResolverList& macroResolvers, + const boost::function& callback = boost::function()); + static ServiceState ExitStatusToState(int exitStatus); static std::pair ParseCheckOutput(const String& output); diff --git a/lib/methods/pluginchecktask.cpp b/lib/methods/pluginchecktask.cpp index 144d91e66..d50a8e668 100644 --- a/lib/methods/pluginchecktask.cpp +++ b/lib/methods/pluginchecktask.cpp @@ -38,7 +38,6 @@ REGISTER_SCRIPTFUNCTION(PluginCheck, &PluginCheckTask::ScriptFunc); void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr) { CheckCommand::Ptr commandObj = checkable->GetCheckCommand(); - Value raw_command = commandObj->GetCommandLine(); Host::Ptr host; Service::Ptr service; @@ -51,38 +50,15 @@ void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes resolvers.push_back(std::make_pair("command", commandObj)); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, checkable->GetLastCheckResult(), Utility::EscapeShellArg); - - Dictionary::Ptr envMacros = make_shared(); - - Dictionary::Ptr env = commandObj->GetEnv(); - - if (env) { - ObjectLock olock(env); - BOOST_FOREACH(const Dictionary::Pair& kv, env) { - String name = kv.second; - - Value value = MacroProcessor::ResolveMacros(name, resolvers, checkable->GetLastCheckResult()); - - envMacros->Set(kv.first, value); - } - } - - cr->SetCommand(command); - - Process::Ptr process = make_shared(Process::PrepareCommand(command), envMacros); - - process->SetTimeout(commandObj->GetTimeout()); - - process->Run(boost::bind(&PluginCheckTask::ProcessFinishedHandler, checkable, cr, _1)); - + PluginUtility::ExecuteCommand(commandObj, checkable, resolvers, boost::bind(&PluginCheckTask::ProcessFinishedHandler, checkable, cr, _1, _2)); } -void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const ProcessResult& pr) +void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Value& commandLine, const ProcessResult& pr) { String output = pr.Output; output.Trim(); std::pair co = PluginUtility::ParseCheckOutput(output); + cr->SetCommand(commandLine); cr->SetOutput(co.first); cr->SetPerformanceData(co.second); cr->SetState(PluginUtility::ExitStatusToState(pr.ExitStatus)); diff --git a/lib/methods/pluginchecktask.h b/lib/methods/pluginchecktask.h index 77addcf29..0527983f3 100644 --- a/lib/methods/pluginchecktask.h +++ b/lib/methods/pluginchecktask.h @@ -40,7 +40,7 @@ public: private: PluginCheckTask(void); - static void ProcessFinishedHandler(const Checkable::Ptr& service, const CheckResult::Ptr& cr, const ProcessResult& pr); + static void ProcessFinishedHandler(const Checkable::Ptr& service, const CheckResult::Ptr& cr, const Value& commandLine, const ProcessResult& pr); }; diff --git a/lib/methods/plugineventtask.cpp b/lib/methods/plugineventtask.cpp index e91630ec5..0c079275b 100644 --- a/lib/methods/plugineventtask.cpp +++ b/lib/methods/plugineventtask.cpp @@ -20,6 +20,7 @@ #include "methods/plugineventtask.h" #include "icinga/eventcommand.h" #include "icinga/macroprocessor.h" +#include "icinga/pluginutility.h" #include "icinga/icingaapplication.h" #include "base/dynamictype.h" #include "base/logger_fwd.h" @@ -35,7 +36,6 @@ REGISTER_SCRIPTFUNCTION(PluginEvent, &PluginEventTask::ScriptFunc); void PluginEventTask::ScriptFunc(const Checkable::Ptr& checkable) { EventCommand::Ptr commandObj = checkable->GetEventCommand(); - Value raw_command = commandObj->GetCommandLine(); Host::Ptr host; Service::Ptr service; @@ -48,26 +48,5 @@ void PluginEventTask::ScriptFunc(const Checkable::Ptr& checkable) resolvers.push_back(std::make_pair("command", commandObj)); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, checkable->GetLastCheckResult(), Utility::EscapeShellArg); - - Dictionary::Ptr envMacros = make_shared(); - - Dictionary::Ptr env = commandObj->GetEnv(); - - if (env) { - ObjectLock olock(env); - BOOST_FOREACH(const Dictionary::Pair& kv, env) { - String name = kv.second; - - Value value = MacroProcessor::ResolveMacros(name, resolvers, checkable->GetLastCheckResult()); - - envMacros->Set(kv.first, value); - } - } - - Process::Ptr process = make_shared(Process::PrepareCommand(command), envMacros); - - process->SetTimeout(commandObj->GetTimeout()); - - process->Run(); + PluginUtility::ExecuteCommand(commandObj, checkable, resolvers); } diff --git a/lib/methods/pluginnotificationtask.cpp b/lib/methods/pluginnotificationtask.cpp index 1beb2c287..848847ad2 100644 --- a/lib/methods/pluginnotificationtask.cpp +++ b/lib/methods/pluginnotificationtask.cpp @@ -20,6 +20,7 @@ #include "methods/pluginnotificationtask.h" #include "icinga/notification.h" #include "icinga/notificationcommand.h" +#include "icinga/pluginutility.h" #include "icinga/service.h" #include "icinga/macroprocessor.h" #include "icinga/icingaapplication.h" @@ -42,8 +43,6 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, c Checkable::Ptr checkable = notification->GetCheckable(); - Value raw_command = commandObj->GetCommandLine(); - Dictionary::Ptr notificationExtra = make_shared(); notificationExtra->Set("type", Notification::NotificationTypeToString(type)); notificationExtra->Set("author", author); @@ -63,28 +62,7 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, c resolvers.push_back(std::make_pair("command", commandObj)); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); - Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, cr, Utility::EscapeShellArg); - - Dictionary::Ptr envMacros = make_shared(); - - Dictionary::Ptr env = commandObj->GetEnv(); - - if (env) { - ObjectLock olock(env); - BOOST_FOREACH(const Dictionary::Pair& kv, env) { - String name = kv.second; - - Value value = MacroProcessor::ResolveMacros(name, resolvers, checkable->GetLastCheckResult()); - - envMacros->Set(kv.first, value); - } - } - - Process::Ptr process = make_shared(Process::PrepareCommand(command), envMacros); - - process->SetTimeout(commandObj->GetTimeout()); - - process->Run(boost::bind(&PluginNotificationTask::ProcessFinishedHandler, checkable, command, _1)); + PluginUtility::ExecuteCommand(commandObj, checkable, resolvers, boost::bind(&PluginNotificationTask::ProcessFinishedHandler, checkable, _1, _2)); } void PluginNotificationTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const Value& command, const ProcessResult& pr)