Skip to content

Commit

Permalink
feat: Add custom field choice set resource
Browse files Browse the repository at this point in the history
  • Loading branch information
fbreckle committed Sep 14, 2023
1 parent 0770799 commit a77cd7a
Show file tree
Hide file tree
Showing 9 changed files with 406 additions and 54 deletions.
2 changes: 1 addition & 1 deletion docs/resources/custom_field.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ resource "netbox_custom_field" "test" {

### Optional

- `choices` (Set of String)
- `choice_set_id` (Number)
- `default` (String)
- `description` (String)
- `group_name` (String)
Expand Down
51 changes: 51 additions & 0 deletions docs/resources/custom_field_choice_set.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
# generated by https://github.com/fbreckle/terraform-plugin-docs
page_title: "netbox_custom_field_choice_set Resource - terraform-provider-netbox"
subcategory: "Extras"
description: |-
From the official documentation https://docs.netbox.dev/en/stable/models/extras/customfieldchoiceset/:
Single- and multi-selection custom fields must define a set of valid choices from which the user may choose when defining the field value. These choices are defined as sets that may be reused among multiple custom fields.
A choice set must define a base choice set and/or a set of arbitrary extra choices.
---

# netbox_custom_field_choice_set (Resource)

From the [official documentation](https://docs.netbox.dev/en/stable/models/extras/customfieldchoiceset/):

Single- and multi-selection custom fields must define a set of valid choices from which the user may choose when defining the field value. These choices are defined as sets that may be reused among multiple custom fields.

A choice set must define a base choice set and/or a set of arbitrary extra choices.

## Example Usage

```terraform
resource "netbox_custom_field_choice_set" "test" {
name = "my-custom-field-set"
description = "Description"
extra_choices = [
["choice1", "label1"], # label and choice are different
["choice2", "choice2"] # label and choice are the same
]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String)

### Optional

- `base_choices` (String) Valid values are `IATA`, `ISO_3166` and `UN_LOCODE`. At least one of `base_choices` or `extra_choices` must be given.
- `custom_fields` (Map of String)
- `description` (String)
- `extra_choices` (List of List of String) This length of the inner lists must be exactly two, where the first value is the value of a choice and the second value is the label of the choice. At least one of `base_choices` or `extra_choices` must be given.
- `order_alphabetically` (Boolean) experimental. Defaults to `false`.

### Read-Only

- `id` (String) The ID of this resource.


8 changes: 8 additions & 0 deletions examples/resources/netbox_custom_field_choice_set/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
resource "netbox_custom_field_choice_set" "test" {
name = "my-custom-field-set"
description = "Description"
extra_choices = [
["choice1", "label1"], # label and choice are different
["choice2", "choice2"] # label and choice are the same
]
}
1 change: 1 addition & 0 deletions netbox/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ func Provider() *schema.Provider {
"netbox_inventory_item_role": resourceNetboxInventoryItemRole(),
"netbox_inventory_item": resourceNetboxInventoryItem(),
"netbox_webhook": resourceNetboxWebhook(),
"netbox_custom_field_choice_set": resourceNetboxCustomFieldChoiceSet(),
},
DataSourcesMap: map[string]*schema.Resource{
"netbox_asn": dataSourceNetboxAsn(),
Expand Down
65 changes: 26 additions & 39 deletions netbox/resource_netbox_custom_field.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package netbox

import (
"fmt"
"strconv"

"github.com/fbreckle/go-netbox/netbox/client"
Expand Down Expand Up @@ -58,14 +57,6 @@ func resourceCustomField() *schema.Resource {
return 100, nil
},
},
"choices": {
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Default: nil,
},
"default": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -98,6 +89,10 @@ func resourceCustomField() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
"choice_set_id": {
Type: schema.TypeInt,
Optional: true,
},
},
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
Expand All @@ -121,14 +116,9 @@ func resourceNetboxCustomFieldUpdate(d *schema.ResourceData, m interface{}) erro
Weight: int64ToPtr(int64(d.Get("weight").(int))),
}

choices, ok := d.GetOk("choices")
choiceSet, ok := d.GetOk("choice_set_id")
if ok {
if data.Type != "select" && data.Type != "multiselect" {
return fmt.Errorf("choices may be set only for custom selection fields")
}
for _, choice := range choices.(*schema.Set).List() {
data.Choices = append(data.Choices, choice.(string))
}
data.ChoiceSet = int64ToPtr(int64(choiceSet.(int)))
}

ctypes, ok := d.GetOk("content_types")
Expand Down Expand Up @@ -172,14 +162,9 @@ func resourceNetboxCustomFieldCreate(d *schema.ResourceData, m interface{}) erro
Weight: int64ToPtr(int64(d.Get("weight").(int))),
}

choices, ok := d.GetOk("choices")
choiceSet, ok := d.GetOk("choice_set_id")
if ok {
if data.Type != "select" && data.Type != "multiselect" {
return fmt.Errorf("choices may be set only for custom selection fields")
}
for _, choice := range choices.(*schema.Set).List() {
data.Choices = append(data.Choices, choice.(string))
}
data.ChoiceSet = int64ToPtr(int64(choiceSet.(int)))
}

ctypes, ok := d.GetOk("content_types")
Expand Down Expand Up @@ -228,29 +213,31 @@ func resourceNetboxCustomFieldRead(d *schema.ResourceData, m interface{}) error
}
return err
}
d.Set("name", res.GetPayload().Name)
d.Set("type", *res.GetPayload().Type.Value)

d.Set("content_types", res.GetPayload().ContentTypes)
customField := res.GetPayload()
d.Set("name", customField.Name)
d.Set("type", *customField.Type.Value)

d.Set("content_types", customField.ContentTypes)

choices := res.GetPayload().Choices
if choices != nil {
d.Set("choices", res.GetPayload().Choices)
choiceSet := customField.ChoiceSet
if choiceSet != nil {
d.Set("choice_set_id", customField.ChoiceSet.ID)
}

d.Set("weight", res.GetPayload().Weight)
if res.GetPayload().Default != nil {
d.Set("default", res.GetPayload().Default)
d.Set("weight", customField.Weight)
if customField.Default != nil {
d.Set("default", customField.Default)
}

d.Set("description", res.GetPayload().Description)
d.Set("group_name", res.GetPayload().GroupName)
d.Set("label", res.GetPayload().Label)
d.Set("required", res.GetPayload().Required)
d.Set("description", customField.Description)
d.Set("group_name", customField.GroupName)
d.Set("label", customField.Label)
d.Set("required", customField.Required)

d.Set("validation_maximum", res.GetPayload().ValidationMaximum)
d.Set("validation_minimum", res.GetPayload().ValidationMinimum)
d.Set("validation_regex", res.GetPayload().ValidationRegex)
d.Set("validation_maximum", customField.ValidationMaximum)
d.Set("validation_minimum", customField.ValidationMinimum)
d.Set("validation_regex", customField.ValidationRegex)

return nil
}
Expand Down
Loading

0 comments on commit a77cd7a

Please sign in to comment.