Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Director 1.9.0 API - GET director/service?name=... returns Call to a member function toString() on null (Http code 500) #2487

Closed
axelhahn opened this issue Mar 8, 2022 · 8 comments
Assignees
Labels
Milestone

Comments

@axelhahn
Copy link

axelhahn commented Mar 8, 2022

Expected Behavior

Using director API with a GET to https://icinga2.example.com/icingaweb2/director/service?name=service-template_for_command returns a valid response.

Current Behavior

We updated our Icingaweb2 instance and our modules. With update to Director 1.7 --> 1.9 I get HTTP status code 500.

Uncaught Error: Call to a member function toString() on null in /usr/share/icingaweb2/modules/director/application/controllers/ServiceController.php:254
Stack trace:
#0 /usr/share/icingaweb2/modules/director/library/Director/Web/Controller/ObjectController.php(497): Icinga\Module\Director\Controllers\ServiceController->loadObject()
#1 /usr/share/icingaweb2/modules/director/library/Director/Web/Controller/ObjectController.php(90): Icinga\Module\Director\Web\Controller\ObjectController->loadOptionalObject()
#2 /usr/share/icingaweb2/modules/director/application/controllers/ServiceController.php(46): Icinga\Module\Director\Web\Controller\ObjectController->init()
#3 /usr/share/php/Icinga/Web/Controller/ActionController.php(165): Icinga\Module\Director\Controllers\ServiceController->init()
#4 /usr/share/php/Icinga/Web/Controller/Dispatcher.php(59): Icinga\Web\Controller\ActionController->__construct()
#5 /usr/share/icingaweb2/library/vendor/Zend/Controller/Front.php(937): Icinga\Web\Controller\Dispatcher->dispatch()
#6 /usr/share/php/Icinga/Application/Web.php(304): Zend_Controller_Front->dispatch()
#7 /usr/share/php/Icinga/Application/webrouter.php(107): Icinga\Application\Web->dispatch()
#8 /usr/share/icingaweb2/public/index.php(4): require_once('...')
#9 {main}
thrown

Possible Solution

/usr/share/icingaweb2/modules/director/application/controllers/ServiceController.php
loadObject loads the object from table icinga_service by filtering object_type='object'. But the service template is object_type='template'. The $uuid is empty and $uuid->toString() fails.
I stupidly added:

...
    protected function loadObject()
    {
        if ($this->params->has('uuid')) {
            parent::loadObject();
            return;
        }

        $key = $this->getLegacyKey();
        $uuid = UuidLookup::findServiceUuid($this->db(), $this->getBranch(), 'object', $key, $this->host, $this->set);

        // --- HOT FIX: search for type template too
        if(is_null($uuid)){
                $uuid = UuidLookup::findServiceUuid($this->db(), $this->getBranch(), 'template', $key, $this->host, $this->set);
        }
        // --- /FIX

        $this->params->set('uuid', $uuid->toString());
        parent::loadObject();
    }
...

It works for me but is not a clean solution.
Maybe the problem is the database update and service templates need to be object_type='object'??

Steps to Reproduce (for bugs)

GET to https://icinga2.example.com/icingaweb2/director/service?name=service-template_for_command

Your Environment

  • Director version (System - About): 1.9.0
  • Icinga Web 2 version and modules (System - About):2.9.5
  • Icinga 2 version (icinga2 --version): 2.13.2-1)
  • Operating System and version: Centos 8 stream
  • Webserver, PHP versions: apache httpd 2.4.37; PHP 8.0.13 using PHP FPM service
@axelhahn axelhahn changed the title Bug: Director API - GET director/service?name=... returns Call to a member function toString() on null (Http code 500) Bug: Director 1.9.0 API - GET director/service?name=... returns Call to a member function toString() on null (Http code 500) Mar 8, 2022
@mwaldmueller
Copy link

+1

@berrnd
Copy link

berrnd commented Mar 20, 2022

I hit the same problem when trying to edit existing service set services (adding new services works).

@axelhahn's hot fix above basically works for me (thanks!), but I noticed that my existing service set services (in table icinga_service) have the object_type apply. Don't know if that's another problem (newly added services get object as object_type).

So changing the hot fix to search for apply services is my currently working workaround:

if(is_null($uuid)){
        $uuid = UuidLookup::findServiceUuid($this->db(), $this->getBranch(), 'apply', $key, $this->host, $this->set);
}

@mdetrano
Copy link
Contributor

Another rough fix could be to check explicitly for host or set params, and switch to template when not present. Also, a 'not found' could be thrown instead of the PHP errors, to make the API respond similarly to other failed object lookups.

$uuid = UuidLookup::findServiceUuid($this->db(), $this->getBranch(), ( ($this->host || $this->set) ? 'object' : 'template'), $key, $this->host, $this->set);
if (!$uuid) throw new \Icinga\Exception\NotFoundError("No such object available");

@mwaldmueller
Copy link

#2487 (comment) solved it in my case

@Thomas-Gelf
Copy link
Contributor

@mwaldmueller: did you tweak the code, or change the type in your DB?

@mwaldmueller
Copy link

@mwaldmueller: did you tweak the code, or change the type in your DB?

I modified the code with this:

        $key = $this->getLegacyKey();
        $uuid = UuidLookup::findServiceUuid($this->db(), $this->getBranch(), 'object', $key, $this->host, $this->set);
+       if(is_null($uuid)){
+               $uuid = UuidLookup::findServiceUuid($this->db(), $this->getBranch(), 'apply', $key, $this->host, $this->set);
+       }
        $this->params->set('uuid', $uuid->toString());
        parent::loadObject();

@Thomas-Gelf
Copy link
Contributor

Thank you!

@mwaldmueller
Copy link

The code modification doesn't work for templates.

@mwaldmueller: did you tweak the code, or change the type in your DB?

I modified the code with this:

        $key = $this->getLegacyKey();
        $uuid = UuidLookup::findServiceUuid($this->db(), $this->getBranch(), 'object', $key, $this->host, $this->set);
+       if(is_null($uuid)){
+               $uuid = UuidLookup::findServiceUuid($this->db(), $this->getBranch(), 'apply', $key, $this->host, $this->set);
+       }
        $this->params->set('uuid', $uuid->toString());
        parent::loadObject();

@Thomas-Gelf Thomas-Gelf self-assigned this Jun 24, 2022
@Thomas-Gelf Thomas-Gelf added this to the 1.10.0 milestone Jun 24, 2022
Thomas-Gelf added a commit that referenced this issue Jun 24, 2022
...when looking up uuid for legacy key

refs #2487
refs #2554
yhabteab pushed a commit that referenced this issue Oct 6, 2022
yhabteab pushed a commit that referenced this issue Oct 6, 2022
...when looking up uuid for legacy key

refs #2487
refs #2554
Thomas-Gelf added a commit that referenced this issue Oct 6, 2022
Thomas-Gelf added a commit that referenced this issue Oct 6, 2022
...when looking up uuid for legacy key

refs #2487
refs #2554
rndmh3ro added a commit to telekom-mms/icinga2-docker that referenced this issue Jul 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants