ArnesSI / netbox-inventory

Manage your hardware inventory in NetBox
MIT License
191 stars 16 forks source link

Need some help for understanding an API call in error #132

Closed GuiliSab closed 6 months ago

GuiliSab commented 9 months ago

Hello,

I'm trying importing 18K assets linked on inventory items. It works for 17K but some of them failed with this error (I print the content of HTTP call):

string 'value too long for type character varying(50)' (length=45)
string 'DataError' (length=9)
string '3.6.2' (length=5)
1023:string '3.9.16' (length=6)

I send this json on the endpoint "POST", '/api/plugins/inventory/assets/':

array (size=9)
  'name' => string 'LPe12002-E fc8 Double port 8Gbits/s Fiber Cha' (length=45)
  'serial' => string 'XXXXXXXXXX' (length=10)
  'status' => string 'used' (length=4)
  'custom_fields' => 
    array (size=1)
      'id_composant_asset' => int 29874
  'tenant' => int 113
  'delivery' => int 2440
  'warranty_start' => string '2014-12-19' (length=10)
  'inventoryitem_type' => int 449
  'inventoryitem' => int 210

I don't understand why it fails. I limit the name field to 45 chars. What field must be limitied by 50 characters ? The endpoint try to insert another thing ?

Thank you for your help.

cs-1 commented 9 months ago

Have you tried doing a POST of this data in the Swagger interface ("API Documentation") of NetBox? I tried it and didn't have any issues (I needed to change some numeric IDs but nothing else). What code / tools do you use to post this to the API?

GuiliSab commented 9 months ago

I tried just right now to use the swagger and have the same result:

curl -X 'POST' \
  'http://x.x.x.x/api/plugins/inventory/assets/' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'X-CSRFTOKEN: blablabla' \
  -d '{
  "name": "LPe12002-E fc8 Double port 8Gbits/s Fiber Cha",
  "serial": "XXXXXXXXXX",
  "status": "used",
  "inventoryitem_type": 449,
  "inventoryitem": 210,
  "tenant": 113,
  "delivery": 2440,
  "warranty_start": "2014-12-19",
  "custom_fields": {
    "id_composant_asset": 29874
  }
}'

{
  "error": "value too long for type character varying(50)",
  "exception": "DataError",
  "netbox_version": "3.6.2",
  "python_version": "3.9.16"
}

api-version: 3.6 
 connection: keep-alive 
 content-length: 139 
 content-type: application/json 
 cross-origin-opener-policy: same-origin 
 date: Wed,27 Sep 2023 09:53:02 GMT 
 referrer-policy: same-origin 
 server: nginx/1.20.1 
 vary: HX-Request,Cookie,origin 
 x-content-type-options: nosniff 
 x-frame-options: SAMEORIGIN 
 x-request-id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

The swagger uses a curl request. I talk to the API in PHP with thebundle HttpClient (used by Symfony)... which used curl under the bundle.

In this case, the inventory item type and inventory items exists, so I don't think it tries to create something. But the error seems to come from a "type" field limited by 50 characters. I'm trying to search in the database what field it can be but i'm a little lost.

cs-1 commented 9 months ago

Have you tried creating the asset on NetBox's "nbshell" on the CLI? This very likely gives you more detailed messages. See: https://netbox.rz.tu-clausthal.de/static/docs/administration/netbox-shell/ Warning: You can definitely break things in nbshell so be careful or try on a staging system.

If nbshell is no option, try looking looking at both at the inventory_item with ID 210 and at the inventory_item_type with ID 449 and try finding any strings >45. Maybe that's the problem here. Meanwhile I'll have a look at the models for both, maybe there's a discrepancy in expected string lengths.

GuiliSab commented 9 months ago

InventoryItem_Type "model" field: LPe12002-E fc8 Double port 8Gbits/s Fiber Channel - LOW profile InventoryItem "name" field: LPe12002-E fc8 Double port 8Gbits/s Fiber Channel - LOW profile

Both are > 50

When I only rename the InventoryItem_Type "model" field to fit under 50 characters, everything is working. Do I need to rename all my InventoryItem_Type model field ? Or is there a problem in the call to be corrected ?

Anyway, thanks for your help, I was becoming crazy :)

cs-1 commented 9 months ago

@matejv This looks like a bug. It seems like the model in netbox-inventory has a shorter character length than the netbox internal model. I might be mistaken but this is what I reckon.

matejv commented 9 months ago

We have the following fields involved in this:

plugin model field max_length
netbox_inventory inventoryitem_type model 100 chars (mandatory)
netbox_inventory inventoryitem_type part_number 50 chars (optional)
netbox core inventoryitem part_id 50 chars (optional)
netbox core inventoryitem name 64 chars (required)

When you assign netbox_inventory asset to netbox inventory item, the plugin populates some fields of inventoryitem, including part_id. By default it uses inventoryitem_type.part_number but if this field is blank it uses inventoryitem_type.model. See this line. If it happens that inventoryitem_type.part_number is not set and inventoryitem_type.model is longer than 50 chars this bug occurs.

It is also reproducible via GUI (if you try to use "Create inventory item" from asset detail view).

There are 2 ways I could solve this when assigning asset to inventoryitem:

  1. when setting inventoryitem.part_id only use inventoryitem_type.part_number. If it's empty leave part_id empty as well.
  2. when setting inventoryitem.part_id use inventoryitem_type.part_number first. It that's empty use only first 50 chars of inventoryitem_type.model.

Let me know which way you'd prefer to resolve this. I'm inclined to use method 2.

I've checked our installation - we set model and part_number fields for all our inventoryitem_types. Also all our values are way shorter than 50 chars so we've not seen this bug.

GuiliSab commented 9 months ago

Hi, Thank you for your response. I think the use of 50 firsts characters is not a valid solution, because in my case it doesn't work.

In my actual inventory, users have created two component types:

If you take only the first 50 characters (LPe12002-E fc8 Double port 8Gbits/s Fiber Channel), it's becoming the same value, but they are two different types.

My solution was to check all types > 50 characters and rename one per one. It fixes my problem.