Can you use an "icingacli" command as a service?

Hey everyone,

I want to do this check: icingacli vspheredb check host --name host-name. This works fine in the terminal on the master. So I started making a command but soon noticed that it will always use the PluginDir as directory. So I can’t point it to the initial icingacli. I found this post about the same issue. But if I create a file named icingacli-vspheredb in the PluginDir and set the command to the same name of the file my hosts will state this issue:

/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 1: object: not found
/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 2: import: not found
/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 3: =: not found
timeout: invalid time interval �=�
Try 'timeout --help' for more information.
/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 5: arguments: not found
/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 6: (no key): not found
/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 7: order: not found
/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 8: required: not found
/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 9: skip_key: not found
/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 10: value: not found
/usr/lib/nagios/plugins/icingacli-vspheredb.conf: 11: Syntax error: "}" unexpected

I implemented the command with the Icinga Director.

Can anybody tell me why it can not interpret the file? Or did I maybe put the Check-Command object at the wrong spot?

Some more information:

This is the definition of the Command in the Director

This would be the preview of it:

object CheckCommand "vSphere Unsolved" {
    import "plugin-check-command"
    command = [ PluginDir + "/icingacli-vspheredb" ]
    arguments += {
        "--name" = "$host.address$"
    }
}

Is anything else needed?

Yes.
At first you need the correct command. icinga-vspheredb in PluginDir is not correct, unless you made a link to the binary
This is the base command that is needed:
command = [ "/usr/bin/icingacli", "vspheredb", "check" ]
then you need another datafield as the first parameter without argument and at the first position where you specify what to check (host, vm, datastore)

Check the coammnd on the CLI to see what you can do and need.

1 Like

I now finally understand where to out the command. I just never got around to think that it needs to be in the commands.conf. I stupidly defined it as a own file and tested some stuff there.
But with the director in place the commands.conf file just gets overwritten. How did you avoid that? And how did you get the director to recognize the new command in the commands.conf? If I run the Kickstart Wizard nothing will change.

You should decide how you want to manage your config.
Though you could mix both I suggest if you use the Director, use it for everything.

A reason why there is no change after running the kickstart wizard could be that the inclusion of the /etc/icinga2/conf.d directory is disabled in the icinga2.conf file, as the conf.d directory only hold some basic config examples.
If you want to use config files with the director either put them under zones.d with a separate subfolder for every zone, or put them anywhere you want and enable the inclusion of that directory in the icinga2.conf

The config file naming doesn’t matter really. You could put all your configuration in one single file called myconfig.conf. The separation by object type/zone/whatever is just to make it easier to work with.

Some light reading regarding the config topics
https://icinga.com/docs/icinga-2/latest/doc/04-configuration/
https://icinga.com/docs/icinga-director/latest/doc/10-How-it-works/

1 Like

Thank you very much. I much more understand the whole thing now. Still quite new to icinga and only as an intern setting the whole thing up is quite much.

The only problem left (hopefully) now is that it will run into this php-file-issue. Have you encountered it before?

PHP Fatal error:  Uncaught Error: Call to a member function translate() on null in /usr/share/php/Icinga/Application/functions.php:35
Stack trace:
#0 /usr/share/php/Icinga/Application/Config.php(328): t()
#1 /usr/share/php/Icinga/Application/Config.php(397): Icinga\Application\Config::fromIni()
#2 /usr/share/php/Icinga/Application/ApplicationBootstrap.php(589): Icinga\Application\Config::app()
#3 /usr/share/php/Icinga/Application/Cli.php(42): Icinga\Application\ApplicationBootstrap->loadConfig()
#4 /usr/share/php/Icinga/Application/ApplicationBootstrap.php(416): Icinga\Application\Cli->bootstrap()
#5 /usr/bin/icingacli(7): Icinga\Application\ApplicationBootstrap::start()
#6 {main}
  thrown in /usr/share/php/Icinga/Application/functions.php on line 35

Fatal error: Uncaught Error: Call to a member function translate() on null in /usr/share/php/Icinga/Application/functions.php:35
Stack trace:
#0 /usr/share/php/Icinga/Application/Config.php(328): t()
#1 /usr/share/php/Icinga/Application/Config.php(397): Icinga\Application\Config::fromIni()
#2 /usr/share/php/Icinga/Application/ApplicationBootstrap.php(589): Icinga\Application\Config::app()
#3 /usr/share/php/Icinga/Application/Cli.php(42): Icinga\Application\ApplicationBootstrap->loadConfig()
#4 /usr/share/php/Icinga/Application/ApplicationBootstrap.php(416): Icinga\Application\Cli->bootstrap()
#5 /usr/bin/icingacli(7): Icinga\Application\ApplicationBootstrap::start()
#6 {main}
  thrown in /usr/share/php/Icinga/Application/functions.php on line 35

I found this solution but it sadly didn’t bring me any further.

My permissions for the Icingaweb2 are:
drwxrws--x 4 www-data icingaweb2 4096 13. Jan 08:30 icingaweb2

When do you get this error?

I added the command to the hosts. I imported the vSphere hosts through the automation tool and added a service group with this service to them.
My command looks like this:

object CheckCommand "vSphere unsolved" {
    import "plugin-check-command"
    command = [ "/usr/bin/icingacli", "vspheredb", "check" ]
    timeout = 1m
    arguments += {
        "(no key)" = {
            order = 1
            required = true
            skip_key = true
            value = "host" // we only check hosts
        }
        "--name" = {
            order = 2
            required = false
            value = "$host.address$"
        }
        "--perfdata" = {
            order = 3
            required = false
            set_if = "$vspheredb_perfdata$"
        }
    }
}

I immediately got this error on the dashboard for all the checks.

I have everything with php that is needed and we restarted the apache. But no use so we commented out the problematic line:35 in the /usr/share/php/Icinga/Application/functions.php file. And got a (I think) more useful error in the dashboard:

Icinga\Exception\IcingaException in /usr/share/php/Icinga/Application/ApplicationBootstrap.php:591 with message: Cannot load application configuration. An exception was thrown: <- Icinga\Exception\NotReadableError in /usr/share/php/Icinga/Application/Config.php:328 with message:
Icinga\Exception\IcingaException in /usr/share/php/Icinga/Application/ApplicationBootstrap.php:662 with message: Cannot load user backend configuration. An exception was thrown: <- Icinga\Exception\NotReadableError in /usr/share/php/Icinga/Application/Config.php:328 with message: 
ERROR: Cannot read enabled modules. Config directory "/etc/icingaweb2" is not readable

check if all files and folders inside /etc/icingaweb2 have the correct permissions for the icingaweb2 group.
As an example (keep in mind that this system is a centos, so apache = www-data from your debian/ubuntu system)

]# pwd
/etc/icingaweb2
# ls -la
total 28
drwxrws---.   4 root   icingaweb2  125 Nov 18 12:06 .
drwxr-xr-x. 105 root   root       8192 Jan  5 15:40 ..
-rw-r--r--.   1 apache icingaweb2  108 Mar 16  2021 authentication.ini
-rw-r--r--.   1 apache icingaweb2  209 Mar 16  2021 config.ini
drwxr-s---.   2 apache icingaweb2   87 Mar 16  2021 enabledModules
drwxrws---.   6 root   icingaweb2   72 Nov 18 12:06 modules
-rw-r--r--.   1 apache icingaweb2  522 Mar 16  2021 resources.ini
-rw-r--r--.   1 apache icingaweb2   79 Mar 16  2021 roles.ini

Looks the same here

drwxrws--x   4 root     icingaweb2 4096 13. Jan 08:30 .
drwxr-xr-x 103 root     root       4096  3. Mär 10:52 ..
-rw-rw----   1 www-data icingaweb2  154 13. Jan 08:24 authentication.ini
-rw-rw----   1 www-data icingaweb2  212 11. Jan 10:35 config.ini
drwxr-s---   2 www-data icingaweb2 4096 18. Feb 08:23 enabledModules
-rw-rw----   1 www-data icingaweb2   58 11. Jan 10:35 groups.ini
drwxrws---   9 root     icingaweb2 4096 18. Feb 08:23 modules
-rw-rw----   1 www-data icingaweb2 1036 10. Feb 10:51 resources.ini
-rw-rw----   1 www-data icingaweb2  290 13. Jan 08:30 roles.ini

except that most my folders also have writing enabled

try restarting all icinga-related services

  • icinga2
  • icinga-director
  • icinga-vspheredb (if you installed the vspheredb module)
  • apache2 (or nginx, whichever you use)

Also double check that all required php libraries are installed

Edit: after fiddling with this with the entire team we decided we would create an issue on the github repository

Checked both of them now. Nothing is missing, also checked with some colleagues. But I probably found another lead.
The function that it can’t get in line 35:

is the translation function called StaticTranslator. This function is inside the incubator module. I reinstalled, disabled and enabled it but there is still no use to it. But it might be a lead at least.

I got to the idea from another similar problem:

I still find that strange…
Below is a list of all php packages installed in my ubuntu 20.04.4 test setup:

# dpkg -l | grep php|sort
ii  icinga-php-common                    1.0.0-1.focal                     all          Icinga PHP Common for Icinga Web 2
ii  icinga-php-library                   0.7.0-1.focal                     all          Icinga PHP Library for Icinga Web 2
ii  icinga-php-thirdparty                0.10.0-2.focal                    all          Icinga PHP Thirdparty for Icinga Web 2
ii  libapache2-mod-php7.4                7.4.3-4ubuntu2.10                 amd64        server-side, HTML-embedded scripting language (Apache 2 module)
ii  php                                  2:7.4+75                          all          server-side, HTML-embedded scripting language (default)
ii  php-common                           2:75                              all          Common files for PHP packages
ii  php-curl                             2:7.4+75                          all          CURL module for PHP [default]
ii  php-gd                               2:7.4+75                          all          GD module for PHP [default]
ii  php-icinga                           2.9.6-1.focal                     all          PHP library to communicate with and use Icinga
ii  php-imagick                          3.4.4-4                           amd64        Provides a wrapper to the ImageMagick library
ii  php-intl                             2:7.4+75                          all          Internationalisation module for PHP [default]
ii  php-ldap                             2:7.4+75                          all          LDAP module for PHP [default]
ii  php-mbstring                         2:7.4+75                          all          MBSTRING module for PHP [default]
ii  php-mysql                            2:7.4+75                          all          MySQL module for PHP [default]
ii  php-soap                             2:7.4+75                          all          SOAP module for PHP [default]
ii  php-xml                              2:7.4+75                          all          DOM, SimpleXML, WDDX, XML, and XSL module for PHP [default]
ii  php-yaml                             2.0.4+1.3.2-2build1               amd64        YAML-1.1 parser and emitter for PHP
ii  php-zip                              2:7.4+75                          all          Zip module for PHP [default]
ii  php7.4                               7.4.3-4ubuntu2.10                 all          server-side, HTML-embedded scripting language (metapackage)
ii  php7.4-cli                           7.4.3-4ubuntu2.10                 amd64        command-line interpreter for the PHP scripting language
ii  php7.4-common                        7.4.3-4ubuntu2.10                 amd64        documentation, examples and common module for PHP
ii  php7.4-curl                          7.4.3-4ubuntu2.10                 amd64        CURL module for PHP
ii  php7.4-gd                            7.4.3-4ubuntu2.10                 amd64        GD module for PHP
ii  php7.4-intl                          7.4.3-4ubuntu2.10                 amd64        Internationalisation module for PHP
ii  php7.4-json                          7.4.3-4ubuntu2.10                 amd64        JSON module for PHP
ii  php7.4-ldap                          7.4.3-4ubuntu2.10                 amd64        LDAP module for PHP
ii  php7.4-mbstring                      7.4.3-4ubuntu2.10                 amd64        MBSTRING module for PHP
ii  php7.4-mysql                         7.4.3-4ubuntu2.10                 amd64        MySQL module for PHP
ii  php7.4-opcache                       7.4.3-4ubuntu2.10                 amd64        Zend OpCache module for PHP
ii  php7.4-readline                      7.4.3-4ubuntu2.10                 amd64        readline module for PHP
ii  php7.4-soap                          7.4.3-4ubuntu2.10                 amd64        SOAP module for PHP
ii  php7.4-xml                           7.4.3-4ubuntu2.10                 amd64        DOM, SimpleXML, XML, and XSL module for PHP
ii  php7.4-zip                           7.4.3-4ubuntu2.10                 amd64        Zip module for PHP

Compare them to what you got, though some might not be needed as I got the graphite, fileshipper and icingadb modules running as well.
If you got them all, the permissions on the /etc/icingaweb2 folder are correct and all required icinga modules are there, I am out of ideas where to look atm.

1 Like

I checked all the php-modules that are listed here and they are all there. So I don’t think a dependency is missing. I don’t really know either where else to check now.
The only thing I did differently from your solution in the original post is that the value of no key is set to host. I wouldn’t think that should be bothersome since the icingacli check host ... works fine.

The config I’m speaking of:

But if I set it to $vspheredb_check_mode$ I get this error in the Icingaweb2 anyways:

Error: Non-optional macro 'vspheredb_check_mode' used in argument '(no key)' is missing.
Context:

	(0) Executing check for object
'secretvm.name.de!vSphere Unsolved'

That is to be expected. For that to work you would need to create that data field and then fill it when applying the check to a host object.

Can you tell (or show) again where and when exactly you get that PHP error?
What actions are you taking before getting it.

Alright that makes a lot of sense.

I get the PHP error on this part of the php file /usr/share/php/Icinga/Application/functions.php:

  GNU nano 5.4                                   /usr/share/php/Icinga/Application/functions.php                                            
<?php
/* Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */

use ipl\Stdlib\Contract\Translator;
use ipl\I18n\StaticTranslator;

/**
 * No-op translate
 *
 * Supposed to be used for marking a string as available for translation without actually translating it immediately.
 * The returned string is the one given in the input. This does only work with the standard gettext macros t() and mt().
 *
 * @param   string  $messageId
 *
 * @return  string
 */
function N_($messageId)
{
    return $messageId;
}

// Workaround for test issues, this is required unless our tests are able to
// accomplish "real" bootstrapping
if (function_exists('t')) {
    return;
}

if (extension_loaded('gettext')) {

    /**
     * @see Translator::translate() For the function documentation.
     */
    function t($messageId, $context = null)
    {
// 
//  THIS IS LINE 35
//
        return StaticTranslator::$instance->translate($messageId, $context);
    }

    /**
     * @see Translator::translateInDomain() For the function documentation.
     */
    function mt($domain, $messageId, $context = null)
    {
        return StaticTranslator::$instance->translateInDomain($domain, $messageId, $context);
    }

    /**
     * @see Translator::translatePlural() For the function documentation.
     */
    function tp($messageId, $messageId2, $number, $context = null)
    {
        return StaticTranslator::$instance->translatePlural($messageId, $messageId2, $number, $context);
    }

    /**
     * @see Translator::translatePluralInDomain() For the function documentation.
     */
    function mtp($domain, $messageId, $messageId2, $number, $context = null)
    {
        return StaticTranslator::$instance->translatePluralInDomain(
            $domain,
            $messageId,
            $messageId2,
            $number,
            $context
        );
    }

Before this I have had installed VMware like this and so on. I’m working with the director as you know. For this Check I used the Directors Automation tool to create all the VMware hosts in the director. All of them basically look like this:

object Host "vm.intern.de" {
    import "ESXi"

    address = "vm.intern.de"
    check_command = "ping4"
}

Then I created the file myconfig.conf inside of /etc/icinga2/. In this conf is this:

After that I run the Director Kickstarter. And made a Service Template for the Check. I set this Service into a Service Group for the VMware hosts and let the check run. That check had this output first:

After working on it with my colleagues we decided to figure out what would happen if we comment line 35 out. And replace it with return ""; And it gave us this error

So we gave more permissions to that folder. And that also returned an similar error with not being able to read the folder one below: /etc/icingaweb2/enabled-modules. So in return we gave this folder more permissions but now it just returns an [UNKNOWN].

We commented the line 35 back in after that.

Do you need any more information?

Why do you create a config file when you are using the Director anyway?

Ok. So it is the output of the check itself, nothing from the web interface.

What output do you get if you restore the file to its original state?

How does you commandline executed by icinga look like?
You can see that be checking the ‘Inspect’ link in the webinterface of the service

When using the director to create the command I couldn’t figure out how to set the command to a different directory. The standard is the PluginDir.
Also you suggested it here:

Yea right the output itself. Just wanted to say where I got it from. Sorry

It goes back to the error at line 35 like before.

Thank you for showing me this feature. Never seen it before! :slight_smile:

'/usr/bin/icingacli' 'vspheredb' 'check' 'host' '--name' 'vm.intern.somewhere.de'

This is what I’d get if I try it on the master:

root@ism-icinga-01:/etc/icinga2# '/usr/bin/icingacli' 'vspheredb' 'check' 'host' '--name' 'vm.intern.somewhere.de'
Overall status is "green"

And this is the service in the zones.d/director-global/servicesets.conf:185 as pointed to in the screenshot:

apply Service "vSphere Unsolved" {
    import "vSphere Unsolved"

    assign where "ESXi" in host.groups

    import DirectorOverrideTemplate
}

Simply put the whole path in there, e.g. /usr/bin/icingacli or for a sub folder of PluginDir put PluginDir + /my/sub/folder/script.py

Can you run the check on the cli with the user running the icinga service please?
Put sudo -u username in front of the inspected command (replace username with nagios if Debian/Ubuntu or icinga if centOS/RHEL/SUSE)