Back to OP5 Monitor FAQ

Creating an HTTP API driven command-line tool

Solutions provided by the OP5 Monitor Community for the benefit of other clients. These solutions or documents are NOT maintained, tested or supported by ITRS Client Services and are provided as written by the original submitter.

Version Copied

This article was written for version 7.0 of OP5 Monitor, it could work on both lower and higher versions unless otherwise stated. Articles in the Community-Space are not supported by OP5 Client Services.

About Copied

This document describes how to build custom tools for executing remote commands using the HTTP API. You may download the script that is created and use without warranty or support. You should read through the guide to understand the script and how it could be extended. PHP is used as the scripting language in the examples here, though the ideas can be transposed to other languages. Python examples are also given in the online API documentation.

The OP5 Monitor API is the recommended and supported way of communicating with OP5 Monitor from external sources.

Why use the HTTP API when we have NSCA available? Copied

The Nagios Service Check Acceptor (NSCA) is a tool for submitting passive check results to Nagios or Naemon. As a result, it will bypass the authentication layers of OP5 Monitor.

By contrast the HTTP API uses the OP5 authentication as it essentially mirrors the function of the web interface. Additionally, OP5 Monitor extends the functionality of Naemon and therefore provides commands not available using NSCA.

A Command Line Example Copied

The API documentation can be found on your OP5 monitor via the web interface using the URL with your resolvable hostname:

http:///api

If you navigate to the API documentation and click the Command link in the left-side menu you will then see a list of commands. Selecting the PROCESS_SERVICE_CHECK_RESULT link will then display details of how to submit a passive check result for services. There are examples for PHP, Python and plain shell using curl.

Api

The curl example from the web page is repeated here below, with placeholders that would need to be replaced with actual data.

curl -u ‘:’ -H ‘content-type: application/json’ -d ‘{“host_name”:“string”,“service_description”:“string”,“status_code”:“int”,“plugin_output”:“string”}’ ‘https:///api/command/PROCESS_SERVICE_CHECK_RESULT’

This is clearly a long-winded command to type out and it is expected that users would script and modularise their API requests.

Creating a reusable script Copied

Note! All the example scripts below are outside the bounds of OP5 support.

In the first instance we will create a tool for the explicit process_service_check command and then gradually build a more generic tool.

The following example can only submit the PROCESS_SERVICE_CHECK_RESULT command and does not validate inputs to the script, which can result in unexpected errors.

example1.php

#!/usr/bin/php

'); define('MONITOR\_USER', ''); define('MONITOR\_PASS', ''); // We will send the data to the HTTP API as JSON, adding the data given from the command-line // which is stored in the $argv variable in PHP. $data = json\_encode(array( "host\_name" => $argv[1], "service\_description" => $argv[2], "status\_code " => intval($argv[3]), "plugin\_output" => $argv[4])); $a\_handle = curl\_init('https://' . MONITOR\_HOST . '/api/command/PROCESS\_SERVICE\_CHECK\_RESULT'); // Tell the API that this is JSON curl\_setopt($a\_handle, CURLOPT\_HTTPHEADER, array('Content-Type: application/json')); // Tell the API who we are curl\_setopt($a\_handle, CURLOPT\_USERPWD, MONITOR\_USER . ':' . MONITOR\_PASS); // Tell curl that this is a HTTP POST curl\_setopt($a\_handle, CURLOPT\_POST, 1); // Tell curl that we want to see the result of the request curl\_setopt($a\_handle, CURLOPT\_RETURNTRANSFER, TRUE); // And give curl the data we are about to send curl\_setopt($a\_handle, CURLOPT\_POSTFIELDS, $data); // By default monitor is installed with a self-signed certificate, if you have a proper // SSL cert. you may remove this line(s), otherwise you need to keep it. curl\_setopt($handle, CURLOPT\_SSL\_VERIFYHOST, FALSE); curl\_setopt($a\_handle, CURLOPT\_SSL\_VERIFYPEER, false); // Execute the curl request and json decode the result$result = curl\_exec($a\_handle); $result = json\_decode($result, true); /\*\* \* This script relies on the monitor HTTP API to handle errors and return them \* in a printable format. This could write to a log instead of printing depending \* on your needs. \* \* Errors from API POST's contain an "error" and "full\_error" member, successes \* contain a "result" member. \*/ if ($result['error']) { echo $result['error'] . "\n"; echo $result['full\_error'] . "\n"; exit(1); } elseif ($result['result']) { echo $result['result'] . "\n"; echo sprintf("On service '%s' of host '%s'\n", $argv[2], $argv[1]); } "ex1.php" 62 lines, 2612 bytes written

This next example has more advanced PHP scripting that makes it extensible to support commands other than the submission of passive check results.

example2.php

#!/usr/bin/php<?php /** * This script can run the PROCESS_SERVICE_CHEK_RESULT and PROCESS_HOST_CHECK_RESULT * based on parameters given, that is given you submitted host AND service name or * simply the host name. The first submits a service result, the second a host * result. * * ./example2.php “monitor;Zombie processes” 0 “OK: Everything is fine and dandy” * ./example2.php “monitor” 0 “UP: Everything is fine and dandy” * * It also has some failsafes for improper or forgotten input which it handles by * setting this parameters to types which are not allowed for that field in the HTTP * API, the API will supply a proper error message when executing. * * plugin_output is not required for the command so executing: * * ./example2.php “monitor” 0 * * Will be successfull and the output will be set to empty. */

define(‘MONITOR_HOST’, ‘’); define(‘MONITOR_USER’, ‘’); define(‘MONITOR_PASS’, ‘’);

/** * This script takes the host and service identifiers in naemon/nagios style, * separated by a semicolon. i.e. “host;service” */

$key = explode(’;’, $argv[1]); $host = $key[0];

// This is the ternary operator, I will use it during these scripts // for setting values or defaults, in simple terms think of them as // (if) ? then : else, in this case if $key[1] isset, assign that to // $service else assign false to service, since no service description // was supplied.

$service = (isset($key[1])) ? $key[1] : false;

/** * Validate that status_code and plugin_output are set, if status_code is not an * integer set it to an invalid value so that the API returns an error. */ $state = (isset($argv[2]) && is_numeric($argv[2])) ? intval($argv[2]) : false; $output = (isset($argv[3])) ? $argv[3] : false; $data = array( “host_name” => $host, “status_code” => $state, “plugin_output” => $output); // Only add “service_description” if this is a service request

if ($service) { $data[‘service_description’] = $service; } // Select command based on whether a service was given or not $command = ($service) ? ‘PROCESS_SERVICE_CHECK_RESULT’ : ‘PROCESS_HOST_CHECK_RESULT’; // Build the URL from MONITOR_HOST name and determined $command $url = sprintf(‘https://%s/api/command/%s’, MONITOR_HOST, $command); $data = json_encode($data);

/** * This part is the example presented in the API documentation */

$a_handle = curl_init($url); curl_setopt($a_handle, CURLOPT_USERPWD, MONITOR_USER . ‘:’ . MONITOR_PASS); curl_setopt($a_handle, CURLOPT_POST, 1); curl_setopt($a_handle, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($a_handle, CURLOPT_POSTFIELDS, $data); curl_setopt($a_handle, CURLOPT_HTTPHEADER, array(‘Content-Type: application/json’)); curl_setopt($a_handle, CURLOPT_SSL_VERIFYPEER, false); $result = curl_exec($a_handle); $result = json_decode($result, true);

/** * This script relies on the monitor HTTP API to handle errors and return them * in a printable format. This could write to a log instead of printing depending * on your needs. */ if ($result[’error’]) { echo $result[’error’] . “\n”; echo $result[‘full_error’] . “\n”; exit(1); } elseif ($result[‘result’]) { echo $result[‘result’] . “\n”; echo sprintf(“On service ‘%s’ of host ‘%s’\n”, $service, $host); }

As can be seen in the above script we have two functions that are closely tied with the action they perform, service_result and host_result, the invocation of these is dynamic, based on the context (service or host) the script was called, and which action was supplied ( e.g. “result”). Given this we can easily add another of these functions to perform a different command, for example acknowledge, which is incorporated in this 3rd example below.

op5remote.php

#!/usr/bin/php

$host, "service\_description" => $service, "status\_code" => $state, "plugin\_output" => $output )); } /\*\* \* Submits a passive host check result using the op5 Monitor \* PROCESS\_HOST\_CHECK\_RESULT endpoint of the HTTP API \* \* @param string $host The host \* @param array $parameters The parameters to use \* @return void \*/ function host\_result ($host, $parameters) { $state = (isset($parameters[0]) && is\_numeric($parameters[0])) ? intval($parameters[0]) : false; $output = (isset($parameters[1])) ? $parameters[1] : ''; remote\_call('PROCESS\_SERVICE\_CHECK\_RESULT', array( "host\_name" => $host, "status\_code" => $state, "plugin\_output" => $output )); } /\*\* \* Submits an acknowledge to op5 Monitor ACKNOWLEDGE\_HOST\_PROBLEM \* endpoint of the HTTP API \* \* @param string $host The host \* @param array $parameters The parameters to use \* @return void \*/ function host\_ack ($host, $parameters) { $comment = (isset($parameters[0])) ? $parameters[0] : 'Acknowledged by Monitor Remote'; remote\_call('ACKNOWLEDGE\_HOST\_PROBLEM', array( "host\_name" => $host, "comment" => $comment, "sticky" => 1, "notify" => true, "persistent" => true )); } /\*\* \* Submits an acknowledge to op5 Monitor ACKNOWLEDGE\_SVC\_PROBLEM \* endpoint of the HTTP API \* \* @param string $host The host \* @param string $service The service \* @param array $parameters The parameters to use \* @return void \*/ function service\_ack ($host, $service, $parameters) { $comment = (isset($parameters[0])) ? $parameters[0] : 'Acknowledged by Monitor Remote'; remote\_call('ACKNOWLEDGE\_SVC\_PROBLEM', array( "host\_name" => $host, "service\_description" => $service, "comment" => $comment, "sticky" => 1, "notify" => true, "persistent" => true )); } /\*\* \* Identify required parameters, action and identifier, and invoke proper function \* for the execution. \*/ $action = $argv[1]; $identifier = explode(';', $argv[2]); $host = $identifier[0]; $service = (isset($identifier[1])) ? $identifier[1] : false; $parameters = array\_slice($argv, 3); $context = ($service) ? 'service' : 'host'; $caller = strtolower($context . '\_' . $action); if (function\_exists($caller)) { if ($service) { call\_user\_func\_array($caller, array($host, $service, $parameters)); } else { call\_user\_func\_array($caller, array($host, $parameters)); } } else { echo sprintf("No action '%s' on context '%s' available\n", $action, $context); exit(1); }

Summary Copied

With simple scripts accessing the OP5 API you can perform and automate many functions that you would otherwise need to access the web GUI for.

Examples Copied

Examples using the above op5remote php script.

Acknowledge hosts Copied

op5remote ack "host" "My comment"

Acknowledge services Copied

op5remote ack "host;service" "My comment"

Submit passive host results Copied

op5remote result "host;service" 0 "This host is UP"

Submit passive service results Copied

op5remote result "host;service" 0 "This service is OK"
["Geneos"] ["FAQ"]

Was this topic helpful?