Add WPA3 support to unifi_wlan

Fixes #154
This commit is contained in:
Paul Tyng
2021-09-10 09:44:12 -04:00
parent d34b25bc10
commit ede214c5c5
6 changed files with 128 additions and 4 deletions

View File

@@ -39,6 +39,10 @@ resource "unifi_wlan" "wifi" {
passphrase = "12345678"
security = "wpapsk"
# enable WPA2/WPA3 support
wpa3_support = true
wpa3_transition = true
network_id = unifi_network.vlan.id
ap_group_ids = [data.unifi_ap_group.default.id]
user_group_id = data.unifi_user_group.default.id
@@ -74,6 +78,8 @@ resource "unifi_wlan" "wifi" {
- **vlan_id** (Number, Deprecated) VLAN ID for the network. Set network_id instead of vlan_id for controller version >= 6.
- **wlan_band** (String) Radio band your WiFi network will use.
- **wlan_group_id** (String, Deprecated) ID of the WLAN group to use for this network. Set ap_group_ids instead of wlan_group_id for controller version >= 6.
- **wpa3_support** (Boolean) Enable WPA 3 support (security must be `wpapsk`).
- **wpa3_transition** (Boolean) Enable WPA 3 and WPA 2 support (security must be `wpapsk` and `wpa3_support` must be true).
### Read-Only

View File

@@ -24,6 +24,10 @@ resource "unifi_wlan" "wifi" {
passphrase = "12345678"
security = "wpapsk"
# enable WPA2/WPA3 support
wpa3_support = true
wpa3_transition = true
network_id = unifi_network.vlan.id
ap_group_ids = [data.unifi_ap_group.default.id]
user_group_id = data.unifi_user_group.default.id

View File

@@ -15,6 +15,9 @@ import (
var (
controllerV5 = version.Must(version.NewVersion("5.0.0"))
controllerV6 = version.Must(version.NewVersion("6.0.0"))
// https://community.ui.com/releases/UniFi-Network-Controller-6-1-61/62f1ad38-1ac5-430c-94b0-becbb8f71d7d
controllerVersionWPA3 = version.Must(version.NewVersion("6.1.61"))
)
func init() {

View File

@@ -85,16 +85,20 @@ func preCheck(t *testing.T) {
}
}
func preCheckV6Only(t *testing.T) {
func preCheckMinVersion(t *testing.T, min *version.Version) {
v, err := version.NewVersion(testClient.Version())
if err != nil {
t.Fatalf("error parsing version: %s", err)
}
if v.LessThan(controllerV6) {
t.Skipf("skipping test on controller version %q", v)
if v.LessThan(min) {
t.Skipf("skipping test on controller version %q (need at least %q)", v, min)
}
}
func preCheckV6Only(t *testing.T) {
preCheckMinVersion(t, controllerV6)
}
func preCheckV5Only(t *testing.T) {
v, err := version.NewVersion(testClient.Version())
if err != nil {

View File

@@ -3,10 +3,10 @@ package provider
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"log"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/paultyng/go-unifi/unifi"
@@ -53,6 +53,16 @@ func resourceWLAN() *schema.Resource {
Required: true,
ValidateFunc: validation.StringInSlice([]string{"wpapsk", "wpaeap", "open"}, false),
},
"wpa3_support": {
Description: "Enable WPA 3 support (security must be `wpapsk`).",
Type: schema.TypeBool,
Optional: true,
},
"wpa3_transition": {
Description: "Enable WPA 3 and WPA 2 support (security must be `wpapsk` and `wpa3_support` must be true).",
Type: schema.TypeBool,
Optional: true,
},
"passphrase": {
Description: "The passphrase for the network, this is only required if `security` is not set to `open`.",
Type: schema.TypeString,
@@ -204,6 +214,22 @@ func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*uni
passphrase = ""
}
wpa3 := d.Get("wpa3_support").(bool)
wpa3Transition := d.Get("wpa3_transition").(bool)
switch security {
case "wpapsk":
// nothing
default:
if wpa3 || wpa3Transition {
return nil, fmt.Errorf("wpa3_support and wpa3_transition are only valid for security type wpapsk")
}
}
if v := c.ControllerVersion(); v.LessThanOrEqual(controllerVersionWPA3) {
if wpa3 || wpa3Transition {
return nil, fmt.Errorf("WPA 3 support is not available on controller version %q, you must be on %q or higher", v, controllerVersionWPA3)
}
}
macFilterEnabled := d.Get("mac_filter_enabled").(bool)
macFilterList, err := setToStringSlice(d.Get("mac_filter_list").(*schema.Set))
if err != nil {
@@ -259,6 +285,8 @@ func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*uni
ApGroupIDs: apGroupIDs,
UserGroupID: d.Get("user_group_id").(string),
Security: security,
WPA3Support: wpa3,
WPA3Transition: wpa3Transition,
MulticastEnhanceEnabled: d.Get("multicast_enhance").(bool),
MACFilterEnabled: macFilterEnabled,
MACFilterList: macFilterList,
@@ -321,9 +349,14 @@ func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData, meta
security := resp.Security
passphrase := resp.XPassphrase
wpa3 := false
wpa3Transition := false
switch security {
case "open":
passphrase = ""
case "wpapsk":
wpa3 = resp.WPA3Support
wpa3Transition = resp.WPA3Transition
}
macFilterEnabled := resp.MACFilterEnabled
@@ -349,6 +382,8 @@ func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData, meta
d.Set("hide_ssid", resp.HideSSID)
d.Set("is_guest", resp.IsGuest)
d.Set("security", security)
d.Set("wpa3_support", wpa3)
d.Set("wpa3_transition", wpa3Transition)
d.Set("multicast_enhance", resp.MulticastEnhanceEnabled)
d.Set("mac_filter_enabled", macFilterEnabled)
d.Set("mac_filter_list", macFilterList)

View File

@@ -285,6 +285,48 @@ func TestAccWLAN_uapsd(t *testing.T) {
})
}
func TestAccWLAN_wpa3(t *testing.T) {
vlanID := getTestVLAN(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
preCheck(t)
preCheckV6Only(t)
preCheckMinVersion(t, controllerVersionWPA3)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
<-wlanConcurrency
return nil
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_wpa3(vlanID, false),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_wpa3(vlanID, true),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_wpa3(vlanID, false),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
},
})
}
func testAccWLANConfig_wpapsk(vlanID int) string {
return fmt.Sprintf(`
data "unifi_ap_group" "default" {
@@ -527,3 +569,33 @@ resource "unifi_wlan" "test" {
}
`, vlanID)
}
func testAccWLANConfig_wpa3(vlanID int, wpa3Transition bool) string {
return fmt.Sprintf(`
data "unifi_ap_group" "default" {
}
data "unifi_user_group" "default" {
}
resource "unifi_network" "test" {
name = "tfacc"
purpose = "corporate"
subnet = cidrsubnet("10.0.0.0/8", 6, %[1]d)
vlan_id = %[1]d
}
resource "unifi_wlan" "test" {
name = "tfacc-wpapsk"
network_id = unifi_network.test.id
passphrase = "12345678"
ap_group_ids = [data.unifi_ap_group.default.id]
user_group_id = data.unifi_user_group.default.id
security = "wpapsk"
wpa3_support = true
wpa3_transition = %[2]t
}
`, vlanID, wpa3Transition)
}