diff --git a/go.mod b/go.mod index 15bae947..ebb7c018 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/go-openapi/strfmt v0.21.7 github.com/goware/urlx v0.3.2 github.com/hashicorp/terraform-plugin-sdk/v2 v2.27.0 + github.com/iancoleman/strcase v0.2.0 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.8.4 golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15 diff --git a/go.sum b/go.sum index 630d4592..01f04987 100644 --- a/go.sum +++ b/go.sum @@ -180,6 +180,8 @@ github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= diff --git a/netbox/data_source_netbox_prefixes.go b/netbox/data_source_netbox_prefixes.go index 59326f6e..0b036aea 100644 --- a/netbox/data_source_netbox_prefixes.go +++ b/netbox/data_source_netbox_prefixes.go @@ -2,13 +2,16 @@ package netbox import ( "fmt" + "reflect" "strconv" + "strings" "github.com/fbreckle/go-netbox/netbox/client" "github.com/fbreckle/go-netbox/netbox/client/ipam" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/iancoleman/strcase" ) func dataSourceNetboxPrefixes() *schema.Resource { @@ -98,27 +101,28 @@ func dataSourceNetboxPrefixesRead(d *schema.ResourceData, m interface{}) error { k := f.(map[string]interface{})["name"] v := f.(map[string]interface{})["value"] vString := v.(string) - switch k { - case "prefix": - params.Prefix = &vString - case "vlan_vid": - float, err := strconv.ParseFloat(vString, 64) - if err != nil { - return err + paramName := strcase.ToCamel(strings.Replace(k.(string), "__n", "n", -1)) + paramName = strings.Replace(paramName, "Id", "ID", -1) + + params_reflect := reflect.ValueOf(params).Elem() + field := params_reflect.FieldByName(paramName) + + if !(field.IsValid()) { + return fmt.Errorf("'%s' is not a supported filter parameter. Netbox go SDK does not have the associated parameter [(%s)]", k, paramName) + } + + if field.Kind() == reflect.Slice { + //Param is an array/slice + field.Set(reflect.Append(field, reflect.ValueOf(vString))) + } else if (reflect.PtrTo(field.Type().Elem()).Elem().Kind()) == reflect.Float64 { + // ^ This CANT be the best way to do this, but it works + vFloat, err := strconv.ParseFloat(vString, 64) + if field.Set(reflect.ValueOf(&vFloat)); err != nil { + return fmt.Errorf("Failed to set parameter [(%s)] with error [(%s)]", paramName, err) } - params.VlanVid = &float - case "vrf_id": - params.VrfID = &vString - case "vlan_id": - params.VlanID = &vString - case "status": - params.Status = &vString - case "site_id": - params.SiteID = &vString - case "tag": - params.Tag = []string{vString} - default: - return fmt.Errorf("'%s' is not a supported filter parameter", k) + } else { + //Param is a scalar + field.Set(reflect.ValueOf(&vString)) } } } diff --git a/netbox/data_source_netbox_prefixes_test.go b/netbox/data_source_netbox_prefixes_test.go index d4b67109..386207b0 100644 --- a/netbox/data_source_netbox_prefixes_test.go +++ b/netbox/data_source_netbox_prefixes_test.go @@ -9,7 +9,7 @@ import ( func TestAccNetboxPrefixesDataSource_basic(t *testing.T) { - testPrefixes := []string{"10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24", "10.0.7.0/24"} + testPrefixes := []string{"10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24", "10.0.7.0/24", "10.0.8.0/25"} testSlug := "prefixes_ds_basic" testVlanVids := []int{4093, 4094} testName := testAccGetTestName(testSlug) @@ -34,8 +34,15 @@ resource "netbox_prefix" "test_prefix2" { vlan_id = netbox_vlan.test_vlan2.id } +resource "netbox_prefix" "test_prefix_two_tags_and_length_25" { + prefix = "%[6]s" + status = "active" + description = "multiple-tag-prefix" + tags = [netbox_tag.test_tag3.slug, netbox_tag.test_tag4.slug] +} + resource "netbox_prefix" "without_vrf_and_vlan" { - prefix = "%[4]s" + prefix = "%[5]s" status = "active" } @@ -56,12 +63,12 @@ resource "netbox_vrf" "test_vrf" { resource "netbox_vlan" "test_vlan1" { name = "%[1]s_vlan1" - vid = %[6]d + vid = %[7]d } resource "netbox_vlan" "test_vlan2" { name = "%[1]s_vlan2" - vid = %[7]d + vid = %[8]d } resource "netbox_tag" "test_tag1" { @@ -72,6 +79,14 @@ resource "netbox_tag" "test_tag2" { name = "tag-with-no-associtions" } +resource "netbox_tag" "test_tag3" { + name = "%[1]s-tag-3" +} + +resource "netbox_tag" "test_tag4" { + name = "%[1]s-tag-4" +} + data "netbox_prefixes" "by_vrf" { depends_on = [netbox_prefix.test_prefix1, netbox_prefix.test_prefix2] filter { @@ -84,7 +99,7 @@ data "netbox_prefixes" "by_vid" { depends_on = [netbox_prefix.test_prefix1, netbox_prefix.test_prefix2] filter { name = "vlan_vid" - value = "%[6]d" + value = "%[7]d" } } @@ -96,6 +111,38 @@ data "netbox_prefixes" "by_tag" { } } +data "netbox_prefixes" "by_mask_length" { + depends_on = [netbox_prefix.test_prefix_two_tags_and_length_25] + filter { + name = "mask_length" + value = "25" + } +} + +data "netbox_prefixes" "by_mask_length_and_tag" { + depends_on = [netbox_prefix.test_prefix1] + filter { + name = "mask_length" + value = "24" + } + filter { + name = "tag" + value = "%[1]s" + } +} + +data "netbox_prefixes" "by_multiple_tags" { + depends_on = [netbox_prefix.test_prefix_two_tags_and_length_25] + filter { + name = "tag" + value = netbox_tag.test_tag3.slug + } + filter { + name = "tag" + value = netbox_tag.test_tag4.slug + } +} + data "netbox_prefixes" "no_results" { depends_on = [netbox_prefix.test_prefix1] filter { @@ -118,7 +165,7 @@ data "netbox_prefixes" "find_prefix_with_site_id" { value = netbox_site.test.id } } -`, testName, testPrefixes[0], testPrefixes[1], testPrefixes[2], testPrefixes[3], testVlanVids[0], testVlanVids[1]), +`, testName, testPrefixes[0], testPrefixes[1], testPrefixes[2], testPrefixes[3], testPrefixes[4], testVlanVids[0], testVlanVids[1]), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("data.netbox_prefixes.by_vrf", "prefixes.#", "2"), resource.TestCheckResourceAttrPair("data.netbox_prefixes.by_vrf", "prefixes.1.vlan_vid", "netbox_vlan.test_vlan2", "vid"), @@ -128,6 +175,12 @@ data "netbox_prefixes" "find_prefix_with_site_id" { resource.TestCheckResourceAttr("data.netbox_prefixes.no_results", "prefixes.#", "0"), resource.TestCheckResourceAttr("data.netbox_prefixes.find_prefix_with_site_id", "prefixes.#", "1"), resource.TestCheckResourceAttr("data.netbox_prefixes.find_prefix_with_site_id", "prefixes.0.prefix", "10.0.7.0/24"), + resource.TestCheckResourceAttr("data.netbox_prefixes.by_mask_length", "prefixes.#", "1"), + resource.TestCheckResourceAttr("data.netbox_prefixes.by_mask_length", "prefixes.0.prefix", "10.0.8.0/25"), + resource.TestCheckResourceAttr("data.netbox_prefixes.by_multiple_tags", "prefixes.#", "1"), + resource.TestCheckResourceAttr("data.netbox_prefixes.by_multiple_tags", "prefixes.0.prefix", "10.0.8.0/25"), + resource.TestCheckResourceAttr("data.netbox_prefixes.by_mask_length_and_tag", "prefixes.#", "1"), + resource.TestCheckResourceAttr("data.netbox_prefixes.by_mask_length_and_tag", "prefixes.0.prefix", "10.0.4.0/24"), ), }, },