Skip to content

Commit

Permalink
Added custom fields resource (VM's only) (#158)
Browse files Browse the repository at this point in the history
* Up go-netbox version

* Added custom field for VM's

Co-authored-by: fbreckle <39595706+fbreckle@users.noreply.github.com>
  • Loading branch information
chapsuk and fbreckle authored May 6, 2022
1 parent e6e8e96 commit cd7f541
Show file tree
Hide file tree
Showing 8 changed files with 476 additions and 3 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.17

require (
github.com/davecgh/go-spew v1.1.1
github.com/fbreckle/go-netbox v0.0.0-20220117123939-7f4dc1816b81
github.com/fbreckle/go-netbox v0.0.0-20220412164522-d49cfef38bfd
github.com/go-openapi/runtime v0.24.1
github.com/goware/urlx v0.3.1
github.com/hashicorp/terraform-plugin-sdk/v2 v2.15.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fbreckle/go-netbox v0.0.0-20220117123939-7f4dc1816b81 h1:B+msHm89glJ9nJ4dGZwI5jwUMUTTQULQkVLTxc/aHzw=
github.com/fbreckle/go-netbox v0.0.0-20220117123939-7f4dc1816b81/go.mod h1:Nf2bxylehF4ROF+s2paaRCKLIeYcUb2+NK1R/nOsE0o=
github.com/fbreckle/go-netbox v0.0.0-20220412164522-d49cfef38bfd h1:ILjUs5ZBk8f3Z7SZ2v3ZPti++X0sdVXD0C4pfMcDOVI=
github.com/fbreckle/go-netbox v0.0.0-20220412164522-d49cfef38bfd/go.mod h1:Nf2bxylehF4ROF+s2paaRCKLIeYcUb2+NK1R/nOsE0o=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
Expand Down
25 changes: 25 additions & 0 deletions netbox/custom_fields.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package netbox

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

const customFieldsKey = "custom_fields"

var customFieldsSchema = &schema.Schema{
Type: schema.TypeMap,
Optional: true,
Default: nil,
Elem: &schema.Schema{
Type: schema.TypeString,
Default: nil,
},
}

func getCustomFields(cf interface{}) map[string]interface{} {
cfm, ok := cf.(map[string]interface{})
if !ok || len(cfm) == 0 {
return nil
}
return cfm
}
1 change: 1 addition & 0 deletions netbox/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func Provider() *schema.Provider {
"netbox_circuit_type": resourceNetboxCircuitType(),
"netbox_circuit_provider": resourceNetboxCircuitProvider(),
"netbox_circuit_termination": resourceNetboxCircuitTermination(),
"netbox_custom_field": resourceCustomField(),
},
DataSourcesMap: map[string]*schema.Resource{
"netbox_cluster": dataSourceNetboxCluster(),
Expand Down
251 changes: 251 additions & 0 deletions netbox/resource_netbox_custom_field.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
package netbox

import (
"fmt"
"strconv"

"github.com/fbreckle/go-netbox/netbox/client"
"github.com/fbreckle/go-netbox/netbox/client/extras"
"github.com/fbreckle/go-netbox/netbox/models"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func resourceCustomField() *schema.Resource {
return &schema.Resource{
Create: resourceNetboxCustomFieldCreate,
Read: resourceNetboxCustomFieldRead,
Update: resourceNetboxCustomFieldUpdate,
Delete: resourceNetboxCustomFieldDelete,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
models.CustomFieldTypeValueText,
models.CustomFieldTypeValueInteger,
models.CustomFieldTypeValueBoolean,
models.CustomFieldTypeValueDate,
models.CustomFieldTypeValueURL,
models.CustomFieldTypeValueSelect,
models.CustomFieldTypeValueMultiselect,
}, false),
},
"content_types": {
Type: schema.TypeSet,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Set: schema.HashString,
},
"weight": {
Type: schema.TypeInt,
Required: true,
DefaultFunc: func() (interface{}, error) {
return 100, nil
},
},
"choices": {
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Default: nil,
},
"default": {
Type: schema.TypeString,
Optional: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"label": {
Type: schema.TypeString,
Optional: true,
},
"required": {
Type: schema.TypeBool,
Optional: true,
},
"validation_maximum": {
Type: schema.TypeInt,
Optional: true,
},
"validation_minimum": {
Type: schema.TypeInt,
Optional: true,
},
"validation_regex": {
Type: schema.TypeString,
Optional: true,
},
},
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
}
}

func resourceNetboxCustomFieldUpdate(d *schema.ResourceData, m interface{}) error {
api := m.(*client.NetBoxAPI)

id, _ := strconv.ParseInt(d.Id(), 10, 64)

data := &models.WritableCustomField{
Name: strToPtr(d.Get("name").(string)),
Type: d.Get("type").(string),
Description: d.Get("description").(string),
Label: d.Get("label").(string),
Required: d.Get("required").(bool),
ValidationRegex: d.Get("validation_regex").(string),
Weight: int64ToPtr(int64(d.Get("weight").(int))),
}

choices, ok := d.GetOk("choices")
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))
}
}

ctypes, ok := d.GetOk("content_types")
if ok {
for _, t := range ctypes.(*schema.Set).List() {
data.ContentTypes = append(data.ContentTypes, t.(string))
}
}

vmax, ok := d.GetOk("validation_maximum")
if ok {
data.ValidationMaximum = int64ToPtr(int64(vmax.(int)))
}
vmin, ok := d.GetOk("validation_minimum")
if ok {
data.ValidationMinimum = int64ToPtr(int64(vmin.(int)))
}

params := extras.NewExtrasCustomFieldsUpdateParams().WithID(id).WithData(data)
res, err := api.Extras.ExtrasCustomFieldsUpdate(params, nil)
if err != nil {
return err
}

d.SetId(strconv.FormatInt(res.GetPayload().ID, 10))

return resourceNetboxCustomFieldRead(d, m)
}

func resourceNetboxCustomFieldCreate(d *schema.ResourceData, m interface{}) error {
api := m.(*client.NetBoxAPI)

data := &models.WritableCustomField{
Name: strToPtr(d.Get("name").(string)),
Type: d.Get("type").(string),
Description: d.Get("description").(string),
Label: d.Get("label").(string),
Required: d.Get("required").(bool),
ValidationRegex: d.Get("validation_regex").(string),
Weight: int64ToPtr(int64(d.Get("weight").(int))),
}

choices, ok := d.GetOk("choices")
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))
}
}

ctypes, ok := d.GetOk("content_types")
if ok {
for _, t := range ctypes.(*schema.Set).List() {
data.ContentTypes = append(data.ContentTypes, t.(string))
}
}

vmax, ok := d.GetOk("validation_maximum")
if ok {
data.ValidationMaximum = int64ToPtr(int64(vmax.(int)))
}
vmin, ok := d.GetOk("validation_minimum")
if ok {
data.ValidationMinimum = int64ToPtr(int64(vmin.(int)))
}

params := extras.NewExtrasCustomFieldsCreateParams().WithData(data)

res, err := api.Extras.ExtrasCustomFieldsCreate(params, nil)
if err != nil {
//return errors.New(getTextFromError(err))
return err
}

d.SetId(strconv.FormatInt(res.GetPayload().ID, 10))

return resourceNetboxCustomFieldRead(d, m)
}

func resourceNetboxCustomFieldRead(d *schema.ResourceData, m interface{}) error {
api := m.(*client.NetBoxAPI)
id, _ := strconv.ParseInt(d.Id(), 10, 64)
params := extras.NewExtrasCustomFieldsReadParams().WithID(id)
res, err := api.Extras.ExtrasCustomFieldsRead(params, nil)
if err != nil {
errapi, ok := err.(*extras.ExtrasCustomFieldsReadDefault)
if !ok {
return err
}
errorcode := errapi.Code()
if errorcode == 404 {
d.SetId("")
return nil
}
return err
}

d.Set("name", res.GetPayload().Name)
d.Set("type", *res.GetPayload().Type.Value)

d.Set("content_types", res.GetPayload().ContentTypes)

choices := res.GetPayload().Choices
if choices != nil {
d.Set("choices", res.GetPayload().Choices)
}

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

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

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

return nil
}

func resourceNetboxCustomFieldDelete(d *schema.ResourceData, m interface{}) error {
api := m.(*client.NetBoxAPI)
id, _ := strconv.ParseInt(d.Id(), 10, 64)
params := extras.NewExtrasCustomFieldsDeleteParams().WithID(id)
_, err := api.Extras.ExtrasCustomFieldsDelete(params, nil)
return err
}
Loading

0 comments on commit cd7f541

Please sign in to comment.