From 0a24e7224d33df8623572463c91fb1189b82a72d Mon Sep 17 00:00:00 2001 From: Paul Tyng Date: Thu, 27 Aug 2020 22:49:04 -0400 Subject: [PATCH] Add IPv6 support to unifi_network (#47) * add support for adding IPv6 to a network * quote value in the network test * change tests to use static prefix * minor fix for sdkv2 Co-authored-by: Alex Hanselka --- docs/resources/network.md | 5 ++ internal/provider/resource_network.go | 43 +++++++++++++++-- internal/provider/resource_network_test.go | 55 ++++++++++++++++++++++ 3 files changed, 98 insertions(+), 5 deletions(-) diff --git a/docs/resources/network.md b/docs/resources/network.md index 51e6e5bb..89c426f5 100644 --- a/docs/resources/network.md +++ b/docs/resources/network.md @@ -45,6 +45,11 @@ resource "unifi_network" "vlan" { - **domain_name** (String, Optional) The domain name of this network. - **id** (String, Optional) The ID of this resource. - **igmp_snooping** (Boolean, Optional) Specifies whether IGMP snooping is enabled or not. +- **ipv6_interface_type** (String, Optional) Specifies which type of IPv6 connection to use. Defaults to `none`. +- **ipv6_pd_interface** (String, Optional) Specifies which WAN interface to use for IPv6 PD. +- **ipv6_pd_prefixid** (String, Optional) Specifies the IPv6 Prefix ID. +- **ipv6_ra_enable** (Boolean, Optional) Specifies whether to enable router advertisements or not. +- **ipv6_static_subnet** (String, Optional) Specifies the static IPv6 subnet when ipv6_interface_type is 'static'. - **network_group** (String, Optional) The group of the network. Defaults to `LAN`. - **subnet** (String, Optional) The subnet of the network. Must be a valid CIDR address. - **vlan_id** (Number, Optional) The VLAN ID of the network. diff --git a/internal/provider/resource_network.go b/internal/provider/resource_network.go index e45e4813..770f0159 100644 --- a/internal/provider/resource_network.go +++ b/internal/provider/resource_network.go @@ -99,6 +99,32 @@ func resourceNetwork() *schema.Resource { Type: schema.TypeBool, Optional: true, }, + "ipv6_interface_type": { + Description: "Specifies which type of IPv6 connection to use.", + Type: schema.TypeString, + Optional: true, + Default: "none", + }, + "ipv6_static_subnet": { + Description: "Specifies the static IPv6 subnet when ipv6_interface_type is 'static'.", + Type: schema.TypeString, + Optional: true, + }, + "ipv6_pd_interface": { + Description: "Specifies which WAN interface to use for IPv6 PD.", + Type: schema.TypeString, + Optional: true, + }, + "ipv6_pd_prefixid": { + Description: "Specifies the IPv6 Prefix ID.", + Type: schema.TypeString, + Optional: true, + }, + "ipv6_ra_enable": { + Description: "Specifies whether to enable router advertisements or not.", + Type: schema.TypeBool, + Optional: true, + }, }, } } @@ -150,11 +176,13 @@ func resourceNetworkGetResourceData(d *schema.ResourceData) (*unifi.Network, err VLANEnabled: vlan != 0 && vlan != 1, - Enabled: true, - IPV6InterfaceType: "none", - // IPV6InterfaceType string `json:"ipv6_interface_type"` // "none" - // IPV6PDStart string `json:"ipv6_pd_start"` // "::2" - // IPV6PDStop string `json:"ipv6_pd_stop"` // "::7d1" + Enabled: true, + + IPV6InterfaceType: d.Get("ipv6_interface_type").(string), + IPV6Subnet: d.Get("ipv6_static_subnet").(string), + IPV6PDInterface: d.Get("ipv6_pd_interface").(string), + IPV6PDPrefixid: d.Get("ipv6_pd_prefixid").(string), + IPV6RaEnabled: d.Get("ipv6_ra_enable").(bool), }, nil } @@ -196,6 +224,11 @@ func resourceNetworkSetResourceData(resp *unifi.Network, d *schema.ResourceData) d.Set("domain_name", resp.DomainName) d.Set("igmp_snooping", resp.IGMPSnooping) d.Set("dhcp_dns", dhcpDNS) + d.Set("ipv6_interface_type", resp.IPV6InterfaceType) + d.Set("ipv6_static_subnet", resp.IPV6Subnet) + d.Set("ipv6_pd_interface", resp.IPV6PDInterface) + d.Set("ipv6_pd_prefixid", resp.IPV6PDPrefixid) + d.Set("ipv6_ra_enable", resp.IPV6RaEnabled) return nil } diff --git a/internal/provider/resource_network_test.go b/internal/provider/resource_network_test.go index dfaf9823..ad540c3b 100644 --- a/internal/provider/resource_network_test.go +++ b/internal/provider/resource_network_test.go @@ -91,6 +91,37 @@ func TestAccNetwork_dhcp_dns(t *testing.T) { }) } +func TestAccNetwork_v6(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { preCheck(t) }, + ProviderFactories: providerFactories, + // TODO: CheckDestroy: , + Steps: []resource.TestStep{ + { + Config: testAccNetworkConfigV6("10.0.206.0/24", 206, "static", "fd6a:37be:e362::1/64"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("unifi_network.test", "domain_name", "foo.local"), + resource.TestCheckResourceAttr("unifi_network.test", "subnet", "10.0.206.0/24"), + resource.TestCheckResourceAttr("unifi_network.test", "vlan_id", "206"), + resource.TestCheckResourceAttr("unifi_network.test", "ipv6_static_subnet", "fd6a:37be:e362::1/64"), + ), + }, + importStep("unifi_network.test"), + { + Config: testAccNetworkConfigV6("10.0.207.0/24", 207, "static", "fd6a:37be:e363::1/64"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("unifi_network.test", "subnet", "10.0.207.0/24"), + resource.TestCheckResourceAttr("unifi_network.test", "vlan_id", "207"), + resource.TestCheckResourceAttr("unifi_network.test", "ipv6_static_subnet", "fd6a:37be:e363::1/64"), + ), + }, + importStep("unifi_network.test"), + }, + }) +} + +// TODO: ipv6 prefix delegation test + func quoteStrings(src []string) []string { dst := make([]string, 0, len(src)) for _, s := range src { @@ -121,3 +152,27 @@ resource "unifi_network" "test" { } `, subnet, vlan, igmpSnoop, strings.Join(quoteStrings(dhcpDNS), ",")) } + +func testAccNetworkConfigV6(subnet string, vlan int, ipv6Type string, ipv6Subnet string) string { + return fmt.Sprintf(` +variable "subnet" { + default = "%s" +} + +resource "unifi_network" "test" { + name = "tfacc" + purpose = "corporate" + + subnet = var.subnet + vlan_id = %d + dhcp_start = cidrhost(var.subnet, 6) + dhcp_stop = cidrhost(var.subnet, 254) + dhcp_enabled = true + domain_name = "foo.local" + + ipv6_interface_type = "%s" + ipv6_static_subnet = "%s" + ipv6_ra_enable = true +} +`, subnet, vlan, ipv6Type, ipv6Subnet) +}