Page 1 of 2

Schedule Downtime Using Rest API

Posted: Tue Nov 06, 2018 8:28 am
by ddaluka
Hi,

I have a requirement to put the schedule downtime using the rest API and the nagios version (5.4.7) I have got doesn't have this rest API available so I tried to create a custom API for that. I have created following php file. '/usr/local/nagiosxi/html/includes/components/nagiosxicustomendpoints/nagiosxicustomendpoints.inc.php '

Here is the section to register the custom api.

Code: Select all

register_custom_api_callback('downtime', 'hostgroup', 'nagiosxicustomendpoints_downtime_hostgroup');
Here is the function definition.

Code: Select all

function nagiosxicustomendpoints_downtime_hostgroup($endpoint, $verb, $args) {

    $argslist = '';
    $schParams = array();
    $nagiosCmdFile = '/usr/local/nagios/var/rw/nagios.cmd';
    if (isset($_GET['hostgroup_name'])) {
        $schParams['hostgroup_name'] = $_GET['hostgroup_name'];
    }
    if (isset($_GET['start_time'])) {
        $schParams['start_time'] = $_GET['start_time'];
    }
    if (isset($_GET['end_time'])) {
        $schParams['end_time'] = $_GET['end_time'];
    }
    if (isset($_GET['fixed'])) {
        $schParams['fixed'] = $_GET['fixed'];
    }
    if (isset($_GET['trigger_id'])) {
        $schParams['trigger_id'] = $_GET['trigger_id'];
    }
    if (isset($_GET['duration'])) {
        $schParams['duration'] = $_GET['duration'];
    }
    if (isset($_GET['author'])) {
        $schParams['author'] = $_GET['author'];
    }
    if (isset($_GET['comment'])) {
        $schParams['comment'] = $_GET['comment'];
    }
    foreach ($args as $key => $arg) {
        $argslist .= "<arg><num>{$key}</num><data>{$arg}</data></arg>";
    }

    $xml = "    <xml>
                    <endpoint>{$endpoint}</endpoint>
                    <verb>{$verb}</verb>
                    <hostgroup>{$schParams['hostgroup_name']},{$schParams['start_time']},{$schParams['end_time']},{$schParams['fixed']},{$schParams['trigger_id']},{$schParams['duration']},{$schParams['author']},{$schParams['comment']}</hostgroup>
                    <argslist>{$argslist}</argslist>
                </xml>";

   //echo file_put_contents($nagiosCmdFile, "$schParams['hostgroup_name'],$schParams['start_time'],$schParams['end_time'],$schParams['fixed'],$schParams['trigger_id'],$schParams['duration'],$schParams['author'],$schParams['comment']", FILE_APPEND);

$file = '/tmp/test_with_php.txt';

// Open the file to get existing content
//$current = file_get_contents($file);

echo "hi";

// Append a new person to the file
$current = "John Smith\n";

// Write the contents back to the file
$output = file_put_contents($file, $current);
echo "output is $output";


    return xml2json::transformXmlStringToJson($xml);
}
I am trying to use Nagios External command to schedule the downtime and I need to write this information in nagios.cmd file but when I am trying to use the curl command, its showing the output bytes but not writing anything. I tried it with a test file also in /tmp folder but its not working.

If i am trying with a test php file, its working and writing the file. But not when using curl to use it via rest API.

Code: Select all

<?php

$file = '/tmp/test_with_php.txt';

// Open the file to get existing content
#$current = file_get_contents($file);

echo "hi";

// Append a new person to the file
$current = "John Smith\n";

// Write the contents back to the file
echo file_put_contents($file, $current);



?>
'https://assets.nagios.com/downloads/nag ... and_id=123'

Can you please help me on this?

Re: Schedule Downtime Using Rest API

Posted: Tue Nov 06, 2018 2:37 pm
by jomann
This is definitely outside the support scope, including the fact that it is included in XI 5.5+
However, I can give you a couple pointers and maybe somewhere to look.

The easiest way to do this is going to be sending Nagios Core an external command, we can build the external command call, and run it through the XI system's functions. Here is a snippet of how we generate an external command and run it.

Code: Select all

// Generate command arguments
$args = array("comment_data" => $comment,
        "comment_author" => $author,
        "trigger_id" => $triggered_by,
        "start_time" => $start,
        "end_time" => $end,
        "fixed" => 1);

// If flexible, add a duration value
if ($flexible == 1) {
    $args['fixed'] = 0;
    $args['duration'] = $duration;
}

$host_args = $args;
$host_args['host_name'] = $host;

// Generate the external command string
$cmd = NAGIOSCORE_CMD_SCHEDULE_HOST_DOWNTIME;
$core_cmd = core_get_raw_command($cmd, $host_args);

// Submit command ($x will be false if cannot submit)
$output = ""; // output is passed as reference, so must be defined beforehand
$x = core_submit_command($core_cmd, $output);
Basically any command you can send to Nagios Core via https://assets.nagios.com/downloads/nag ... ernalcmds/ you can send via this using NAGIOSCORE_CMD_<name of command> and here are the values you can pass into the core_get_raw_command():

host_name
service_name
host_group
service_group
persistent_comment
comment_author
comment_data

// timestamps
start_time
end_time

// for scheduled commands
notification_time
scheduled_time

// for downtime
fixed
trigger_id
duration

// used for deletion
comment_id
downtime_id

sticky
notify

The above correspond to the values you'll find in the external commands that are posted on the page I linked. You just pass them in using the $args array link in the example and it will generate the command for you. You can, if you want, just use core_submit_command() to run the command yourself like:

Code: Select all

$output = "";
core_submit_command("SCHEDULE_SVC_DOWNTIME;host1;service1;1110741500;1110748700;0;0;7200;Some One;Some Downtime Comment", $output);
Also, you should use json_encode() if it's available for your PHP version instead of relying on xml2json which is removed in newer versions.

Re: Schedule Downtime Using Rest API

Posted: Tue Nov 06, 2018 3:56 pm
by cdienger
I believe it's failing with the second parameter of the file_puts_contents function. Try putting everything in a string or serialize the array:

$string = $schParams['hostgroup_name'] . $schParams['start_time'] . $schParams['end_time'] . $schParams['fixed'] . $schParams['trigger_id'] . $schParams['duration'] . $schParams['author'] .$schParams['comment'];

file_put_contents($file, $string, FILE_APPEND);

or

file_put_contents($file, serialize($schParams), FILE_APPEND);

Re: Schedule Downtime Using Rest API

Posted: Wed Nov 07, 2018 5:10 am
by ddaluka
jomann wrote:This is definitely outside the support scope, including the fact that it is included in XI 5.5+
However, I can give you a couple pointers and maybe somewhere to look.

The easiest way to do this is going to be sending Nagios Core an external command, we can build the external command call, and run it through the XI system's functions. Here is a snippet of how we generate an external command and run it.

Code: Select all

// Generate command arguments
$args = array("comment_data" => $comment,
        "comment_author" => $author,
        "trigger_id" => $triggered_by,
        "start_time" => $start,
        "end_time" => $end,
        "fixed" => 1);

// If flexible, add a duration value
if ($flexible == 1) {
    $args['fixed'] = 0;
    $args['duration'] = $duration;
}

$host_args = $args;
$host_args['host_name'] = $host;

// Generate the external command string
$cmd = NAGIOSCORE_CMD_SCHEDULE_HOST_DOWNTIME;
$core_cmd = core_get_raw_command($cmd, $host_args);

// Submit command ($x will be false if cannot submit)
$output = ""; // output is passed as reference, so must be defined beforehand
$x = core_submit_command($core_cmd, $output);
Basically any command you can send to Nagios Core via https://assets.nagios.com/downloads/nag ... ernalcmds/ you can send via this using NAGIOSCORE_CMD_<name of command> and here are the values you can pass into the core_get_raw_command():

host_name
service_name
host_group
service_group
persistent_comment
comment_author
comment_data

// timestamps
start_time
end_time

// for scheduled commands
notification_time
scheduled_time

// for downtime
fixed
trigger_id
duration

// used for deletion
comment_id
downtime_id

sticky
notify

The above correspond to the values you'll find in the external commands that are posted on the page I linked. You just pass them in using the $args array link in the example and it will generate the command for you. You can, if you want, just use core_submit_command() to run the command yourself like:

Code: Select all

$output = "";
core_submit_command("SCHEDULE_SVC_DOWNTIME;host1;service1;1110741500;1110748700;0;0;7200;Some One;Some Downtime Comment", $output);
Also, you should use json_encode() if it's available for your PHP version instead of relying on xml2json which is removed in newer versions.
Hi jomann,

We are on the same page on using this solution because I am trying to use external command by putting this data in nagios.cmd file. After putting this post yesterday, I also tried to use an already existing submit_command function but it didn't work. May be because that is only written as per new NagiosXI command but not handling NagiosCore external command formats or I am not able to pass the argument in correct format.

Please see /usr/local/nagiosxi/html/api/includes/utils-api.inc.php which is using sumbit command for existing APIs. This function defined in /usr/local/nagiosxi/html/includes/js/commands.js

I tried to use this function as below and also tried it with different parameter formats but that didn't work.

Code: Select all

submit_command(NAGIOSCORE_CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME,$schParams);


Response was:

Code: Select all

==> cmdsubsys.log <==
PROCESSING COMMAND ID 11...
PROCESS COMMAND: CMD=84, DATA=a:8:{s:14:"hostgroup_name";s:4:"test";s:10:"start_time";s:10:"1541487600";s:8:"end_time";s:10:"1541494800";s:5:"fixed";s:1:"0";s:10:"trigger_id";s:1:"0";s:8:"duration";s:4:"7200";s:6:"author";s:7:"ddaluka";s:7:"comment";s:5:"test1";}
INVALID COMMAND (84)! 
I will try your solution and I will also see if we can upgrade nagios. Thanks For your response. It is very helpful.

Re: Schedule Downtime Using Rest API

Posted: Wed Nov 07, 2018 12:38 pm
by cdienger
Let us know once you've had a chance to test @jomann's suggestion or upgrade the software.

Re: Schedule Downtime Using Rest API

Posted: Thu Nov 08, 2018 7:01 am
by ddaluka
Hi cdienger, jomann

We will be upgrading nagios to 5.5.6 version and I tried it on one of our test box. I can see there are API's available now. I had a requirement to put the downtime for a hostgroup but looks like there is a bug in the code. If you see below section from utils-api.inc.php, if "only" option is not given along with hostgroup name, API should put downtime for hosts and services both but it is trying to run only core_host_cmd in both the cases and putting the double downtime for hosts and not applying any downtime for services.

If "only=services" option is chosen along with hostgroup that won't work either and will put downtime only for hosts.

Code: Select all

        if (!empty($hostgroups)) {
            foreach ($hostgroups as $hostgroup) {
                $hostgroup_args = $args;
                $hostgroup_args['host_group'] = $hostgroup;
                $core_host_cmd = core_get_raw_command(NAGIOSCORE_CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME, $hostgroup_args);
                $core_svc_cmd = core_get_raw_command(NAGIOSCORE_CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME, $hostgroup_args);

                // Add hosts if we are not only adding services
                if ($only != 'services') {
                    $x = core_submit_command($core_host_cmd, $output);
                    if (!$x) {
                        $errors++;
                        $error_items['hostgroups'][$hostgroup][] = _('HOSTS');
                    }
                    $scheduled['hostgroups'][$hostgroup][] = _('HOSTS');
                }

                // Add services if we are not only adding hosts
                if ($only != 'hosts') {
                    $x = core_submit_command($core_host_cmd, $output);
                    if (!$x) {
                        $errors++;
                        $error_items['hostgroups'][$hostgroup][] = _('SERVICES');
                    }
                    $scheduled['hostgroups'][$hostgroup][] = _('SERVICES');
                }
            }
        }
The same problem is in servicegroup code as well.

Command executed:

Code: Select all

curl -XPOST "https://<ip>/nagiosxi/api/v1/system/scheduleddowntime?apikey=<api key>&pretty=1" -d "comment=Test downtime creation&start=1541677782&end=1541678382&hostgroups[]=testHostGroup" -k
{
    "success": "Schedule downtime command(s) sent successfully.",
    "scheduled": {
        "hostgroups": {
            "testHostGroup": [
                "HOSTS",
                "SERVICES"
            ]
        }
    }
}

Re: Schedule Downtime Using Rest API

Posted: Thu Nov 08, 2018 1:41 pm
by jomann
This looks like a bug for sure, we are updating this for 5.5.7 but for now, you're right about it using core_host_cmd, you should set the second core_host_cmd under the $only != 'hosts' to core_svc_cmd and that should fix the issue for you in the meantime.

Re: Schedule Downtime Using Rest API

Posted: Mon Nov 12, 2018 5:44 am
by ddaluka
Hi jomann,

Thanks. Is there any plan or change request available to remove the downtime as per hostgroup/servicegroup name? currently available APIs and NagiosCore command expects downtime ID . Is it possible to put a wrapper which can accept object name and can get the downtime ID and remove the downtime for that object?

Re: Schedule Downtime Using Rest API

Posted: Tue Nov 13, 2018 6:01 pm
by ssax
Right now it's not on the roadmap that I'm aware of, I can create a feature request for it if you'd like?

Re: Schedule Downtime Using Rest API

Posted: Wed Nov 14, 2018 5:20 am
by ddaluka
ssax wrote:Right now it's not on the roadmap that I'm aware of, I can create a feature request for it if you'd like?
Hi ssax,

Yes please. Thank You. We can close this thread now as I do not have anymore queries on this topic. Thanks for your support.