report for hosts and services not in groups

This support forum board is for support questions relating to Nagios XI, our flagship commercial network monitoring solution.
Post Reply
markjgreene
Posts: 2
Joined: Tue Aug 08, 2023 10:45 am

report for hosts and services not in groups

Post by markjgreene »

Is there a method or an already existing report to find hosts not in host groups and services not in service groups for XI v5.8.5 ?

Thanks!
mark greene
User avatar
eloyd
Cool Title Here
Posts: 2129
Joined: Thu Sep 27, 2012 9:14 am
Location: Rochester, NY
Contact:

Re: report for hosts and services not in groups

Post by eloyd »

Not inherently within XI. But you can cheat a little bit and use the API to find things out. Click on "Help" and then "Objects Reference" within XI and you'll be greeted with a bunch of API calls that you can make to query the host groups. To my knowledge, no one has written an API to the parser to see exactly what Nagios Core sees when it unwinds the config files, but you can use "jq" and bash to traipse through the JSON list of groups and then groupmembers to see what's in every group. Then combine that list with the list of all hosts and figure out what's not in a group.

It's not neccessarily easy, but it should be relatively straightforward.
Image
Eric Loyd • http://everwatch.global • 844.240.EVER • @EricLoydI'm a Nagios Fanatic!
User avatar
danderson
Posts: 111
Joined: Wed Aug 09, 2023 10:05 am

Re: report for hosts and services not in groups

Post by danderson »

I made a little script based on what @eloyd said

Code: Select all

#!/bin/bash

key=""
xi=""

function usage() {
        echo ""
        echo "Usage: $0 -k \"API Key\" -x \"XI Hostname\""
        echo "Usage: $0 -h,--help"
        echo ""
        echo "Options:"
        echo " -k,--key     API Key         XI API Key"
        echo " -x,--xi      XI Hostname     Hostname of XI server"
        echo ""
}

if [ $# -eq 0 ]; then
        usage
        exit 1
fi

while [ "$1" != "" ]
do
    case "$1" in
        -k | --key) key=$2; shift 2;;
        -x | --xi) xi=$2; shift 2;;
        -h | --help) usage; exit 0;;
        *) usage; exit 1;;
    esac
done

if [ -z $key ]; then
    echo "No API key specified"
    exit 1
fi

if [ -z $xi ]; then
    echo "No XI hostname specified"
    exit 1
fi

hostgroupmembers="$(curl -s -XGET "http://$xi/nagiosxi/api/v1/objects/hostgroupmembers?apikey=$key&pretty=1" | grep "host_name" | sed -e 's/^[ \t]*//;s/,*[ \t]*$//')"
hosts="$(curl -s -XGET "http://$xi/nagiosxi/api/v1/objects/host?apikey=$key&pretty=1" | grep "host_name" | sed -e 's/^[ \t]*//;s/,*[ \t]*$//')"

servicegroupmembers="$(curl -s -XGET "http://$xi/nagiosxi/api/v1/objects/servicegroupmembers?apikey=$key&pretty=1" | grep "service_description" | sed -e 's/^[ \t]*//;s/,*[ \t]*$//')"
services="$(curl -s -XGET "http://$xi/nagiosxi/api/v1/objects/service?apikey=$key&pretty=1" | grep "service_description" | sed -e 's/^[ \t]*//;s/,*[ \t]*$//')"
# echo -e "Hostgroup members:\n$hostgroupmembers\n"
# echo -e "Hosts:\n$hosts\n"
# echo -e "Servicegroup members:\n$servicegroupmembers\n"
# echo -e "Services:\n$services\n"

echo "Hosts not in Hostgroups:"
echo "$(diff --suppress-common-lines <(echo "$hosts") <(echo "$hostgroupmembers") | grep "host_name" | sed -e 's/^< "host_name": //')"
echo ""
echo "Services not in Servicegroups"
echo "$(diff --suppress-common-lines <(echo "$services") <(echo "$servicegroupmembers") | grep "service_description" | sed -e 's/^< "service_description": //')"

exit 0
You could probably do things a little be different with the sed's and the diffs, but this is the general strategy.
User avatar
eloyd
Cool Title Here
Posts: 2129
Joined: Thu Sep 27, 2012 9:14 am
Location: Rochester, NY
Contact:

Re: report for hosts and services not in groups

Post by eloyd »

Nice! That's pretty much what I was suggesting. And I love it when someone else does the work for me. :-)
Image
Eric Loyd • http://everwatch.global • 844.240.EVER • @EricLoydI'm a Nagios Fanatic!
User avatar
danderson
Posts: 111
Joined: Wed Aug 09, 2023 10:05 am

Re: report for hosts and services not in groups

Post by danderson »

If you want it in php and with arrays you can manipulate further, try

Code: Select all

<?php 

$key = "";
$xi = "";
$shortopts = "";
$longopts = array();
$name = basename(__FILE__, "");
$hosts = array();
$hostgroupmembers = array();
$services = array();
$servicegroupmembers = array();

// Short options
$shortopts .= "k:";
$shortopts .= "x:";
$shortopts .= "h";

// Long options
$longopts[] = "key:";
$longopts[] = "xi:";
$longopts[] = "help";

$values = getopt($shortopts, $longopts);

function print_usage($name) {
    echo "\nUsage: php ./$name -k \"API Key\" -x \"XI Hostname\"\n";
    echo "Usage: php ./$name --key \"API Key\" --xi \"XI Hostname\"\n";
    echo "Usage: php ./$name -h,--help\n";
    echo "Options:\n";
    echo " -k,--key     API Key         XI API Key\n";
    echo " -x,--xi      XI Hostname     Hostname of XI server\n\n";
    exit(0);
}

if (empty($values)) {
    print_usage($name);
}

if (isset($values["help"]) || isset($values["h"])) {
    print_usage($name);
}

if (empty($values["k"]) && empty($values["key"])) {
    echo "No API key specified\n";
    exit(1);
} else if (!empty($values["k"]) && !empty($values["key"])) {
    echo "Too many API keys specified\n";
    exit(1);
} else {
    if (empty($values["k"])) {
        if (is_array($values["key"])) {
            echo "Too many API keys specified\n";
            exit(1);
        }
        $key = $values["key"];
    } else {
        if (is_array($values["k"])) {
            echo "Too many API keys specified\n";
            exit(1);
        }
        $key = $values["k"];
    }
}

if (empty($values["x"]) && empty($values["xi"])) {
    echo "No XI specified\n";
    exit(1);
} else if (!empty($values["x"]) && !empty($values["xi"])) {
    echo "Too many XIs specified\n";
    exit(1);
} else {
    if (empty($values["x"])) {
        if (is_array($values["xi"])) {
            echo "Too many XIs specified\n";
            exit(1);
        }
        $xi = $values["xi"];
    } else {
        if (is_array($values["x"])) {
            echo "Too many XIs specified\n";
            exit(1);
        }
        $xi = $values["x"];
    }
}

$hoststring = file_get_contents("http://$xi/nagiosxi/api/v1/objects/host?apikey=$key");
$hostjson = json_decode($hoststring, true);

$servicestring = file_get_contents("http://$xi/nagiosxi/api/v1/objects/service?apikey=$key");
$servicejson = json_decode($servicestring, true);

$hostmemberstring = file_get_contents("http://$xi/nagiosxi/api/v1/objects/hostgroupmembers?apikey=$key");
$hostmemberjson = json_decode($hostmemberstring, true);

$servicememberstring = file_get_contents("http://$xi/nagiosxi/api/v1/objects/servicegroupmembers?apikey=$key");
$servicememberjson = json_decode($servicememberstring, true);

array_walk_recursive($hostjson, function ($value, $key) use (&$hosts) {
    if ($key == "host_name") {
        $hosts[] = $value;
    }
});

array_walk_recursive($servicejson, function ($value, $key) use (&$services) {
    if ($key == "service_description") {
        $services[] = $value;
    }
});

array_walk_recursive($hostmemberjson, function ($value, $key) use (&$hostgroupmembers) {
    if ($key == "host_name") {
        $hostgroupmembers[] = $value;
    }
});

array_walk_recursive($servicememberjson, function ($value, $key) use (&$servicegroupmembers) {
    if ($key == "service_description") {
        $servicegroupmembers[] = $value;
    }
});


$uniquehosts = array_diff($hosts, $hostgroupmembers);
$uniqueservices = array_diff($services, $servicegroupmembers);

print_r($uniquehosts);
print_r($uniqueservices);

?>
markjgreene
Posts: 2
Joined: Tue Aug 08, 2023 10:45 am

Re: report for hosts and services not in groups

Post by markjgreene »

Thank you all for the replies, I appreciate that. My apologies for not replying sooner. I found a direct MySQL solution as well:

SELECT name1 as host_name
FROM nagios_objects
WHERE object_id NOT IN (SELECT host_object_id from nagios_hostgroup_members)
AND is_active=1
AND objecttype_id=1;

Obviously, this requires direct access to the host running the MySQL db for the Nagios XI system and the credentials used by the XI processes to access the Nagios db, so this is not going to be a generally applicable solution for everyone.

mark
User avatar
eloyd
Cool Title Here
Posts: 2129
Joined: Thu Sep 27, 2012 9:14 am
Location: Rochester, NY
Contact:

Re: report for hosts and services not in groups

Post by eloyd »

You also run the risk that the database schema changes between releases. The API exists to make sure you always have a supported method of getting information. I'd suggest you switch to it rather the SQL queries.
Image
Eric Loyd • http://everwatch.global • 844.240.EVER • @EricLoydI'm a Nagios Fanatic!
Post Reply