netbox-community / go-netbox

The official Go API client for Netbox IPAM and DCIM service.
Other
199 stars 157 forks source link

Creating Manufacture errors out because of missing required property devicetype_count #165

Open rogerscuall opened 10 months ago

rogerscuall commented 10 months ago

I'm trying to create a manufacturer like this:

man := n.NewManufacturerRequestWithDefaults()
man.Name = "somename"
man.Slug = "someslug"
resp, _, err := nb.DcimAPI.DcimManufacturersCreate(context.Background()).ManufacturerRequest(manu).Execute()

I get this error:

panic: failed to create manufacturer somename: no value given for required property devicetype_count

I can see how devicetype_count is required for a Manufacturer but not for a ManafacturerRequest. At the same time, the Manufacture is created, but the Execute returns an error.

jqueuniet commented 9 months ago

As the manufacturer is created, this is likely to be a deserialization error from the API response rather than a server error during the creation.

Could you mention what version Netbox you're using? Sadly, Netbox does not offer much in the way of API stability guarantees, and Netbox clients versions need to remain tightly coupled with the server version, otherwise this kind of error is likely to show up.

rogerscuall commented 9 months ago

Yes, 3.7.1 after it was created with goswagger. It also happens to generate DeviceType, DeviceRole, and Site. In line 107803 of the openapi.yaml file, devicetype_count is defined for the Manufacturer, and then, in 107814, is indeed ratified as required.

jacobsalmela commented 9 months ago

Does devicetype_count need to be under AdditionalProperties or CustomFields? I tried both to no avail.

In my case, the API returns 201 and the manufacturer is still created in netbox, so I just bypass that error for now.

rogerscuall commented 9 months ago

I don't know. This is what I see:

Code ### Code from openapi.yaml ```yaml Manufacturer: type: object description: Adds support for custom fields and tags. properties: id: type: integer readOnly: true url: type: string format: uri readOnly: true display: type: string readOnly: true name: type: string maxLength: 100 slug: type: string maxLength: 100 pattern: ^[-a-zA-Z0-9_]+$ description: type: string maxLength: 200 tags: type: array items: $ref: '#/components/schemas/NestedTag' custom_fields: type: object additionalProperties: {} created: type: string format: date-time readOnly: true nullable: true last_updated: type: string format: date-time readOnly: true nullable: true devicetype_count: type: integer readOnly: true inventoryitem_count: type: integer readOnly: true platform_count: type: integer readOnly: true required: - created - devicetype_count - display - id - inventoryitem_count - last_updated - name - platform_count - slug - url ManufacturerRequest: type: object description: Adds support for custom fields and tags. properties: name: type: string minLength: 1 maxLength: 100 slug: type: string minLength: 1 maxLength: 100 pattern: ^[-a-zA-Z0-9_]+$ description: type: string maxLength: 200 tags: type: array items: $ref: '#/components/schemas/NestedTagRequest' custom_fields: type: object additionalProperties: {} required: - name - slug ```

The Manufacturer requires devicetype_count, but the ManufacturerRequest does not. The same goes for DeviceType, DeviceRole, and Site and the Request counterpart. Yeah, I'm doing the same, ignoring the error for now. @jacobsalmela, you pointed out something I did not notice; I was so far ignoring the *http.Response from the Execute because it was contained inside the error, but as you said, it is returning 201. What may be related to @jqueuniet comment about the deserialization of API response is making up this error.

jqueuniet commented 8 months ago

I had some time to look into this issue this morning, and managed to reproduce it creating a device role with a Netbox 3.7.3 server and the current alpha release of the client (v3.7.1-alpha.0).

Reproduction code is as follows:

req := netbox.NewWritableDeviceRoleRequestWithDefaults()
req.SetName("test-role")
req.SetSlug("test-role")

result, resp, err := c.Netbox.
    DcimAPI.
    DcimDeviceRolesCreate(ctx).
    WritableDeviceRoleRequest(*req).
    Execute()

The error returned is no value given for required property device_count.

The list of broken endpoints this far is as follows:

I found a similar issue on the Netbox project for the tenancy/tenants endpoint, and mentioned the current status of this issue.

https://github.com/netbox-community/netbox/issues/14953

jqueuniet commented 6 months ago

Upstream issue is now closed and released as part of 4.0.3

riptidewave93 commented 5 months ago

fwiw it seems this is also broken for dcim/devices. Seeing this myself when using DcimAPI.DcimDevicesList

In my case it may be due to the older version of netbox being used, I downgraded to go-netbox/v3 to fix my issues.

rogerscuall commented 5 months ago

Yeah is affecting everything endpoint or resource I have tried so far.

fxedel commented 5 months ago

Still have the issue when creating device roles:

roleRequest := netbox.NewDeviceRoleRequest("Default device role", "default")
req := r.client.DcimAPI.DcimDeviceRolesCreate(ctx)
req = req.DeviceRoleRequest(roleRequest)
created, _, err = req.Execute()

yields error "no value given for required property device_count"

Client version: v4.0.3-0 Server version: b4c286f67cba (v4.0.5)

When calling the Server API manually (POST /api/dcim/device-roles/), I can see that there is no device_count field in the response, whereas the client model expects one.

EDIT:

Minimal example to reproduce the error:

_, _, err := client.DcimAPI.DcimDeviceTypesList(context.Background()).Execute()

yields error "no value given for required property devicetype_count"

The failure reason in this case is that the device type list includes a manufacturer model for each device type model, but the manufacturer model does not contain the full manufacturer data; in particular, it misses the devicetype_count property (which is present when querying manufacturers directly).

ZionDials commented 2 weeks ago

The reason this problem exists, even with the latest version, is due to the following generated code:

func (o *BriefManufacturer) UnmarshalJSON(data []byte) (err error) {
    // This validates that all required properties are included in the JSON object
    // by unmarshalling the object into a generic map with string keys and checking
    // that every required field exists as a key in the generic map.
    requiredProperties := []string{
        "id",
        "url",
        "display",
        "name",
        "slug",
        "devicetype_count",
    }

If you remove "devicetype_count" the requests will work as expected. This appears to be an issue with Netbox. When you query, it provides a Brief Manufacturer information to the request, however, it's not populating the required "devicetype_count" field, here's an example:

            "manufacturer": {
                "id": 47,
                "url": "https://netbox.xxx.com/api/dcim/manufacturers/47/",
                "display": "A10",
                "name": "A10",
                "slug": "a10",
                "description": ""
            },

Note "devicetype_count" is absent.