mirror of https://github.com/Icinga/icinga2.git
parent
ba0498e2d7
commit
39c24e9ec9
|
@ -21,7 +21,7 @@ addons:
|
||||||
before_script:
|
before_script:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/tmp/icinga2
|
- cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/tmp/icinga2 -DICINGA2_PLUGINDIR=/tmp/icinga2/sbin
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- make
|
- make
|
||||||
|
|
|
@ -1637,7 +1637,61 @@ users\_win\_crit | **Optional**. The critical threshold.
|
||||||
|
|
||||||
## <a id="nscp-plugin-check-commands"></a> Plugin Check Commands for NSClient++
|
## <a id="nscp-plugin-check-commands"></a> Plugin Check Commands for NSClient++
|
||||||
|
|
||||||
Icinga 2 can use the `nscp client` command to run arbitrary NSClient++ checks.
|
There are two methods available for querying NSClient++:
|
||||||
|
|
||||||
|
* Query the [HTTP API](10-icinga-template-library.md#nscp-check-api) locally or remotely (requires a running NSClient++ service)
|
||||||
|
* Run a [local CLI check](10-icinga-template-library.md#nscp-check-local) (does not require NSClient++ as a service)
|
||||||
|
|
||||||
|
Both methods have their advantages and disadvantages. One thing to
|
||||||
|
note: If you rely on performance counter delta calculations such as
|
||||||
|
CPU utilization, please use the HTTP API instead of the CLI sample call.
|
||||||
|
|
||||||
|
### <a id="nscp-check-api"></a> nscp_api
|
||||||
|
|
||||||
|
`check_nscp_api` is part of the Icinga 2 plugins. This plugin is available for
|
||||||
|
both, Windows and Linux/Unix.
|
||||||
|
|
||||||
|
Verify that the ITL CheckCommand is included:
|
||||||
|
|
||||||
|
vim /etc/icinga2/icinga2.conf
|
||||||
|
|
||||||
|
include <plugins>
|
||||||
|
|
||||||
|
`check_nscp_api` runs queries against the NSClient++ API. Therefore NSClient++ needs to have
|
||||||
|
the `webserver` module enabled, configured and loaded.
|
||||||
|
|
||||||
|
You can install the webserver using the following CLI commands:
|
||||||
|
|
||||||
|
./nscp.exe web install
|
||||||
|
./nscp.exe web password — –set icinga
|
||||||
|
|
||||||
|
Now you can define specific [queries](https://docs.nsclient.org/reference/check/CheckHelpers.html#queries)
|
||||||
|
and integrate them into Icinga 2.
|
||||||
|
|
||||||
|
The check plugin `check_nscp_api` can be integrated with the `nscp_api` CheckCommand object:
|
||||||
|
|
||||||
|
Custom attributes:
|
||||||
|
|
||||||
|
Name | Description
|
||||||
|
:----------------------|:----------------------
|
||||||
|
nscp\_api\_host | **Required**. NSCP API host address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise.
|
||||||
|
nscp\_api\_port | **Optional**. NSCP API port. Defaults to `8443`.
|
||||||
|
nscp\_api\_passwd | **Required**. NSCP API password. Please check the NSCP documentation for setup details.
|
||||||
|
nscp\_api\_query | **Required**. NSCP API query endpoint. Refer to the NSCP documentation for possible values.
|
||||||
|
nscp\_api\_arguments | **Optional**. NSCP API arguments dictionary either as single strings or key-value pairs using `=`. Refer to the NSCP documentation.
|
||||||
|
|
||||||
|
`nscp_api_arguments` can be used to pass required thresholds to the executed check. The example below
|
||||||
|
checks the CPU utilization and specifies warning and critical thresholds.
|
||||||
|
|
||||||
|
```
|
||||||
|
check_nscp_api --host 10.0.10.148 --password icinga --query check_cpu --arguments show-all warning='load>40' critical='load>30'
|
||||||
|
check_cpu CRITICAL: critical(5m: 48%, 1m: 36%), 5s: 0% | 'total 5m'=48%;40;30 'total 1m'=36%;40;30 'total 5s'=0%;40;30
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <a id="nscp-check-local"></a> nscp-local
|
||||||
|
|
||||||
|
Icinga 2 can use the `nscp client` command to run arbitrary NSClient++ checks locally on the client.
|
||||||
|
|
||||||
You can enable these check commands by adding the following the include directive in your
|
You can enable these check commands by adding the following the include directive in your
|
||||||
[icinga2.conf](4-configuring-icinga-2.md#icinga2-conf) configuration file:
|
[icinga2.conf](4-configuring-icinga-2.md#icinga2-conf) configuration file:
|
||||||
|
@ -1655,9 +1709,7 @@ not be necessary to manually set this constant.
|
||||||
|
|
||||||
Note that it is not necessary to run NSClient++ as a Windows service for these commands to work.
|
Note that it is not necessary to run NSClient++ as a Windows service for these commands to work.
|
||||||
|
|
||||||
### <a id="nscp-check-local"></a> nscp-local
|
The check command object for NSClient++ is available as `nscp-local`.
|
||||||
|
|
||||||
Check command object for NSClient++
|
|
||||||
|
|
||||||
Custom attributes passed as [command parameters](3-monitoring-basics.md#command-passing-parameters):
|
Custom attributes passed as [command parameters](3-monitoring-basics.md#command-passing-parameters):
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ Instead, choose a plugin and configure its parameters and thresholds. The follow
|
||||||
### <a id="service-monitoring-windows"></a> Windows Monitoring
|
### <a id="service-monitoring-windows"></a> Windows Monitoring
|
||||||
|
|
||||||
* [check_wmi_plus](http://www.edcint.co.nz/checkwmiplus/)
|
* [check_wmi_plus](http://www.edcint.co.nz/checkwmiplus/)
|
||||||
* [NSClient++](https://www.nsclient.org) (in combination with the Icinga 2 client as [nscp-local](10-icinga-template-library.md#nscp-plugin-check-commands) check commands)
|
* [NSClient++](https://www.nsclient.org) (in combination with the Icinga 2 client and either [check_nscp_api](10-icinga-template-library.md#nscp-check-api) or [nscp-local](10-icinga-template-library.md#nscp-plugin-check-commands) check commands)
|
||||||
* [Icinga 2 Windows Plugins](10-icinga-template-library.md#windows-plugins) (disk, load, memory, network, performance counters, ping, procs, service, swap, updates, uptime, users
|
* [Icinga 2 Windows Plugins](10-icinga-template-library.md#windows-plugins) (disk, load, memory, network, performance counters, ping, procs, service, swap, updates, uptime, users
|
||||||
* vbs and Powershell scripts
|
* vbs and Powershell scripts
|
||||||
|
|
||||||
|
|
|
@ -198,9 +198,9 @@ Here is an example of a master setup for the `icinga2-master1.localdomain` node
|
||||||
|
|
||||||
[root@icinga2-master1.localdomain /]# icinga2 node wizard
|
[root@icinga2-master1.localdomain /]# icinga2 node wizard
|
||||||
Welcome to the Icinga 2 Setup Wizard!
|
Welcome to the Icinga 2 Setup Wizard!
|
||||||
|
|
||||||
We'll guide you through all required configuration details.
|
We'll guide you through all required configuration details.
|
||||||
|
|
||||||
Please specify if this is a satellite setup ('n' installs a master setup) [Y/n]: n
|
Please specify if this is a satellite setup ('n' installs a master setup) [Y/n]: n
|
||||||
Starting the Master setup routine...
|
Starting the Master setup routine...
|
||||||
Please specify the common name (CN) [icinga2-master1.localdomain]: icinga2-master1.localdomain
|
Please specify the common name (CN) [icinga2-master1.localdomain]: icinga2-master1.localdomain
|
||||||
|
@ -230,7 +230,7 @@ Here is an example of a master setup for the `icinga2-master1.localdomain` node
|
||||||
information/cli: Updating constants file '/etc/icinga2/constants.conf'.
|
information/cli: Updating constants file '/etc/icinga2/constants.conf'.
|
||||||
information/cli: Updating constants file '/etc/icinga2/constants.conf'.
|
information/cli: Updating constants file '/etc/icinga2/constants.conf'.
|
||||||
Done.
|
Done.
|
||||||
|
|
||||||
Now restart your Icinga 2 daemon to finish the installation!
|
Now restart your Icinga 2 daemon to finish the installation!
|
||||||
|
|
||||||
[root@icinga2-master1.localdomain /]# systemctl restart icinga2
|
[root@icinga2-master1.localdomain /]# systemctl restart icinga2
|
||||||
|
@ -350,9 +350,9 @@ is configured to accept configuration and commands from the master:
|
||||||
|
|
||||||
[root@icinga2-client1.localdomain /]# icinga2 node wizard
|
[root@icinga2-client1.localdomain /]# icinga2 node wizard
|
||||||
Welcome to the Icinga 2 Setup Wizard!
|
Welcome to the Icinga 2 Setup Wizard!
|
||||||
|
|
||||||
We'll guide you through all required configuration details.
|
We'll guide you through all required configuration details.
|
||||||
|
|
||||||
Please specify if this is a satellite setup ('n' installs a master setup) [Y/n]:
|
Please specify if this is a satellite setup ('n' installs a master setup) [Y/n]:
|
||||||
Starting the Node setup routine...
|
Starting the Node setup routine...
|
||||||
Please specify the common name (CN) [icinga2-client1.localdomain]: icinga2-client1.localdomain
|
Please specify the common name (CN) [icinga2-client1.localdomain]: icinga2-client1.localdomain
|
||||||
|
@ -369,22 +369,22 @@ is configured to accept configuration and commands from the master:
|
||||||
information/base: Writing private key to '/etc/icinga2/pki/icinga2-client1.localdomain.key'.
|
information/base: Writing private key to '/etc/icinga2/pki/icinga2-client1.localdomain.key'.
|
||||||
information/base: Writing X509 certificate to '/etc/icinga2/pki/icinga2-client1.localdomain.crt'.
|
information/base: Writing X509 certificate to '/etc/icinga2/pki/icinga2-client1.localdomain.crt'.
|
||||||
information/cli: Fetching public certificate from master (192.168.56.101, 5665):
|
information/cli: Fetching public certificate from master (192.168.56.101, 5665):
|
||||||
|
|
||||||
Certificate information:
|
Certificate information:
|
||||||
|
|
||||||
Subject: CN = icinga2-master1.localdomain
|
Subject: CN = icinga2-master1.localdomain
|
||||||
Issuer: CN = Icinga CA
|
Issuer: CN = Icinga CA
|
||||||
Valid From: Feb 23 14:45:32 2016 GMT
|
Valid From: Feb 23 14:45:32 2016 GMT
|
||||||
Valid Until: Feb 19 14:45:32 2031 GMT
|
Valid Until: Feb 19 14:45:32 2031 GMT
|
||||||
Fingerprint: AC 99 8B 2B 3D B0 01 00 E5 21 FA 05 2E EC D5 A9 EF 9E AA E3
|
Fingerprint: AC 99 8B 2B 3D B0 01 00 E5 21 FA 05 2E EC D5 A9 EF 9E AA E3
|
||||||
|
|
||||||
Is this information correct? [y/N]: y
|
Is this information correct? [y/N]: y
|
||||||
information/cli: Received trusted master certificate.
|
information/cli: Received trusted master certificate.
|
||||||
|
|
||||||
Please specify the request ticket generated on your Icinga 2 master.
|
Please specify the request ticket generated on your Icinga 2 master.
|
||||||
(Hint: # icinga2 pki ticket --cn 'icinga2-client1.localdomain'): 4f75d2ecd253575fe9180938ebff7cbca262f96e
|
(Hint: # icinga2 pki ticket --cn 'icinga2-client1.localdomain'): 4f75d2ecd253575fe9180938ebff7cbca262f96e
|
||||||
information/cli: Requesting certificate with ticket '4f75d2ecd253575fe9180938ebff7cbca262f96e'.
|
information/cli: Requesting certificate with ticket '4f75d2ecd253575fe9180938ebff7cbca262f96e'.
|
||||||
|
|
||||||
information/cli: Created backup file '/etc/icinga2/pki/icinga2-client1.localdomain.crt.orig'.
|
information/cli: Created backup file '/etc/icinga2/pki/icinga2-client1.localdomain.crt.orig'.
|
||||||
information/cli: Writing signed certificate to file '/etc/icinga2/pki/icinga2-client1.localdomain.crt'.
|
information/cli: Writing signed certificate to file '/etc/icinga2/pki/icinga2-client1.localdomain.crt'.
|
||||||
information/cli: Writing CA certificate to file '/etc/icinga2/pki/ca.crt'.
|
information/cli: Writing CA certificate to file '/etc/icinga2/pki/ca.crt'.
|
||||||
|
@ -2133,6 +2133,85 @@ for the requirements.
|
||||||
|
|
||||||
### <a id="distributed-monitoring-windows-nscp"></a> Windows Client and NSClient++
|
### <a id="distributed-monitoring-windows-nscp"></a> Windows Client and NSClient++
|
||||||
|
|
||||||
|
There are two methods available for querying NSClient++:
|
||||||
|
|
||||||
|
* Query the [HTTP API](6-distributed-monitoring.md#distributed-monitoring-windows-nscp-check-api) locally or remotely (requires a running NSClient++ service)
|
||||||
|
* Run a [local CLI check](6-distributed-monitoring.md#distributed-monitoring-windows-nscp-check-local) (does not require NSClient++ as a service)
|
||||||
|
|
||||||
|
Both methods have their advantages and disadvantages. One thing to
|
||||||
|
note: If you rely on performance counter delta calculations such as
|
||||||
|
CPU utilization, please use the HTTP API instead of the CLI sample call.
|
||||||
|
|
||||||
|
#### <a id="distributed-monitoring-windows-nscp-check-api"></a> NSCLient++ with check_nscp_api
|
||||||
|
|
||||||
|
The [Windows setup](6-distributed-monitoring.md#distributed-monitoring-setup-client-windows) already allows
|
||||||
|
you to install the NSClient++ package. In addition to the Windows plugins you can
|
||||||
|
use the [nscp_api command](10-icinga-template-library.md#nscp-check-api) provided by the Icinga Template Library (ITL).
|
||||||
|
|
||||||
|
The initial setup for the NSClient++ API and the required arguments
|
||||||
|
is the described in the ITL chapter for the [nscp_api](10-icinga-template-library.md#nscp-check-api) CheckCommand.
|
||||||
|
|
||||||
|
Based on the [master with clients](6-distributed-monitoring.md#distributed-monitoring-master-clients)
|
||||||
|
scenario we'll now add a local nscp check which queries the NSClient++ API to check the free disk space.
|
||||||
|
|
||||||
|
Define a host object called `icinga2-client2.localdomain` on the master. Add the `nscp_api_password`
|
||||||
|
custom attribute and specify the drives to check.
|
||||||
|
|
||||||
|
[root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/master
|
||||||
|
[root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim hosts.conf
|
||||||
|
|
||||||
|
object Host "icinga2-client1.localdomain" {
|
||||||
|
check_command = "hostalive"
|
||||||
|
address = "192.168.56.111"
|
||||||
|
vars.client_endpoint = name //follows the convention that host name == endpoint name
|
||||||
|
vars.os_type = "Windows"
|
||||||
|
vars.nscp_api_password = "icinga"
|
||||||
|
vars.drives = [ "C:", "D:" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
The service checks are generated using an [apply for](3-monitoring-basics.md#using-apply-for)
|
||||||
|
rule based on `host.vars.drives`:
|
||||||
|
|
||||||
|
[root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim services.conf
|
||||||
|
|
||||||
|
apply Service for "nscp-api-" (drive in host.vars.drives) {
|
||||||
|
import "generic-service"
|
||||||
|
|
||||||
|
check_command = "nscp_api"
|
||||||
|
command_endpoint = host.vars.client_endpoint
|
||||||
|
|
||||||
|
//display_name = "nscp-drive-" + drive
|
||||||
|
|
||||||
|
vars.nscp_api_host = "localhost"
|
||||||
|
vars.nscp_api_query = "check_drivesize"
|
||||||
|
vars.nscp_api_password = host.vars.nscp_api_password
|
||||||
|
vars.nscp_api_arguments = [ "drive=" + drive ]
|
||||||
|
|
||||||
|
ignore where host.vars.os_type != "Windows"
|
||||||
|
}
|
||||||
|
|
||||||
|
Validate the configuration and restart Icinga 2.
|
||||||
|
|
||||||
|
[root@icinga2-master1.localdomain /]# icinga2 daemon -C
|
||||||
|
[root@icinga2-master1.localdomain /]# systemctl restart icinga2
|
||||||
|
|
||||||
|
Two new services ("nscp-drive-D:" and "nscp-drive-C:") will be visible in Icinga Web 2.
|
||||||
|
|
||||||
|
![Icinga 2 Distributed Monitoring Windows Client with NSClient++ nscp-api](images/distributed-monitoring/icinga2_distributed_windows_nscp_api_drivesize_icingaweb2.png)
|
||||||
|
|
||||||
|
Note: You can also omit the `command_endpoint` configuration to execute
|
||||||
|
the command on the master. This also requires a different value for `nscp_api_host`
|
||||||
|
which defaults to `host.address`.
|
||||||
|
|
||||||
|
//command_endpoint = host.vars.client_endpoint
|
||||||
|
|
||||||
|
//vars.nscp_api_host = "localhost"
|
||||||
|
|
||||||
|
You can verify the check execution by looking at the `Check Source` attribute
|
||||||
|
in Icinga Web 2 or the REST API.
|
||||||
|
|
||||||
|
#### <a id="distributed-monitoring-windows-nscp-check-local"></a> NSCLient++ with nscp-local
|
||||||
|
|
||||||
The [Windows setup](6-distributed-monitoring.md#distributed-monitoring-setup-client-windows) already allows
|
The [Windows setup](6-distributed-monitoring.md#distributed-monitoring-setup-client-windows) already allows
|
||||||
you to install the NSClient++ package. In addition to the Windows plugins you can
|
you to install the NSClient++ package. In addition to the Windows plugins you can
|
||||||
use the [nscp-local commands](10-icinga-template-library.md#nscp-plugin-check-commands)
|
use the [nscp-local commands](10-icinga-template-library.md#nscp-plugin-check-commands)
|
||||||
|
@ -2190,8 +2269,7 @@ Validate the configuration and restart Icinga 2.
|
||||||
|
|
||||||
Open Icinga Web 2 and check your newly added Windows NSClient++ check :)
|
Open Icinga Web 2 and check your newly added Windows NSClient++ check :)
|
||||||
|
|
||||||
![Icinga 2 Distributed Monitoring Windows Client with NSClient++](images/distributed-monitoring/icinga2_distributed_windows_nscp_counter_icingaweb2.png)
|
![Icinga 2 Distributed Monitoring Windows Client with NSClient++ nscp-local](images/distributed-monitoring/icinga2_distributed_windows_nscp_counter_icingaweb2.png)
|
||||||
|
|
||||||
|
|
||||||
## <a id="distributed-monitoring-advanced-hints"></a> Advanced Hints
|
## <a id="distributed-monitoring-advanced-hints"></a> Advanced Hints
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
|
@ -25,6 +25,7 @@
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%define _libexecdir %{_prefix}/lib/
|
%define _libexecdir %{_prefix}/lib/
|
||||||
|
%define plugindir %{_libdir}/nagios/plugins
|
||||||
|
|
||||||
%if "%{_vendor}" == "redhat"
|
%if "%{_vendor}" == "redhat"
|
||||||
%define apachename httpd
|
%define apachename httpd
|
||||||
|
@ -43,6 +44,7 @@
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%if "%{_vendor}" == "suse"
|
%if "%{_vendor}" == "suse"
|
||||||
|
%define plugindir %{_prefix}/lib/nagios/plugins
|
||||||
%define apachename apache2
|
%define apachename apache2
|
||||||
%define apacheconfdir %{_sysconfdir}/apache2/conf.d
|
%define apacheconfdir %{_sysconfdir}/apache2/conf.d
|
||||||
%define apacheuser wwwrun
|
%define apacheuser wwwrun
|
||||||
|
@ -330,7 +332,7 @@ CMAKE_OPTS="$CMAKE_OPTS \
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%if "%{_vendor}" != "suse"
|
%if "%{_vendor}" != "suse"
|
||||||
CMAKE_OPTS="$CMAKE_OPTS -DICINGA2_PLUGINDIR=%{_libdir}/nagios/plugins"
|
CMAKE_OPTS="$CMAKE_OPTS -DICINGA2_PLUGINDIR=%{plugindir}"
|
||||||
%else
|
%else
|
||||||
%if 0%{?suse_version} < 1310
|
%if 0%{?suse_version} < 1310
|
||||||
CMAKE_OPTS="$CMAKE_OPTS -DBOOST_LIBRARYDIR=%{_libdir}/boost153 \
|
CMAKE_OPTS="$CMAKE_OPTS -DBOOST_LIBRARYDIR=%{_libdir}/boost153 \
|
||||||
|
@ -340,7 +342,7 @@ CMAKE_OPTS="$CMAKE_OPTS -DBOOST_LIBRARYDIR=%{_libdir}/boost153 \
|
||||||
-DBUILD_TESTING=FALSE \
|
-DBUILD_TESTING=FALSE \
|
||||||
-DBoost_NO_BOOST_CMAKE=TRUE"
|
-DBoost_NO_BOOST_CMAKE=TRUE"
|
||||||
%endif
|
%endif
|
||||||
CMAKE_OPTS="$CMAKE_OPTS -DICINGA2_PLUGINDIR=%{_prefix}/lib/nagios/plugins"
|
CMAKE_OPTS="$CMAKE_OPTS -DICINGA2_PLUGINDIR=%{plugindir}"
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%if 0%{?use_systemd}
|
%if 0%{?use_systemd}
|
||||||
|
@ -674,6 +676,7 @@ fi
|
||||||
%{_sbindir}/%{name}
|
%{_sbindir}/%{name}
|
||||||
%dir %{_libdir}/%{name}/sbin
|
%dir %{_libdir}/%{name}/sbin
|
||||||
%{_libdir}/%{name}/sbin/%{name}
|
%{_libdir}/%{name}/sbin/%{name}
|
||||||
|
%{plugindir}/check_nscp_api
|
||||||
%{_datadir}/%{name}
|
%{_datadir}/%{name}
|
||||||
%exclude %{_datadir}/%{name}/include
|
%exclude %{_datadir}/%{name}/include
|
||||||
%{_mandir}/man8/%{name}.8.gz
|
%{_mandir}/man8/%{name}.8.gz
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
object CheckCommand "disk-windows" {
|
object CheckCommand "disk-windows" {
|
||||||
command = [ PluginDir + "/check_disk.exe" ]
|
command = [ PluginDir + "/check_disk.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
value = "$disk_win_warn$"
|
value = "$disk_win_warn$"
|
||||||
|
@ -43,14 +43,14 @@ object CheckCommand "disk-windows" {
|
||||||
description = "Exclude these drives from check"
|
description = "Exclude these drives from check"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.disk_win_unit = "mb"
|
vars.disk_win_unit = "mb"
|
||||||
//The default
|
//The default
|
||||||
}
|
}
|
||||||
|
|
||||||
object CheckCommand "load-windows" {
|
object CheckCommand "load-windows" {
|
||||||
command = [ PluginDir + "/check_load.exe" ]
|
command = [ PluginDir + "/check_load.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
value = "$load_win_warn$"
|
value = "$load_win_warn$"
|
||||||
|
@ -65,7 +65,7 @@ object CheckCommand "load-windows" {
|
||||||
|
|
||||||
object CheckCommand "memory-windows" {
|
object CheckCommand "memory-windows" {
|
||||||
command = [ PluginDir + "/check_memory.exe" ]
|
command = [ PluginDir + "/check_memory.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
value = "$memory_win_warn$"
|
value = "$memory_win_warn$"
|
||||||
|
@ -86,7 +86,7 @@ object CheckCommand "memory-windows" {
|
||||||
|
|
||||||
object CheckCommand "network-windows" {
|
object CheckCommand "network-windows" {
|
||||||
command = [ PluginDir + "/check_network.exe" ]
|
command = [ PluginDir + "/check_network.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
value = "$network_win_warn$"
|
value = "$network_win_warn$"
|
||||||
|
@ -106,7 +106,7 @@ object CheckCommand "network-windows" {
|
||||||
|
|
||||||
object CheckCommand "perfmon-windows" {
|
object CheckCommand "perfmon-windows" {
|
||||||
command = [ PluginDir + "/check_perfmon.exe" ]
|
command = [ PluginDir + "/check_perfmon.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
value = "$perfmon_win_warn$"
|
value = "$perfmon_win_warn$"
|
||||||
|
@ -135,7 +135,7 @@ object CheckCommand "perfmon-windows" {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.performance_win_wait = 1000
|
vars.performance_win_wait = 1000
|
||||||
vars.perfmon_win_type = "double"
|
vars.perfmon_win_type = "double"
|
||||||
//The default values
|
//The default values
|
||||||
|
@ -168,7 +168,7 @@ template CheckCommand "ping-common-windows" {
|
||||||
description = "Timeout in ms"
|
description = "Timeout in ms"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.ping_win_packets = "5"
|
vars.ping_win_packets = "5"
|
||||||
vars.ping_win_timeout = "1000"
|
vars.ping_win_timeout = "1000"
|
||||||
//The default values
|
//The default values
|
||||||
|
@ -199,7 +199,7 @@ object CheckCommand "ping6-windows" {
|
||||||
|
|
||||||
object CheckCommand "procs-windows" {
|
object CheckCommand "procs-windows" {
|
||||||
command = [ PluginDir + "/check_procs.exe" ]
|
command = [ PluginDir + "/check_procs.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
value = "$procs_win_warn$"
|
value = "$procs_win_warn$"
|
||||||
|
@ -218,7 +218,7 @@ object CheckCommand "procs-windows" {
|
||||||
|
|
||||||
object CheckCommand "service-windows" {
|
object CheckCommand "service-windows" {
|
||||||
command = [ PluginDir + "/check_service.exe" ]
|
command = [ PluginDir + "/check_service.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
set_if = "$service_win_warn$"
|
set_if = "$service_win_warn$"
|
||||||
|
@ -234,7 +234,7 @@ object CheckCommand "service-windows" {
|
||||||
|
|
||||||
object CheckCommand "swap-windows" {
|
object CheckCommand "swap-windows" {
|
||||||
command = [ PluginDir + "/check_swap.exe" ]
|
command = [ PluginDir + "/check_swap.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
value = "$swap_win_warn$"
|
value = "$swap_win_warn$"
|
||||||
|
@ -249,14 +249,14 @@ object CheckCommand "swap-windows" {
|
||||||
description = "Unit to display swap in"
|
description = "Unit to display swap in"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.swap_win_unit = "mb"
|
vars.swap_win_unit = "mb"
|
||||||
//The default
|
//The default
|
||||||
}
|
}
|
||||||
|
|
||||||
object CheckCommand "update-windows" {
|
object CheckCommand "update-windows" {
|
||||||
command = [ PluginDir + "/check_update.exe" ]
|
command = [ PluginDir + "/check_update.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
set_if = "$update_win_warn$"
|
set_if = "$update_win_warn$"
|
||||||
|
@ -277,7 +277,7 @@ object CheckCommand "update-windows" {
|
||||||
|
|
||||||
object CheckCommand "uptime-windows" {
|
object CheckCommand "uptime-windows" {
|
||||||
command = [ PluginDir + "/check_uptime.exe" ]
|
command = [ PluginDir + "/check_uptime.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
value = "$uptime_win_warn$"
|
value = "$uptime_win_warn$"
|
||||||
|
@ -292,14 +292,14 @@ object CheckCommand "uptime-windows" {
|
||||||
description = "Time unit to use"
|
description = "Time unit to use"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vars.uptime_win_unit = "s"
|
vars.uptime_win_unit = "s"
|
||||||
//The default
|
//The default
|
||||||
}
|
}
|
||||||
|
|
||||||
object CheckCommand "users-windows" {
|
object CheckCommand "users-windows" {
|
||||||
command = [ PluginDir + "/check_users.exe" ]
|
command = [ PluginDir + "/check_users.exe" ]
|
||||||
|
|
||||||
arguments = {
|
arguments = {
|
||||||
"-w" = {
|
"-w" = {
|
||||||
value = "$users_win_warn$"
|
value = "$users_win_warn$"
|
||||||
|
|
|
@ -3025,3 +3025,36 @@ object CheckCommand "radius" {
|
||||||
|
|
||||||
vars.radius_address = "$check_address$"
|
vars.radius_address = "$check_address$"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object CheckCommand "nscp_api" {
|
||||||
|
import "ipv4-or-ipv6"
|
||||||
|
|
||||||
|
command = [ PluginDir + "/check_nscp_api" ]
|
||||||
|
|
||||||
|
arguments = {
|
||||||
|
"-H" = {
|
||||||
|
value = "$nscp_api_host$"
|
||||||
|
description = "NSCP API host address"
|
||||||
|
required = true
|
||||||
|
}
|
||||||
|
"-P" = {
|
||||||
|
value = "$nscp_api_port$"
|
||||||
|
description = "NSCP API host port. Defaults to 8443."
|
||||||
|
}
|
||||||
|
"--password" = {
|
||||||
|
value = "$nscp_api_password$"
|
||||||
|
description = "NSCP API password"
|
||||||
|
}
|
||||||
|
"-q" = {
|
||||||
|
value = "$nscp_api_query$"
|
||||||
|
description = "NSCPI API Query endpoint to use"
|
||||||
|
}
|
||||||
|
"-a" = {
|
||||||
|
value = "$nscp_api_arguments$"
|
||||||
|
description = "NSCP API Query arguments"
|
||||||
|
repeat_key = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vars.nscp_api_host = "$check_address$"
|
||||||
|
}
|
||||||
|
|
|
@ -139,8 +139,8 @@ bool HttpResponse::Parse(StreamReadContext& src, bool may_wait)
|
||||||
boost::algorithm::split(tokens, line, boost::is_any_of(" "));
|
boost::algorithm::split(tokens, line, boost::is_any_of(" "));
|
||||||
Log(LogDebug, "HttpRequest")
|
Log(LogDebug, "HttpRequest")
|
||||||
<< "line: " << line << ", tokens: " << tokens.size();
|
<< "line: " << line << ", tokens: " << tokens.size();
|
||||||
if (tokens.size() < 3)
|
if (tokens.size() < 2)
|
||||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP request"));
|
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid HTTP response (Status line)"));
|
||||||
|
|
||||||
if (tokens[0] == "HTTP/1.0")
|
if (tokens[0] == "HTTP/1.0")
|
||||||
ProtocolVersion = HttpVersion10;
|
ProtocolVersion = HttpVersion10;
|
||||||
|
@ -150,7 +150,9 @@ bool HttpResponse::Parse(StreamReadContext& src, bool may_wait)
|
||||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported HTTP version"));
|
BOOST_THROW_EXCEPTION(std::invalid_argument("Unsupported HTTP version"));
|
||||||
|
|
||||||
StatusCode = Convert::ToLong(tokens[1]);
|
StatusCode = Convert::ToLong(tokens[1]);
|
||||||
StatusMessage = tokens[2]; // TODO: Join tokens[2..end]
|
|
||||||
|
if (tokens.size() >= 3)
|
||||||
|
StatusMessage = tokens[2]; // TODO: Join tokens[2..end]
|
||||||
|
|
||||||
m_State = HttpResponseHeaders;
|
m_State = HttpResponseHeaders;
|
||||||
} else if (m_State == HttpResponseHeaders) {
|
} else if (m_State == HttpResponseHeaders) {
|
||||||
|
|
|
@ -36,7 +36,9 @@ Url::Url(const String& base_url)
|
||||||
if (url.GetLength() == 0)
|
if (url.GetLength() == 0)
|
||||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Empty URL."));
|
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid URL Empty URL."));
|
||||||
|
|
||||||
size_t pHelper = url.Find(":");
|
size_t pHelper = String::NPos;
|
||||||
|
if (url[0] != '/')
|
||||||
|
pHelper = url.Find(":");
|
||||||
|
|
||||||
if (pHelper != String::NPos) {
|
if (pHelper != String::NPos) {
|
||||||
if (!ParseScheme(url.SubStr(0, pHelper)))
|
if (!ParseScheme(url.SubStr(0, pHelper)))
|
||||||
|
|
|
@ -15,28 +15,45 @@
|
||||||
# along with this program; if not, write to the Free Software Foundation
|
# along with this program; if not, write to the Free Software Foundation
|
||||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
add_executable ( check_nscp_api check_nscp_api.cpp )
|
||||||
|
target_link_libraries ( check_nscp_api ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_SYSTEM_LIBRARY} base remote )
|
||||||
|
set_target_properties (
|
||||||
|
check_nscp_api PROPERTIES
|
||||||
|
INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
|
||||||
|
DEFINE_SYMBOL I2_PLUGINS_BUILD
|
||||||
|
FOLDER Plugins )
|
||||||
|
|
||||||
|
# Prefer the PluginDir constant which is set to /sbin on Windows
|
||||||
|
|
||||||
|
if ( WIN32 )
|
||||||
|
install ( TARGETS check_nscp_api RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR} )
|
||||||
|
else()
|
||||||
|
install ( TARGETS check_nscp_api RUNTIME DESTINATION ${ICINGA2_PLUGINDIR} )
|
||||||
|
endif()
|
||||||
|
|
||||||
if ( WIN32 )
|
if ( WIN32 )
|
||||||
|
|
||||||
add_definitions ( -DUNICODE -D_UNICODE )
|
add_definitions ( -DUNICODE -D_UNICODE )
|
||||||
|
|
||||||
add_library ( thresholds thresholds )
|
add_library ( thresholds thresholds )
|
||||||
set_target_properties (
|
set_target_properties (
|
||||||
thresholds PROPERTIES
|
thresholds PROPERTIES
|
||||||
INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
|
INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
|
||||||
FOLDER Plugins
|
FOLDER Plugins
|
||||||
)
|
)
|
||||||
|
|
||||||
list ( APPEND check_SOURCES
|
list ( APPEND check_SOURCES
|
||||||
check_disk.cpp check_load.cpp check_memory.cpp check_network.cpp check_perfmon.cpp check_ping.cpp
|
check_disk.cpp check_load.cpp check_memory.cpp check_network.cpp check_perfmon.cpp
|
||||||
check_procs.cpp check_service.cpp check_swap.cpp check_update.cpp check_uptime.cpp check_users.cpp )
|
check_ping.cpp check_procs.cpp check_service.cpp check_swap.cpp check_update.cpp check_uptime.cpp
|
||||||
|
check_users.cpp )
|
||||||
foreach ( source ${check_SOURCES} )
|
|
||||||
|
foreach ( source ${check_SOURCES} )
|
||||||
string ( REGEX REPLACE ".cpp\$" "" check_OUT "${source}" )
|
string ( REGEX REPLACE ".cpp\$" "" check_OUT "${source}" )
|
||||||
string ( REGEX REPLACE ".cpp\$" ".h" check_HEADER "${source}" )
|
string ( REGEX REPLACE ".cpp\$" ".h" check_HEADER "${source}" )
|
||||||
|
|
||||||
add_executable ( ${check_OUT} ${source} ${check_HEADER} )
|
add_executable ( ${check_OUT} ${source} ${check_HEADER} )
|
||||||
target_link_libraries ( ${check_OUT} thresholds Shlwapi.lib ${Boost_PROGRAM_OPTIONS_LIBRARY} )
|
target_link_libraries ( ${check_OUT} thresholds Shlwapi.lib ${Boost_PROGRAM_OPTIONS_LIBRARY} )
|
||||||
|
|
||||||
set_target_properties (
|
set_target_properties (
|
||||||
${check_OUT} PROPERTIES
|
${check_OUT} PROPERTIES
|
||||||
INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
|
INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
|
||||||
|
@ -53,8 +70,8 @@ if ( WIN32 )
|
||||||
target_link_libraries ( check_users wtsapi32.lib )
|
target_link_libraries ( check_users wtsapi32.lib )
|
||||||
|
|
||||||
install (
|
install (
|
||||||
TARGETS check_disk check_load check_memory check_network check_perfmon check_procs
|
TARGETS check_disk check_load check_memory check_network check_perfmon check_procs
|
||||||
check_ping check_service check_swap check_update check_uptime check_users
|
check_ping check_service check_swap check_update check_uptime check_users
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR} )
|
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR} )
|
||||||
|
|
||||||
endif ( )
|
endif ( )
|
||||||
|
|
|
@ -0,0 +1,310 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Icinga 2 *
|
||||||
|
* Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#define VERSION "1.0.0"
|
||||||
|
|
||||||
|
#include "remote/httpclientconnection.hpp"
|
||||||
|
#include "remote/httprequest.hpp"
|
||||||
|
#include "remote/url-characters.hpp"
|
||||||
|
#include "base/application.hpp"
|
||||||
|
#include "base/json.hpp"
|
||||||
|
#include "base/string.hpp"
|
||||||
|
#include "base/exception.hpp"
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
#include <boost/algorithm/string/split.hpp>
|
||||||
|
|
||||||
|
using namespace icinga;
|
||||||
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
|
bool l_Debug = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is called by an 'HttpRequest' once the server answers. After doing a short check on the 'response' it
|
||||||
|
* decodes it to a Dictionary and then tells 'QueryEndpoint()' that it's done
|
||||||
|
*/
|
||||||
|
static void ResultHttpCompletionCallback(const HttpRequest& request, HttpResponse& response, bool& ready,
|
||||||
|
boost::condition_variable& cv, boost::mutex& mtx, Dictionary::Ptr& result)
|
||||||
|
{
|
||||||
|
String body;
|
||||||
|
char buffer[1024];
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
while ((count = response.ReadBody(buffer, sizeof(buffer))) > 0)
|
||||||
|
body += String(buffer, buffer + count);
|
||||||
|
|
||||||
|
if (l_Debug) {
|
||||||
|
std::cout << "Received answer\n"
|
||||||
|
<< "\tHTTP code: " << response.StatusCode << "\n"
|
||||||
|
<< "\tHTTP message: '" << response.StatusMessage << "'\n"
|
||||||
|
<< "\tHTTP body: '" << body << "'.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only try to decode the body if the 'HttpRequest' was successful
|
||||||
|
if (response.StatusCode != 200)
|
||||||
|
result = Dictionary::Ptr();
|
||||||
|
else
|
||||||
|
result = JsonDecode(body);
|
||||||
|
|
||||||
|
// Unlock our mutex, set ready and notify 'QueryEndpoint()'
|
||||||
|
boost::mutex::scoped_lock lock(mtx);
|
||||||
|
ready = true;
|
||||||
|
cv.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function takes all the information required to query an nscp instance on
|
||||||
|
* 'host':'port' with 'password'. The String 'endpoint' contains the specific
|
||||||
|
* query name and all the arguments formatted as an URL.
|
||||||
|
*/
|
||||||
|
static Dictionary::Ptr QueryEndpoint(const String& host, const String& port, const String& password,
|
||||||
|
const String& endpoint)
|
||||||
|
{
|
||||||
|
HttpClientConnection::Ptr m_Connection = new HttpClientConnection(host, port, true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
bool ready = false;
|
||||||
|
boost::condition_variable cv;
|
||||||
|
boost::mutex mtx;
|
||||||
|
Dictionary::Ptr result;
|
||||||
|
boost::shared_ptr<HttpRequest> req = m_Connection->NewRequest();
|
||||||
|
req->RequestMethod = "GET";
|
||||||
|
|
||||||
|
// Url() will call Utillity::UnescapeString() which will thrown an exception if it finds a lonely %
|
||||||
|
req->RequestUrl = new Url(endpoint);
|
||||||
|
req->AddHeader("password", password);
|
||||||
|
if (l_Debug)
|
||||||
|
std::cout << "Sending request to 'https://" << host << ":" << port << req->RequestUrl->Format() << "'\n";
|
||||||
|
|
||||||
|
// Submits the request. The 'ResultHttpCompletionCallback' is called once the HttpRequest receives an answer,
|
||||||
|
// which then sets 'ready' to true
|
||||||
|
m_Connection->SubmitRequest(req, boost::bind(ResultHttpCompletionCallback, _1, _2,
|
||||||
|
boost::ref(ready), boost::ref(cv), boost::ref(mtx), boost::ref(result)));
|
||||||
|
|
||||||
|
// We need to spinlock here because our 'HttpRequest' works asynchronous
|
||||||
|
boost::mutex::scoped_lock lock(mtx);
|
||||||
|
while (!ready) {
|
||||||
|
cv.wait(lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex) {
|
||||||
|
// Exceptions should only happen in extreme edge cases we can't recover from
|
||||||
|
std::cout << "Caught exception: " << DiagnosticInformation(ex, false) << '\n';
|
||||||
|
return Dictionary::Ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Takes a Dictionary 'result' and constructs an icinga compliant output string.
|
||||||
|
* If 'result' is not in the expected format it returns 3 ("UNKNOWN") and prints an informative, icinga compliant,
|
||||||
|
* output string.
|
||||||
|
*/
|
||||||
|
static int FormatOutput(const Dictionary::Ptr& result)
|
||||||
|
{
|
||||||
|
if (!result) {
|
||||||
|
std::cout << "UNKNOWN: No data received.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l_Debug)
|
||||||
|
std::cout << "\tJSON Body:\n" << result->ToString() << '\n';
|
||||||
|
|
||||||
|
Array::Ptr payloads = result->Get("payload");
|
||||||
|
if (!payloads) {
|
||||||
|
std::cout << "UNKNOWN: Answer format error: Answer is missing 'payload'.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payloads->GetLength() == 0) {
|
||||||
|
std::cout << "UNKNOWN: Answer format error: 'payload' was empty.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payloads->GetLength() > 1) {
|
||||||
|
std::cout << "UNKNOWN: Answer format error: Multiple payloads are not supported.";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary::Ptr payload;
|
||||||
|
try {
|
||||||
|
payload = payloads->Get(0);
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
std::cout << "UNKNOWN: Answer format error: 'payload' was not a Dictionary.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array::Ptr lines;
|
||||||
|
try {
|
||||||
|
lines = payload->Get("lines");
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
std::cout << "UNKNOWN: Answer format error: 'payload' is missing 'lines'.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lines) {
|
||||||
|
std::cout << "UNKNOWN: Answer format error: 'lines' is Null.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ssout;
|
||||||
|
ObjectLock olock(lines);
|
||||||
|
|
||||||
|
for (const Value& vline : lines) {
|
||||||
|
Dictionary::Ptr line;
|
||||||
|
try {
|
||||||
|
line = vline;
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
std::cout << "UNKNOWN: Answer format error: 'lines' entry was not a Dictionary.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if (!line) {
|
||||||
|
std::cout << "UNKNOWN: Answer format error: 'lines' entry was Null.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssout << payload->Get("command") << ' ' << line->Get("message") << " | ";
|
||||||
|
|
||||||
|
if (!line->Contains("perf")) {
|
||||||
|
ssout << '\n';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array::Ptr perfs = line->Get("perf");
|
||||||
|
ObjectLock olock(perfs);
|
||||||
|
|
||||||
|
for (const Dictionary::Ptr& perf : perfs) {
|
||||||
|
ssout << "'" << perf->Get("alias") << "'=";
|
||||||
|
Dictionary::Ptr values = perf->Contains("int_value") ? perf->Get("int_value") : perf->Get("float_value");
|
||||||
|
ssout << values->Get("value") << values->Get("unit") << ';' << values->Get("warning") << ';' << values->Get("critical");
|
||||||
|
|
||||||
|
if (values->Contains("minimum") || values->Contains("maximum")) {
|
||||||
|
ssout << ';';
|
||||||
|
|
||||||
|
if (values->Contains("minimum"))
|
||||||
|
ssout << values->Get("minimum");
|
||||||
|
|
||||||
|
if (values->Contains("maximum"))
|
||||||
|
ssout << ';' << values->Get("maximum");
|
||||||
|
}
|
||||||
|
|
||||||
|
ssout << ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
ssout << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Fix
|
||||||
|
String state = static_cast<String>(payload->Get("result")).ToUpper();
|
||||||
|
int creturn = state == "OK" ? 0 :
|
||||||
|
state == "WARNING" ? 1 :
|
||||||
|
state == "CRITICAL" ? 2 :
|
||||||
|
state == "UNKNOWN" ? 3 : 4;
|
||||||
|
|
||||||
|
if (creturn == 4) {
|
||||||
|
std::cout << "check_nscp UNKNOWN Answer format error: 'result' was not a known state.\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << ssout.rdbuf();
|
||||||
|
return creturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process arguments, initialize environment and shut down gracefully.
|
||||||
|
*/
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
po::variables_map vm;
|
||||||
|
po::options_description desc("Options");
|
||||||
|
|
||||||
|
desc.add_options()
|
||||||
|
("help,h", "Print usage message and exit")
|
||||||
|
("version,V", "Print version and exit")
|
||||||
|
("debug,d", "Verbose/Debug output")
|
||||||
|
("host,H", po::value<String>()->required(), "REQUIRED: NSCP API Host")
|
||||||
|
("port,P", po::value<String>()->default_value("8443"), "NSCP API Port (Default: 8443)")
|
||||||
|
("password", po::value<String>()->required(), "REQUIRED: NSCP API Password")
|
||||||
|
("query,q", po::value<String>()->required(), "REQUIRED: NSCP API Query endpoint")
|
||||||
|
("arguments,a", po::value<std::vector<String>>()->multitoken(), "NSCP API Query arguments for the endpoint");
|
||||||
|
|
||||||
|
po::basic_command_line_parser<char> parser(argc, argv);
|
||||||
|
|
||||||
|
try {
|
||||||
|
po::store(
|
||||||
|
parser
|
||||||
|
.options(desc)
|
||||||
|
.style(
|
||||||
|
po::command_line_style::unix_style |
|
||||||
|
po::command_line_style::allow_long_disguise)
|
||||||
|
.run(),
|
||||||
|
vm);
|
||||||
|
|
||||||
|
if (vm.count("version")) {
|
||||||
|
std::cout << "Version: " << VERSION << '\n';
|
||||||
|
Application::Exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm.count("help")) {
|
||||||
|
std::cout << argv[0] << " Help\n\tVersion: " << VERSION << '\n';
|
||||||
|
std::cout << "check_nscp_api is a program used to query the NSClient++ API.\n";
|
||||||
|
std::cout << desc;
|
||||||
|
std::cout << "For detailed information on possible queries and their arguments refer to the NSClient++ documentation.\n";
|
||||||
|
Application::Exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.notify();
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
std::cout << e.what() << '\n' << desc << '\n';
|
||||||
|
Application::Exit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm.count("debug")) {
|
||||||
|
l_Debug = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the URL string and escape certain characters since Url() follows RFC 3986
|
||||||
|
String endpoint = "/query/" + vm["query"].as<String>();
|
||||||
|
if (!vm.count("arguments"))
|
||||||
|
endpoint += '/';
|
||||||
|
else {
|
||||||
|
endpoint += '?';
|
||||||
|
for (String argument : vm["arguments"].as<std::vector<String>>()) {
|
||||||
|
String::SizeType pos = argument.FindFirstOf("=");
|
||||||
|
if (pos == String::NPos)
|
||||||
|
endpoint += Utility::EscapeString(argument, ACQUERY_ENCODE, false);
|
||||||
|
else {
|
||||||
|
String key = argument.SubStr(0, pos);
|
||||||
|
String val = argument.SubStr(pos + 1);
|
||||||
|
endpoint += Utility::EscapeString(key, ACQUERY_ENCODE, false) + "=" + Utility::EscapeString(val, ACQUERY_ENCODE, false);
|
||||||
|
}
|
||||||
|
endpoint += '&';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This needs to happen for HttpRequest to work
|
||||||
|
Application::InitializeBase();
|
||||||
|
|
||||||
|
Dictionary::Ptr result = QueryEndpoint(vm["host"].as<String>(), vm["port"].as<String>(),
|
||||||
|
vm["password"].as<String>(), endpoint);
|
||||||
|
|
||||||
|
// Application::Exit() is the clean way to exit after calling InitializeBase()
|
||||||
|
Application::Exit(FormatOutput(result));
|
||||||
|
return 255;
|
||||||
|
}
|
Loading…
Reference in New Issue