API Bug? Cannot update device location attribute via API

Hi…

I am having trouble updating the ‘location’ field of a device using the update_device_field API call. This used to work, but it has been a while since I added new devices, and so I haven’t needed to update a device’s location in a while either.

Having done a little searching I have seen mention of similar issues elsewhere on the community forums but no solution…for example:

I have tried to troubleshoot this as far as I can, and it appears that trying to update the location field by the API call fails (see log output below) but it works just fine if I update the location via ‘Device Settings’ in the WebUI.

As far as I can tell everything is up to date…at least validate.php seems to think so:

-bash-4.2$ ./validate.php
====================================
Component | Version
--------- | -------
LibreNMS  | 1.57-14-g7bb5f22
DB Schema | 2019_02_05_140857_remove_config_definition_from_db (145)
PHP       | 7.2.13
MySQL     | 5.5.56-MariaDB
RRDTool   | 1.4.8
SNMP      | NET-SNMP 5.7.2
====================================

[OK]    Composer Version: 1.9.1
[OK]    Dependencies up-to-date.
[OK]    Database connection successful
[OK]    Database schema correct

When I run the following curl command to update the location field, it does say it worked, but it never updates the field:

-bash-4.2$ curl -X PATCH -d '{"field": ["location"], "data": ["Timbuktu, [16.7666, 3.0026]"]}' -H 'X-Auth-Token: 6da3sometoken6dasometoken6dasome' http://mylibrenms/api/v0/devices/some_network_switch
{
    "status": "ok",
    "message": "Device fields have been updated"
}

…and I get the following in the librenms.log file:

[2019-11-04 14:53:39] production.ERROR: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'location' in 'field list' (SQL: UPDATE `devices` set `location`=Timbuktu, [16.7666, 3.0026] WHERE `device_id`=228) (SQL: UPDATE `devices` set `location`=Timbuktu, [16.7666, 3.0026] WHERE `device_id`=228)#0 /opt/librenms/includes/html/api_functions.inc.php(1652): dbUpdate(Array, 'devices', '`device_id`=?', Array)
#1 [internal function]: update_device(Object(Illuminate\Http\Request), 'some_network_switch')
#2 /opt/librenms/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array('update_device', Array)
#3 /opt/librenms/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(78): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#4 /opt/librenms/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::callBoundMethod(Object(App\Application), 'update_device', Object(Closure))
#5 /opt/librenms/vendor/laravel/framework/src/Illuminate/Container/Container.php(576): Illuminate\Container\BoundMethod::call(Object(App\Application), 'update_device', Array, NULL)
#6 /opt/librenms/app/Api/Controllers/LegacyApiController.php(43): Illuminate\Container\Container->call('update_device', Array)
#7 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(48): App\Api\Controllers\LegacyApiController->__call('update_device', Array)
#8 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Route.php(219): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(App\Api\Controllers\LegacyApiController), 'update_device')
#9 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Route.php(176): Illuminate\Routing\Route->runController()
#10 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Router.php(680): Illuminate\Routing\Route->run()
#11 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#12 /opt/librenms/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authorize.php(45): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#13 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\Auth\Middleware\Authorize->handle(Object(Illuminate\Http\Request), Object(Closure), 'admin')
#14 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#15 /opt/librenms/vendor/spatie/laravel-cors/src/Cors.php(28): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#16 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Spatie\Cors\Cors->handle(Object(Illuminate\Http\Request), Object(Closure))
#17 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#18 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#19 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
#20 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#21 /opt/librenms/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(43): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#22 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\Auth\Middleware\Authenticate->handle(Object(Illuminate\Http\Request), Object(Closure), 'token')
#23 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#24 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#25 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Router.php(682): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#26 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Router.php(657): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#27 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Router.php(623): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route))
#28 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Router.php(612): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#29 /opt/librenms/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#30 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#31 /opt/librenms/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#32 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Fideloper\Proxy\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure))
#33 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#34 /opt/librenms/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#35 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#36 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#37 /opt/librenms/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#38 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#39 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#40 /opt/librenms/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#41 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure))
#42 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#43 /opt/librenms/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(62): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#44 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(163): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#45 /opt/librenms/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#46 /opt/librenms/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#47 /opt/librenms/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#48 /opt/librenms/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#49 /opt/librenms/html/api_v0.php(55): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#50 {main}

However, if I update the device location under ‘Device Settings’ in the WebUI, it does update the field:

-bash-4.2$ curl -H 'X-Auth-Token: 6da3sometoken6dasometoken6dasome' http://mylibrenms/api/v0/devices/some_network_switch
{
    "status": "ok",
    "devices": [
        {
            "device_id": 8,
            "hostname": "some_network_switch",
                     :
                     :
                     :
            "override_sysLocation": 1,
            "notes": null,
            "port_association_mode": 1,
            "max_depth": 0,
            "location": "Timbuktu, [16.7666, 3.0026]",
            "lat": 16.7666,
            "lng": 3.0026000000000002,
            "attribs": []
        }
    ],
    "count": 1

Might this be a bug in the API?

Would be grateful for any help.

Cacheman.

1 Like

I’m having the same issue and it definitely looks like a bug :frowning:

‘location’ is not a valid field for the devices table. location_id is. So you would need to retrieve the location_id from the “Locations” table first, and then update the “location_id” for the device.

From Here:
image it states the field must match one in the database.

MariaDB [librenms]> describe devices;
...
location_id               | int(10) unsigned
...

Furthermore, there is a locations table,
image

So just my 2c.
Not sure why the API returned 200 OK though.

Try setting location_id, does that work?

Yeah! Fixed! Thanks a million!