From dabc6fc62d900d70bf7ffea04b6bdb2bd2268a77 Mon Sep 17 00:00:00 2001 From: Tuomas Starck Date: Mon, 31 Oct 2022 20:38:59 +0200 Subject: [PATCH] Query VLANs by group, role, or tenant --- .gitignore | 1 + docs/data-sources/vlan.md | 20 ++++-- .../data-sources/netbox_vlan/data-source.tf | 11 ++- netbox/data_source_netbox_tenant.go | 6 +- netbox/data_source_netbox_vlan.go | 25 +++++-- netbox/data_source_netbox_vlan_test.go | 72 ++++++++++++++++++- 6 files changed, 119 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 3eef5b1d..1b9cba81 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.dll *.exe +.envrc .DS_Store example.tf terraform.tfplan diff --git a/docs/data-sources/vlan.md b/docs/data-sources/vlan.md index 5d372efc..8b0ce19b 100644 --- a/docs/data-sources/vlan.md +++ b/docs/data-sources/vlan.md @@ -18,9 +18,16 @@ data "netbox_vlan" "vlan1" { name = "vlan-1" } -# Get VLAN by VLAN ID +# Get VLAN by VID and IPAM role ID data "netbox_vlan" "vlan2" { - vid = 1234 + vid = 1234 + role = netbox_ipam_role.example.id +} + +# Get VLAN by name and tenant ID +data "netbox_vlan" "vlan3" { + name = "vlan-3" + tenant = netbox_tenant.example.id } ``` @@ -29,16 +36,17 @@ data "netbox_vlan" "vlan2" { ### Optional -- `name` (String) At least one of `name` or `vid` must be given. -- `vid` (Number) At least one of `name` or `vid` must be given. +- `group_id` (Number) +- `name` (String) +- `role` (Number) +- `tenant` (Number) +- `vid` (Number) ### Read-Only - `description` (String) - `id` (String) The ID of this resource. -- `role` (Number) - `site` (Number) - `status` (String) -- `tenant` (Number) diff --git a/examples/data-sources/netbox_vlan/data-source.tf b/examples/data-sources/netbox_vlan/data-source.tf index d4a87ded..b22db2b1 100644 --- a/examples/data-sources/netbox_vlan/data-source.tf +++ b/examples/data-sources/netbox_vlan/data-source.tf @@ -3,7 +3,14 @@ data "netbox_vlan" "vlan1" { name = "vlan-1" } -# Get VLAN by VLAN ID +# Get VLAN by VID and IPAM role ID data "netbox_vlan" "vlan2" { - vid = 1234 + vid = 1234 + role = netbox_ipam_role.example.id +} + +# Get VLAN by name and tenant ID +data "netbox_vlan" "vlan3" { + name = "vlan-3" + tenant = netbox_tenant.example.id } diff --git a/netbox/data_source_netbox_tenant.go b/netbox/data_source_netbox_tenant.go index 7c21cfe2..4f2ac515 100644 --- a/netbox/data_source_netbox_tenant.go +++ b/netbox/data_source_netbox_tenant.go @@ -14,19 +14,19 @@ func dataSourceNetboxTenant() *schema.Resource { Read: dataSourceNetboxTenantRead, Description: `:meta:subcategory:Tenancy:`, Schema: map[string]*schema.Schema{ - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Computed: true, Optional: true, AtLeastOneOf: []string{"name", "slug"}, }, - "slug": &schema.Schema{ + "slug": { Type: schema.TypeString, Optional: true, Computed: true, AtLeastOneOf: []string{"name", "slug"}, }, - "group_id": &schema.Schema{ + "group_id": { Type: schema.TypeInt, Computed: true, }, diff --git a/netbox/data_source_netbox_vlan.go b/netbox/data_source_netbox_vlan.go index 2f4596c1..f0df1b0b 100644 --- a/netbox/data_source_netbox_vlan.go +++ b/netbox/data_source_netbox_vlan.go @@ -18,21 +18,25 @@ func dataSourceNetboxVlan() *schema.Resource { "vid": { Type: schema.TypeInt, Optional: true, - AtLeastOneOf: []string{"name", "vid"}, ValidateFunc: validation.IntBetween(1, 4094), }, "name": { - Type: schema.TypeString, - Optional: true, - AtLeastOneOf: []string{"name", "vid"}, + Type: schema.TypeString, + Optional: true, }, "description": { Type: schema.TypeString, Computed: true, }, + "group_id": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + }, "role": { Type: schema.TypeInt, Computed: true, + Optional: true, }, "site": { Type: schema.TypeInt, @@ -45,6 +49,7 @@ func dataSourceNetboxVlan() *schema.Resource { "tenant": { Type: schema.TypeInt, Computed: true, + Optional: true, }, }, } @@ -61,6 +66,15 @@ func dataSourceNetboxVlanRead(d *schema.ResourceData, m interface{}) error { if vid, ok := d.Get("vid").(int); ok && vid != 0 { params.Vid = strToPtr(strconv.Itoa(vid)) } + if groupID, ok := d.Get("group_id").(int); ok && groupID != 0 { + params.GroupID = strToPtr(strconv.Itoa(groupID)) + } + if roleID, ok := d.Get("role").(int); ok && roleID != 0 { + params.RoleID = strToPtr(strconv.Itoa(roleID)) + } + if tenantID, ok := d.Get("tenant").(int); ok && tenantID != 0 { + params.TenantID = strToPtr(strconv.Itoa(tenantID)) + } res, err := api.Ipam.IpamVlansList(params, nil) if err != nil { @@ -78,6 +92,9 @@ func dataSourceNetboxVlanRead(d *schema.ResourceData, m interface{}) error { d.Set("status", vlan.Status.Value) d.Set("description", vlan.Description) + if vlan.Group != nil { + d.Set("group_id", vlan.Group.ID) + } if vlan.Role != nil { d.Set("role", vlan.Role.ID) } diff --git a/netbox/data_source_netbox_vlan_test.go b/netbox/data_source_netbox_vlan_test.go index cae561fa..3db49b76 100644 --- a/netbox/data_source_netbox_vlan_test.go +++ b/netbox/data_source_netbox_vlan_test.go @@ -12,6 +12,7 @@ func TestAccNetboxVlanDataSource_basic(t *testing.T) { testVid := 4092 testName := testAccGetTestName("vlan") setUp := testAccNetboxVlanSetUp(testVid, testName) + extendedSetUp := testAccNetboxVlanSetUpMore(testVid, testVid-1, testName) resource.ParallelTest(t, resource.TestCase{ Providers: testAccProviders, Steps: []resource.TestStep{ @@ -30,29 +31,82 @@ func TestAccNetboxVlanDataSource_basic(t *testing.T) { }, { Config: setUp + testAccNetboxVlanDataByVid(testVid), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair("data.netbox_vlan.test", "id", "netbox_vlan.test", "id"), + ), + }, + + { + Config: setUp + extendedSetUp + testAccNetboxVlanDataByNameAndRole(testName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair("data.netbox_vlan.test", "id", "netbox_vlan.test", "id"), + ), + }, + { + Config: setUp + extendedSetUp + testAccNetboxVlanDataByVidAndTenant(testVid), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair("data.netbox_vlan.test", "id", "netbox_vlan.test", "id"), resource.TestCheckResourceAttr("data.netbox_vlan.test", "name", testName), resource.TestCheckResourceAttr("data.netbox_vlan.test", "status", "active"), resource.TestCheckResourceAttr("data.netbox_vlan.test", "description", "Test"), + resource.TestCheckResourceAttrPair("data.netbox_vlan.test", "role", "netbox_ipam_role.test", "id"), + resource.TestCheckResourceAttrPair("data.netbox_vlan.test", "site", "netbox_site.test", "id"), + resource.TestCheckResourceAttrPair("data.netbox_vlan.test", "tenant", "netbox_tenant.test", "id"), ), }, + { + Config: setUp + extendedSetUp + testAccNetboxVlanDataByName(testName), + ExpectError: regexp.MustCompile("expected one device type, but got 2"), + }, + { + Config: setUp + extendedSetUp + testAccNetboxVlanDataByVid(testVid), + ExpectError: regexp.MustCompile("expected one device type, but got 2"), + }, }, }) } func testAccNetboxVlanSetUp(testVid int, testName string) string { return fmt.Sprintf(` +resource "netbox_ipam_role" "test" { + name = "%[2]s" +} + +resource "netbox_site" "test" { + name = "%[2]s" +} + +resource "netbox_tenant" "test" { + name = "%[2]s" +} + resource "netbox_vlan" "test" { vid = %[1]d name = "%[2]s" - status = "active" description = "Test" + role_id = netbox_ipam_role.test.id + site_id = netbox_site.test.id + status = "active" tags = [] + tenant_id = netbox_tenant.test.id } `, testVid, testName) } +func testAccNetboxVlanSetUpMore(testVid int, anotherVid int, testName string) string { + return fmt.Sprintf(` +resource "netbox_vlan" "same_name" { + vid = %[1]d + name = "%[3]s" +} + +resource "netbox_vlan" "not_same" { + vid = %[2]d + name = "%[3]s_unique" +} +`, testVid, anotherVid, testName) +} + const testAccNetboxVlanDataNoResult = ` data "netbox_vlan" "no_result" { name = "_no_result_" @@ -71,3 +125,19 @@ data "netbox_vlan" "test" { vid = "%[1]d" }`, testVid) } + +func testAccNetboxVlanDataByNameAndRole(testName string) string { + return fmt.Sprintf(` +data "netbox_vlan" "test" { + name = "%[1]s" + role = netbox_ipam_role.test.id +}`, testName) +} + +func testAccNetboxVlanDataByVidAndTenant(testVid int) string { + return fmt.Sprintf(` +data "netbox_vlan" "test" { + vid = "%[1]d" + tenant = netbox_tenant.test.id +}`, testVid) +}