smutel / terraform-provider-netbox

Terraform provider for Netbox
ISC License
58 stars 19 forks source link

feat: Add suppport for missing customfield types #154

Closed amhn closed 1 year ago

amhn commented 1 year ago

fixes: #153

This PR adds support for missing custom field types.

Moved schema for custom fields into variable in utils to allow easier modification for all resources at once.

Support for longtext is accomplished by adding it to the types.

Added select and multiselect type to better imitate netbox types. Old selection and multiple are still available, but removed from examples. multiselect uses a JSON-Field, see examples.

json type just accepts the string provided. Best used with jsonencode.

object and mutliobject are mostly copies of select and multiselect but are converted to integer before being sent to netbox.

smutel commented 1 year ago

I tried to migrate from legacy custom fields to new ones. It is working except for netbox_tenancy_contact_group with the error message below (I didn't find any details through tcpdump):

│ Error: response status code does not match any response statuses defined for this endpoint in the swagger spec (status 400): {}
│ 
│   with netbox_tenancy_contact_group.contact_group_01,
│   on main.tf line 884, in resource "netbox_tenancy_contact_group" "contact_group_01":
│  884: resource "netbox_tenancy_contact_group" "contact_group_01" {
Terraform will perform the following actions:

  # netbox_ipam_vlan.vlan_test will be updated in-place
  ~ resource "netbox_ipam_vlan" "vlan_test" {
        id            = "47"
        name          = "Test_Vlan"     
      ~ vlan_group_id = 0 -> 48  
        # (7 unchanged attributes hidden)

        # (12 unchanged blocks hidden)
    }                   

  # netbox_tenancy_contact.contact will be updated in-place
  ~ resource "netbox_tenancy_contact" "contact" {
      ~ contact_group_id = 0 -> 96
        id               = "48"       
        name             = "John Doe"
        # (6 unchanged attributes hidden)

        # (12 unchanged blocks hidden)
    }

~ resource "netbox_tenancy_contact_group" "contact_group_01" {                                                                                                                                           [9/8300]
        id           = "95"          
        name         = "A contact group"
        # (4 unchanged attributes hidden)

      - custom_field {
          - name = "cf_json" -> null 
          - type = "json" -> null                                                                        
        }                                
      + custom_field {
          + name  = "cf_json"
          + type  = "json"
          + value = jsonencode(
                {
                  + boolvalue   = false
                  + dictionary  = {
                      + numbervalue = 5
                    }
                  + stringvalue = "string"
                }
            )
        }
      - custom_field {
          - name = "cf_multi_object" -> null
          - type = "multiobject" -> null
        }
      + custom_field {
          + name  = "cf_multi_object"
          + type  = "multiobject"
          + value = jsonencode(
                [
                  + 1,
                  + 2,
                ]
            )
        }
      - custom_field {
          - name = "cf_multi_selection" -> null
          - type = "multiselect" -> null
        }
      + custom_field {
          + name  = "cf_multi_selection"
          + type  = "multiselect"
          + value = jsonencode(
                [
                  + "0",
                  + "1",
                ]
            )
        }
      - custom_field {
          - name = "cf_object" -> null
          - type = "object" -> null
        }
      + custom_field {
          + name  = "cf_object"
          + type  = "object"
          + value = "1"
        }
amhn commented 1 year ago

Another good case for a comprehensive test suite.

It seems I did not test the object field, instead only assumed that the value is an integer. Instead the value is a list with one element.

I modified your exports, so they can be imported without modification and added 2 platforms and the new types of custom fields reference in the examples.

smutel commented 1 year ago

It seems that you deleted some files in the exports folder but I didn't see any change. Is-it a mistake ?

I created everything in Netbox using https://github.com/smutel/terraform-provider-netbox/blob/master/examples/main.tf. I added the two platforms and the new custom fields.

However I encounter other kind of issues if I execute the provider made with this PR:

│ Error: response status code does not match any response statuses defined for this endpoint in the swagger spec (status 500): {}
│ 
│   with netbox_tenancy_tenant.tenant_test,
│   on main.tf line 1, in resource "netbox_tenancy_tenant" "tenant_test":
│    1: resource "netbox_tenancy_tenant" "tenant_test" {
│ 
╵
╷
│ Error: response status code does not match any response statuses defined for this endpoint in the swagger spec (status 500): {}
│ 
│   with netbox_ipam_ip_range.range_test,
│   on main.tf line 320, in resource "netbox_ipam_ip_range" "range_test":
│  320: resource "netbox_ipam_ip_range" "range_test" {
│ 
╵
╷
│ Error: response status code does not match any response statuses defined for this endpoint in the swagger spec (status 500): {}
│ 
│   with netbox_ipam_aggregate.aggregate_test,
│   on main.tf line 712, in resource "netbox_ipam_aggregate" "aggregate_test":
│  712: resource "netbox_ipam_aggregate" "aggregate_test" {
│ 
╵
╷
│ Error: response status code does not match any response statuses defined for this endpoint in the swagger spec (status 500): {}
│ 
│   with netbox_tenancy_contact.contact,
│   on main.tf line 801, in resource "netbox_tenancy_contact" "contact":
│  801: resource "netbox_tenancy_contact" "contact" {
│ 
╵
╷
│ Error: response status code does not match any response statuses defined for this endpoint in the swagger spec (status 400): {}
│ 
│   with netbox_tenancy_contact_group.contact_group_01,
│   on main.tf line 893, in resource "netbox_tenancy_contact_group" "contact_group_01":
│  893: resource "netbox_tenancy_contact_group" "contact_group_01" {
│ 
╵
╷
│ Error: response status code does not match any response statuses defined for this endpoint in the swagger spec (status 500): {}
│ 
│   with netbox_tenancy_contact_role.contact_role_01,
│   on main.tf line 988, in resource "netbox_tenancy_contact_role" "contact_role_01":
│  988: resource "netbox_tenancy_contact_role" "contact_role_01" {
{"parent":["Related object not found using the provided numeric ID: 0"]}
{"error": "Field 'id' expected a number but got [1].", "exception": "TypeError", "netbox_version": "3.2.9", "python_version": "3.10.4"}
amhn commented 1 year ago

I moved the export from netbox{resource}.csv ot netbox{module}_{resource}.csv to make it easier to import them in the right order. Also I edited them so they can be imported as is. Because of https://github.com/netbox-community/netbox/issues/5952 the export is unfortunately not usable for the import.

I can revert the change or split it in 2 to make it easier to unterstand what is going on.

  1. Commit: Move files
  2. Commit: Edit files.
amhn commented 1 year ago

Can you try again? I just added a fix if parent_id is 0 for netbox_tenancy_contact_group.

This is unrelated to the new code. It was just triggered, because netbox_tenancy_contact_group is updated.

Another thing I noticed is that I did rename the cf_multiple_selection custom field to cf_multi_selection. I would change that to cf_multi_select and cf_selection to cf_select to harmonize data types and field names.

smutel commented 1 year ago

I don't have this message anymore:

{"parent":["Related object not found using the provided numeric ID: 0"]}

But I still have these messages:

{"error": "Field 'id' expected a number but got [1].", "exception": "TypeError", "netbox_version": "3.2.9", "python_version": "3.10.4"}
amhn commented 1 year ago

I can not reproduce this error.

My test:

My result is no errors. There were just two changes which were report in a second terraform apply. group_id in for vlan and contact was reset on updating. This is fixed in a new commit. But this was also unrelated to my changes.

Can you provide more details? For example the plan output before the errors.

smutel commented 1 year ago

I did some tests again and I was not able to reproduce this issue. I assume that I did'nt create the custom fields properly. Thanks for your PR.