unistra / python-glpi-api

Python module for interacting with GLPI using the API.
GNU General Public License v3.0
18 stars 10 forks source link

ERROR_BAD_ARRAY when updating #20

Closed ruivit closed 8 months ago

ruivit commented 10 months ago

Hello everyone.

I can't seem to update items no matter what input I give.

try:
    with glpi_api.connect(URL, APPTOKEN, USERTOKEN, verify_certs=False) as glpi:
        print(glpi.update('Computer', [{'id': 108, 'name': "test server1"}]))

        print(glpi.update('Computer', {'id': 108, 'name': "test server1"}))

except glpi_api.GLPIError as err:
    print(str(err))

I've even tried to create a request myself in which I get 200 OK but no message, nor the item is updated. `def update_location(self, computer_id, location_id): print("Updating location for computer id:", computer_id)

-d '{"input": {"id": 11, "otherserial": "abcde"}}' \

    json_data = '{"input": {"id": ' + str(computer_id) + ', "locations_id": ' + str(location_id) + '}}'

    response = self.session.put(url=self._update_computer_url(),
                                data=json_data,
                                verify=self.verify_certs)

    print("Status code:", response.status_code)

    return response

Any help will be appreciated.

fmenabe commented 10 months ago

Hello,

You don't use the update method correctly (cf https://di.pages.unistra.fr/glpi/python-glpi-api/#glpi_api.GLPI.update). It does not take just two parameters, the second parameter being a list, but as many objects to update as parameters:

glpi.update('Computer', {'id': 1, 'name': 'test'}, {'id': 2, 'name': 'test2'})

(see this for the Python explanation)

In your exemple, the first update is incorrect and the second update will never be executed as the exception will be raised and catched by the first update.

As for trying to use requests directly, it should works (if the requests is formatted as expected by the API). I spawn a new GLPI instance with Docker (see this gist) and make some tests without errors (using iPython):

In [22]: glpi.add('Computer', {'name': 'test'})
Out[22]: [{'id': 2, 'message': 'Item successfully added: test'}]

In [23]: glpi.get_item('Computer', 2)['name']
Out[23]: 'test'

In [24]: glpi.update('Computer', {'id': 2, 'name': 'test2'})
Out[24]: [{'2': True, 'message': ''}]

In [25]: glpi.get_item('Computer', 2)['name']
Out[25]: 'test2'

In [28]: glpi.update('Computer', {'id': 1, 'name': 'test3'}, {'id': 2, 'name': 'test3'})
Out[28]: [{'1': True, 'message': ''}, {'2': True, 'message': ''}]

In [29]: glpi.get_item('Computer', 2)['name']
Out[29]: 'test3'

In [30]: glpi.add('Location', {'name': 'test'})
Out[30]: [{'id': 1, 'message': 'Item successfully added: test'}]

In [34]: glpi.update('Computer', {'id': 2, 'locations_id': 1})
Out[34]: [{'2': True, 'message': ''}]

In [35]: glpi.get_item('Computer', 2)['locations_id']
Out[35]: 1

(You cast the ids to string but the API may actually expects integers)