diff --git a/docs/data-sources/prefix.md b/docs/data-sources/prefix.md index 7971f6d9..a8a07f01 100644 --- a/docs/data-sources/prefix.md +++ b/docs/data-sources/prefix.md @@ -17,20 +17,20 @@ description: |- ### Optional -- `cidr` (String, Deprecated) At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. Conflicts with `prefix`. +- `cidr` (String, Deprecated) Conflicts with `prefix`. - `custom_fields` (Map of String) -- `description` (String) Description to include in the data source filter. At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. -- `family` (Number) The IP family of the prefix. One of 4 or 6. At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. -- `prefix` (String) At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. Conflicts with `cidr`. -- `role_id` (Number) At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. -- `site_id` (Number) At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. -- `tag` (String) Tag to include in the data source filter (must match the tag's slug). At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. +- `description` (String) Description to include in the data source filter. +- `family` (Number) The IP family of the prefix. One of 4 or 6. +- `prefix` (String) At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr`, `custom_fields` or `tag` must be given. Conflicts with `cidr`. +- `role_id` (Number) +- `site_id` (Number) +- `tag` (String) Tag to include in the data source filter (must match the tag's slug). - `tag__n` (String) Tag to exclude from the data source filter (must match the tag's slug). Refer to [Netbox's documentation](https://demo.netbox.dev/static/docs/rest-api/filtering/#lookup-expressions) for more information on available lookup expressions. -- `vlan_id` (Number) At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. -- `vlan_vid` (Number) At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. -- `vrf_id` (Number) At least one of `description`, `family`, `prefix`, `vlan_vid`, `vrf_id`, `vlan_id`, `site_id`, `role_id`, `cidr` or `tag` must be given. +- `vlan_id` (Number) +- `vlan_vid` (Number) +- `vrf_id` (Number) ### Read-Only diff --git a/netbox/custom_fields.go b/netbox/custom_fields.go index ad35c37d..47750db7 100644 --- a/netbox/custom_fields.go +++ b/netbox/custom_fields.go @@ -1,6 +1,12 @@ package netbox import ( + "fmt" + "net/url" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -23,3 +29,37 @@ func getCustomFields(cf interface{}) map[string]interface{} { } return cfm } + +type CustomFieldParams struct { + params runtime.ClientRequestWriter + cfm map[string]interface{} +} + +func (o *CustomFieldParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error { + if err := o.params.WriteToRequest(r, reg); err != nil { + return err + } + + for k, v := range o.cfm { + if vs, ok := v.(string); ok { + if err := r.SetQueryParam(fmt.Sprintf("cf_%s", url.QueryEscape(k)), vs); err != nil { + return err + } + } + } + + return nil +} + +func WithCustomFieldParamsOption(cfm map[string]interface{}) func(*runtime.ClientOperation) { + if cfm == nil { + cfm = make(map[string]interface{}) + } + + return func(co *runtime.ClientOperation) { + co.Params = &CustomFieldParams{ + params: co.Params, + cfm: cfm, + } + } +} diff --git a/netbox/data_source_netbox_prefix.go b/netbox/data_source_netbox_prefix.go index be311e5c..daa4c521 100644 --- a/netbox/data_source_netbox_prefix.go +++ b/netbox/data_source_netbox_prefix.go @@ -25,63 +25,54 @@ func dataSourceNetboxPrefix() *schema.Resource { Deprecated: "The `cidr` parameter is deprecated in favor of the canonical `prefix` attribute.", ConflictsWith: []string{"prefix"}, ValidateFunc: validation.IsCIDR, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, }, customFieldsKey: customFieldsSchema, "description": { - Type: schema.TypeString, - Optional: true, - Computed: true, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, - Description: "Description to include in the data source filter.", + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Description to include in the data source filter.", }, "family": { Type: schema.TypeInt, Optional: true, Computed: true, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, ValidateFunc: validation.IntInSlice([]int{4, 6}), Description: "The IP family of the prefix. One of 4 or 6", }, "role_id": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, + Type: schema.TypeInt, + Optional: true, + Computed: true, }, "prefix": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.IsCIDR, ConflictsWith: []string{"cidr"}, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, + AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "custom_fields", "tag"}, }, "vlan_vid": { Type: schema.TypeFloat, Optional: true, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, ValidateFunc: validation.FloatBetween(1, 4094), }, "vrf_id": { - Type: schema.TypeInt, - Optional: true, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, + Type: schema.TypeInt, + Optional: true, }, "vlan_id": { - Type: schema.TypeInt, - Optional: true, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, + Type: schema.TypeInt, + Optional: true, }, "site_id": { - Type: schema.TypeInt, - Optional: true, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, + Type: schema.TypeInt, + Optional: true, }, "tag": { - Type: schema.TypeString, - Optional: true, - AtLeastOneOf: []string{"description", "family", "prefix", "vlan_vid", "vrf_id", "vlan_id", "site_id", "role_id", "cidr", "tag"}, - Description: "Tag to include in the data source filter (must match the tag's slug).", + Type: schema.TypeString, + Optional: true, + Description: "Tag to include in the data source filter (must match the tag's slug).", }, "tag__n": { Type: schema.TypeString, @@ -103,6 +94,7 @@ func dataSourceNetboxPrefixRead(d *schema.ResourceData, m interface{}) error { api := m.(*client.NetBoxAPI) params := ipam.NewIpamPrefixesListParams() + var opts []ipam.ClientOption limit := int64(2) // Limit of 2 is enough params.Limit = &limit @@ -155,7 +147,11 @@ func dataSourceNetboxPrefixRead(d *schema.ResourceData, m interface{}) error { params.Tagn = &tagn } - res, err := api.Ipam.IpamPrefixesList(params, nil) + if cfm, ok := d.Get(customFieldsKey).(map[string]interface{}); ok { + opts = append(opts, WithCustomFieldParamsOption(cfm)) + } + + res, err := api.Ipam.IpamPrefixesList(params, nil, opts...) if err != nil { return err } diff --git a/netbox/data_source_netbox_prefix_test.go b/netbox/data_source_netbox_prefix_test.go index 520dcdd3..c736ed2e 100644 --- a/netbox/data_source_netbox_prefix_test.go +++ b/netbox/data_source_netbox_prefix_test.go @@ -147,7 +147,9 @@ resource "netbox_prefix" "test" { data "netbox_prefix" "test_output" { depends_on = [netbox_prefix.test] - prefix = "%[2]s" + custom_fields = { + "${netbox_custom_field.test.name}" = "test value" + } }`, testField, testPrefix), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("data.netbox_prefix.test_output", "status", "active"),