Add support for controller v6

This commit is contained in:
Paul Tyng
2020-10-19 11:16:05 -04:00
parent 5c30de2319
commit e60a4faa5f
20 changed files with 764 additions and 163 deletions

View File

@@ -2,6 +2,8 @@
set -eou pipefail
default_tag="stable-6"
# Local Administrator
# Username: tfacctest
# Password: tfacctest1234
@@ -26,7 +28,7 @@ case "$1" in
-e TZ='America/New_York' \
-v $(pwd)/testdata/unifi:/unifi \
--name unifi \
jacobalberty/unifi:${2:-stable}
jacobalberty/unifi:${2:-$default_tag}
echo "Waiting for login page..."
timeout 300 bash -c 'while [[ "$(curl --insecure -s -o /dev/null -w "%{http_code}" '"https://localhost:${DOCKER_HTTPS_PORT}/manage/account/login"')" != "200" ]]; do sleep 5; done'
@@ -45,7 +47,7 @@ case "$1" in
docker stop unifi
;;
"update")
docker pull jacobalberty/unifi:${2:-stable}
docker pull jacobalberty/unifi:${2:-$default_tag}
;;
"reset")
git checkout - testdata/unifi/

View File

@@ -0,0 +1,29 @@
---
page_title: "unifi_ap_group Data Source - terraform-provider-unifi"
subcategory: ""
description: |-
unifi_ap_group data source can be used to retrieve the ID for an AP group by name.
---
# Data Source `unifi_ap_group`
`unifi_ap_group` data source can be used to retrieve the ID for an AP group by name.
## Example Usage
```terraform
data "unifi_ap_group" "default" {
}
```
## Schema
### Optional
- **name** (String, Optional) The name of the AP group to look up, leave blank to look up the default AP group.
### Read-only
- **id** (String, Read-only) The ID of this AP group.

View File

@@ -3,24 +3,25 @@ page_title: "unifi_wlan_group Data Source - terraform-provider-unifi"
subcategory: ""
description: |-
unifi_wlan_group data source can be used to retrieve the ID for a WLAN group by name.
Please note that WLAN Groups are deprecated in v6 of the controller.
---
# Data Source `unifi_wlan_group`
`unifi_wlan_group` data source can be used to retrieve the ID for a WLAN group by name.
## Example Usage
Please note that WLAN Groups are deprecated in v6 of the controller.
```terraform
data "unifi_wlan_group" "default" {
}
```
## Schema
### Optional
- **id** (String, Optional) The ID of this resource.
- **name** (String, Optional) The name of the WLAN group to look up. Defaults to `Default`.
### Read-only
- **id** (String, Read-only) The ID of this AP group.

View File

@@ -16,7 +16,7 @@ description: |-
### Optional
- **dst_port** (String, Optional) The destination port for the forwarding.
- **enabled** (Boolean, Optional, Deprecated) Specifies whether the port forwarding rule is enabled or not.
- **enabled** (Boolean, Optional, Deprecated) Specifies whether the port forwarding rule is enabled or not. This will attribute will be removed in a future release. Instead of disabling a port forwarding rule you can remove it from your configuration.
- **fwd_ip** (String, Optional) The IPv4 address to forward traffic to.
- **fwd_port** (String, Optional) The port to forward traffic to.
- **log** (Boolean, Optional) Specifies whether to log forwarded traffic or not. Defaults to `false`.

View File

@@ -35,20 +35,22 @@ resource "unifi_wlan" "wifi" {
- **name** (String, Required) The SSID of the network.
- **security** (String, Required) The type of WiFi security for this network. Valid values are: `wpapsk`, `wpaeap`, and `open`.
- **user_group_id** (String, Required) ID of the user group to use for this network.
- **wlan_group_id** (String, Required) ID of the WLAN group to use for this network.
### Optional
- **ap_group_ids** (Set of String, Optional) IDs of the AP groups to use for this network.
- **hide_ssid** (Boolean, Optional) Indicates whether or not to hide the SSID from broadcast.
- **is_guest** (Boolean, Optional) Indicates that this is a guest WLAN and should use guest behaviors.
- **mac_filter_enabled** (Boolean, Optional) Indicates whether or not the MAC filter is turned of for the network.
- **mac_filter_list** (Set of String, Optional) List of MAC addresses to filter (only valid if `mac_filter_enabled` is `true`).
- **mac_filter_policy** (String, Optional) MAC address filter policy (only valid if `mac_filter_enabled` is `true`). Defaults to `deny`.
- **multicast_enhance** (Boolean, Optional) Indicates whether or not Multicast Enhance is turned of for the network.
- **network_id** (String, Optional) ID of the network for this SSID
- **passphrase** (String, Optional) The passphrase for the network, this is only required if `security` is not set to `open`.
- **radius_profile_id** (String, Optional) ID of the RADIUS profile to use when security `wpaeap`. You can query this via the `unifi_radius_profile` data source.
- **schedule** (Block List) Start and stop schedules for the WLAN (see [below for nested schema](#nestedblock--schedule))
- **vlan_id** (Number, Optional) VLAN ID for the network. Defaults to `1`.
- **vlan_id** (Number, Optional, Deprecated) VLAN ID for the network. Set network_id instead of vlan_id for controller version >= 6.
- **wlan_group_id** (String, Optional, Deprecated) ID of the WLAN group to use for this network. Set ap_group_ids instead of wlan_group_id for controller version >= 6.
### Read-only

View File

@@ -0,0 +1,2 @@
data "unifi_ap_group" "default" {
}

View File

@@ -1,2 +0,0 @@
data "unifi_wlan_group" "default" {
}

5
go.mod
View File

@@ -18,6 +18,7 @@ require (
github.com/hashicorp/go-hclog v0.14.1 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect
github.com/hashicorp/go-version v1.2.1
github.com/hashicorp/terraform-exec v0.11.0 // indirect
github.com/hashicorp/terraform-json v0.6.0 // indirect
github.com/hashicorp/terraform-plugin-docs v0.2.0
@@ -26,8 +27,8 @@ require (
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mitchellh/cli v1.1.2 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/paultyng/go-unifi v1.9.0
github.com/posener/complete v1.2.3 // indirect
github.com/paultyng/go-unifi v1.10.0
github.com/posener/complete v1.2.1 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/zclconf/go-cty v1.6.1 // indirect
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect

36
go.sum
View File

@@ -336,19 +336,17 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/paultyng/go-unifi v1.9.0 h1:kAjTG1WCx0X80Zs1CnjEtIM6vX9cQbiUYK9QZEqLE1E=
github.com/paultyng/go-unifi v1.9.0/go.mod h1:136w8wenUPfYXRTAYtKqYJ/u32ZFMHE9QVD3NQfEcuI=
github.com/paultyng/go-unifi v1.10.0 h1:B42QK7OxW8laPSMpFp+uLh5eX/tskal3qF+5LSGnJVY=
github.com/paultyng/go-unifi v1.10.0/go.mod h1:0QJAKEi4w9CU1qraI3Co2huU1KsklzEbLc5/19MqONE=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/posener/complete v1.2.1 h1:LrvDIY//XNo65Lq84G/akBuMGlawHvGBABv8f/ZN6DI=
github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
@@ -362,13 +360,11 @@ github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk=
github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk=
github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ=
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
@@ -385,18 +381,14 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8=
github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.4.1 h1:Xzr4m4utRDhHDifag1onwwUSq32HLoLBsp+w6tD0880=
github.com/zclconf/go-cty v1.4.1/go.mod h1:nHzOclRkoj++EU9ZjSrZvRG0BXIWt8c7loYc0qXAFGQ=
github.com/zclconf/go-cty v1.6.1 h1:wHtZ+LSSQVwUSb+XIJ5E9hgAQxyWATZsAWT+ESJ9dQ0=
github.com/zclconf/go-cty v1.6.1/go.mod h1:VDR4+I79ubFBGm1uJac1226K5yANQFHeauxPBoP54+o=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
@@ -407,7 +399,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
@@ -463,7 +454,6 @@ golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
@@ -471,7 +461,6 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
@@ -480,10 +469,8 @@ golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0 h1:5kGOVHlq0euqwzgTC9Vu15p6f
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
@@ -519,14 +506,12 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -537,7 +522,6 @@ golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -582,9 +566,7 @@ golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed h1:+qzWo37K31KxduIYaBeMqJ8MUOyTayOQKpH9aDPLMSY=
golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200729181040-64cdafbe085c h1:jLQLIAedRoS9I2Py7l/ZAGGzUxLFsdg42JXEpS/a+ow=
golang.org/x/tools v0.0.0-20200729181040-64cdafbe085c/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
@@ -599,14 +581,12 @@ golang.org/x/tools v0.0.0-20201017001424-6003fad69a88/go.mod h1:z6u4i615ZeAfBE4X
golang.org/x/tools/gopls v0.4.4/go.mod h1:zhyGzA+CAtREUwwq/btQxEx2FHnGzDwJvGs5YqdVCbE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
@@ -618,7 +598,6 @@ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo=
@@ -629,9 +608,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
@@ -662,7 +639,6 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200711021454-869866162049 h1:YFTFpQhgvrLrmxtiIncJxFXeCyq84ixuKWVCaCAi9Oc=
google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@@ -682,11 +658,9 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
@@ -706,7 +680,6 @@ google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -715,7 +688,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=

View File

@@ -0,0 +1,52 @@
package provider
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func dataAPGroup() *schema.Resource {
return &schema.Resource{
Description: "`unifi_ap_group` data source can be used to retrieve the ID for an AP group by name.",
Read: dataAPGroupRead,
Schema: map[string]*schema.Schema{
"id": {
Description: "The ID of this AP group.",
Type: schema.TypeString,
Computed: true,
},
"name": {
Description: "The name of the AP group to look up, leave blank to look up the default AP group.",
Type: schema.TypeString,
Optional: true,
},
},
}
}
func dataAPGroupRead(d *schema.ResourceData, meta interface{}) error {
c := meta.(*client)
if v := c.ControllerVersion(); !v.GreaterThanOrEqual(controllerV6) {
return fmt.Errorf("AP groups are not supported on controller version %q", v)
}
name := d.Get("name").(string)
groups, err := c.c.ListAPGroup(context.TODO(), c.site)
if err != nil {
return err
}
for _, g := range groups {
if (name == "" && g.HiddenID == "default") || g.Name == name {
d.SetId(g.ID)
return nil
}
}
return fmt.Errorf("AP group not found with name %s", name)
}

View File

@@ -0,0 +1,31 @@
package provider
import (
"testing"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)
func TestAccDataAPGroup_default(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
preCheck(t)
preCheckV6Only(t)
},
ProviderFactories: providerFactories,
// TODO: CheckDestroy: ,
Steps: []resource.TestStep{
{
Config: testAccDataAPGroupConfig_default,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
},
})
}
const testAccDataAPGroupConfig_default = `
data "unifi_ap_group" "default" {
}
`

View File

@@ -9,11 +9,19 @@ import (
func dataWLANGroup() *schema.Resource {
return &schema.Resource{
Description: "`unifi_wlan_group` data source can be used to retrieve the ID for a WLAN group by name.",
Description: "`unifi_wlan_group` data source can be used to retrieve the ID for a WLAN group by name.\n\n" +
"Please note that WLAN Groups are deprecated in v6 of the controller.",
DeprecationMessage: "WLAN groups are deprecated in controller version 6 and greater.",
Read: dataWLANGroupRead,
Schema: map[string]*schema.Schema{
"id": {
Description: "The ID of this AP group.",
Type: schema.TypeString,
Computed: true,
},
"name": {
Description: "The name of the WLAN group to look up.",
Type: schema.TypeString,
@@ -27,6 +35,10 @@ func dataWLANGroup() *schema.Resource {
func dataWLANGroupRead(d *schema.ResourceData, meta interface{}) error {
c := meta.(*client)
if v := c.ControllerVersion(); !v.LessThan(controllerV6) {
return fmt.Errorf("WLAN groups are not supported on controller version %q", v)
}
name := d.Get("name").(string)
groups, err := c.c.ListWLANGroup(context.TODO(), c.site)

View File

@@ -8,7 +8,10 @@ import (
func TestAccDataWLANGroup_default(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { preCheck(t) },
PreCheck: func() {
preCheck(t)
preCheckV5Only(t)
},
ProviderFactories: providerFactories,
// TODO: CheckDestroy: ,
Steps: []resource.TestStep{

View File

@@ -3,6 +3,8 @@ package provider
import (
"context"
"crypto/tls"
"fmt"
"log"
"net"
"net/http"
"net/http/cookiejar"
@@ -63,10 +65,18 @@ func (c *lazyClient) init(ctx context.Context) error {
}
initErr = c.inner.Login(ctx, c.user, c.pass)
log.Printf("[TRACE] Unifi controller version: %q", c.inner.Version())
})
return initErr
}
func (c *lazyClient) Version() string {
if err := c.init(context.Background()); err != nil {
panic(fmt.Sprintf("client not initialized: %s", err))
}
return c.inner.Version()
}
func (c *lazyClient) ListUserGroup(ctx context.Context, site string) ([]unifi.UserGroup, error) {
if err := c.init(ctx); err != nil {
return nil, err
@@ -79,6 +89,12 @@ func (c *lazyClient) ListWLANGroup(ctx context.Context, site string) ([]unifi.WL
}
return c.inner.ListWLANGroup(ctx, site)
}
func (c *lazyClient) ListAPGroup(ctx context.Context, site string) ([]unifi.APGroup, error) {
if err := c.init(ctx); err != nil {
return nil, err
}
return c.inner.ListAPGroup(ctx, site)
}
func (c *lazyClient) DeleteNetwork(ctx context.Context, site, id, name string) error {
if err := c.init(ctx); err != nil {
return err

View File

@@ -5,10 +5,16 @@ import (
"fmt"
"strings"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/paultyng/go-unifi/unifi"
)
var (
controllerV5 = version.Must(version.NewVersion("5.0.0"))
controllerV6 = version.Must(version.NewVersion("6.0.0"))
)
func init() {
schema.DescriptionKind = 1
@@ -17,6 +23,9 @@ func init() {
if s.Default != nil {
desc += fmt.Sprintf(" Defaults to `%v`.", s.Default)
}
if s.Deprecated != "" {
desc += " " + s.Deprecated
}
return strings.TrimSpace(desc)
}
}
@@ -65,11 +74,13 @@ func New(version string) func() *schema.Provider {
},
},
DataSourcesMap: map[string]*schema.Resource{
"unifi_ap_group": dataAPGroup(),
"unifi_radius_profile": dataRADIUSProfile(),
"unifi_user_group": dataUserGroup(),
"unifi_wlan_group": dataWLANGroup(),
},
ResourcesMap: map[string]*schema.Resource{
// TODO: "unifi_ap_group"
"unifi_firewall_group": resourceFirewallGroup(),
"unifi_firewall_rule": resourceFirewallRule(),
"unifi_network": resourceNetwork(),
@@ -79,6 +90,7 @@ func New(version string) func() *schema.Provider {
"unifi_wlan": resourceWLAN(),
},
}
p.ConfigureFunc = configure(version, p)
return p
}
@@ -107,6 +119,8 @@ func configure(version string, p *schema.Provider) schema.ConfigureFunc {
}
type unifiClient interface {
Version() string
ListUserGroup(ctx context.Context, site string) ([]unifi.UserGroup, error)
DeleteUserGroup(ctx context.Context, site, id string) error
CreateUserGroup(ctx context.Context, site string, d *unifi.UserGroup) (*unifi.UserGroup, error)
@@ -127,6 +141,8 @@ type unifiClient interface {
ListWLANGroup(ctx context.Context, site string) ([]unifi.WLANGroup, error)
ListAPGroup(ctx context.Context, site string) ([]unifi.APGroup, error)
DeleteNetwork(ctx context.Context, site, id, name string) error
CreateNetwork(ctx context.Context, site string, d *unifi.Network) (*unifi.Network, error)
GetNetwork(ctx context.Context, site, id string) (*unifi.Network, error)
@@ -161,3 +177,7 @@ type client struct {
c unifiClient
site string
}
func (c *client) ControllerVersion() *version.Version {
return version.Must(version.NewVersion(c.c.Version()))
}

View File

@@ -3,8 +3,10 @@ package provider
import (
"context"
"os"
"sync"
"testing"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/paultyng/go-unifi/unifi"
@@ -68,3 +70,43 @@ func preCheck(t *testing.T) {
}
}
}
func preCheckV6Only(t *testing.T) {
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)
}
}
func preCheckV5Only(t *testing.T) {
v, err := version.NewVersion(testClient.Version())
if err != nil {
t.Fatalf("error parsing version: %s", err)
}
if v.GreaterThanOrEqual(controllerV6) {
t.Skipf("skipping test on controller version %q", v)
}
}
const (
vlanMin = 2
vlanMax = 4095
)
var (
vlanLock sync.Mutex
vlanNext = vlanMin
)
func getTestVLAN(t *testing.T) int {
vlanLock.Lock()
defer vlanLock.Unlock()
vl := vlanNext
vlanNext++
return vl
}

View File

@@ -2,6 +2,7 @@ package provider
import (
"fmt"
"strconv"
"strings"
"testing"
@@ -9,26 +10,26 @@ import (
)
func TestAccNetwork_basic(t *testing.T) {
vlanID1 := getTestVLAN(t)
vlanID2 := getTestVLAN(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { preCheck(t) },
ProviderFactories: providerFactories,
// TODO: CheckDestroy: ,
Steps: []resource.TestStep{
{
Config: testAccNetworkConfig("10.0.202.0/24", 202, true, nil),
Config: testAccNetworkConfig(vlanID1, true, nil),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("unifi_network.test", "domain_name", "foo.local"),
resource.TestCheckResourceAttr("unifi_network.test", "subnet", "10.0.202.0/24"),
resource.TestCheckResourceAttr("unifi_network.test", "vlan_id", "202"),
resource.TestCheckResourceAttr("unifi_network.test", "vlan_id", strconv.Itoa(vlanID1)),
resource.TestCheckResourceAttr("unifi_network.test", "igmp_snooping", "true"),
),
},
importStep("unifi_network.test"),
{
Config: testAccNetworkConfig("10.0.203.0/24", 203, false, nil),
Config: testAccNetworkConfig(vlanID2, false, nil),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("unifi_network.test", "subnet", "10.0.203.0/24"),
resource.TestCheckResourceAttr("unifi_network.test", "vlan_id", "203"),
resource.TestCheckResourceAttr("unifi_network.test", "vlan_id", strconv.Itoa(vlanID2)),
resource.TestCheckResourceAttr("unifi_network.test", "igmp_snooping", "false"),
),
},
@@ -38,15 +39,17 @@ func TestAccNetwork_basic(t *testing.T) {
}
func TestAccNetwork_weird_cidr(t *testing.T) {
vlanID := getTestVLAN(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { preCheck(t) },
ProviderFactories: providerFactories,
// TODO: CheckDestroy: ,
Steps: []resource.TestStep{
{
Config: testAccNetworkConfig("10.0.204.3/24", 204, true, nil),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("unifi_network.test", "subnet", "10.0.204.0/24"),
Config: testAccNetworkConfig(vlanID, true, nil),
Check: resource.ComposeTestCheckFunc(
// TODO: ...
),
},
importStep("unifi_network.test"),
@@ -55,20 +58,22 @@ func TestAccNetwork_weird_cidr(t *testing.T) {
}
func TestAccNetwork_dhcp_dns(t *testing.T) {
vlanID := getTestVLAN(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { preCheck(t) },
ProviderFactories: providerFactories,
// TODO: CheckDestroy: ,
Steps: []resource.TestStep{
{
Config: testAccNetworkConfig("10.0.205.0/24", 205, true, []string{"192.168.1.101"}),
Config: testAccNetworkConfig(vlanID, true, []string{"192.168.1.101"}),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("unifi_network.test", "dhcp_dns.0", "192.168.1.101"),
),
},
importStep("unifi_network.test"),
{
Config: testAccNetworkConfig("10.0.205.0/24", 205, true, []string{"192.168.1.101", "192.168.1.102"}),
Config: testAccNetworkConfig(vlanID, true, []string{"192.168.1.101", "192.168.1.102"}),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("unifi_network.test", "dhcp_dns.0", "192.168.1.101"),
resource.TestCheckResourceAttr("unifi_network.test", "dhcp_dns.1", "192.168.1.102"),
@@ -76,13 +81,13 @@ func TestAccNetwork_dhcp_dns(t *testing.T) {
},
importStep("unifi_network.test"),
{
Config: testAccNetworkConfig("10.0.205.0/24", 205, true, nil),
Config: testAccNetworkConfig(vlanID, true, nil),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckNoResourceAttr("unifi_network.test", "dhcp_dns"),
),
},
{
Config: testAccNetworkConfig("10.0.205.0/24", 205, true, []string{"192.168.1.101"}),
Config: testAccNetworkConfig(vlanID, true, []string{"192.168.1.101"}),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("unifi_network.test", "dhcp_dns.0", "192.168.1.101"),
),
@@ -92,26 +97,27 @@ func TestAccNetwork_dhcp_dns(t *testing.T) {
}
func TestAccNetwork_v6(t *testing.T) {
vlanID1 := getTestVLAN(t)
vlanID2 := getTestVLAN(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"),
Config: testAccNetworkConfigV6(vlanID1, "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", "vlan_id", strconv.Itoa(vlanID1)),
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"),
Config: testAccNetworkConfigV6(vlanID2, "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", "vlan_id", strconv.Itoa(vlanID2)),
resource.TestCheckResourceAttr("unifi_network.test", "ipv6_static_subnet", "fd6a:37be:e363::1/64"),
),
},
@@ -130,49 +136,51 @@ func quoteStrings(src []string) []string {
return dst
}
func testAccNetworkConfig(subnet string, vlan int, igmpSnoop bool, dhcpDNS []string) string {
func testAccNetworkConfig(vlan int, igmpSnoop bool, dhcpDNS []string) string {
return fmt.Sprintf(`
variable "subnet" {
default = "%s"
locals {
subnet = cidrsubnet("10.0.0.0/8", 4, %[1]d)
vlan_id = %[1]d
}
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)
subnet = local.subnet
vlan_id = local.vlan_id
dhcp_start = cidrhost(local.subnet, 6)
dhcp_stop = cidrhost(local.subnet, 254)
dhcp_enabled = true
domain_name = "foo.local"
igmp_snooping = %t
igmp_snooping = %[2]t
dhcp_dns = [%s]
dhcp_dns = [%[3]s]
}
`, subnet, vlan, igmpSnoop, strings.Join(quoteStrings(dhcpDNS), ","))
`, vlan, igmpSnoop, strings.Join(quoteStrings(dhcpDNS), ","))
}
func testAccNetworkConfigV6(subnet string, vlan int, ipv6Type string, ipv6Subnet string) string {
func testAccNetworkConfigV6(vlan int, ipv6Type string, ipv6Subnet string) string {
return fmt.Sprintf(`
variable "subnet" {
default = "%s"
locals {
subnet = cidrsubnet("10.0.0.0/8", 4, %[1]d)
vlan_id = %[1]d
}
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)
subnet = local.subnet
vlan_id = local.vlan_id
dhcp_start = cidrhost(local.subnet, 6)
dhcp_stop = cidrhost(local.subnet, 254)
dhcp_enabled = true
domain_name = "foo.local"
ipv6_interface_type = "%s"
ipv6_static_subnet = "%s"
ipv6_interface_type = "%[2]s"
ipv6_static_subnet = "%[3]s"
ipv6_ra_enable = true
}
`, subnet, vlan, ipv6Type, ipv6Subnet)
`, vlan, ipv6Type, ipv6Subnet)
}

View File

@@ -34,17 +34,7 @@ func resourceWLAN() *schema.Resource {
Type: schema.TypeString,
Required: true,
},
"vlan_id": {
Description: "VLAN ID for the network.",
Type: schema.TypeInt,
Optional: true,
Default: 1,
},
"wlan_group_id": {
Description: "ID of the WLAN group to use for this network.",
Type: schema.TypeString,
Required: true,
},
"user_group_id": {
Description: "ID of the user group to use for this network.",
Type: schema.TypeString,
@@ -135,12 +125,45 @@ func resourceWLAN() *schema.Resource {
},
},
},
// controller v6 fields
"network_id": {
Description: "ID of the network for this SSID",
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"vlan_id"},
},
"ap_group_ids": {
Description: "IDs of the AP groups to use for this network.",
Type: schema.TypeSet,
Optional: true,
ConflictsWith: []string{"wlan_group_id"},
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
// controller v5 fields
"vlan_id": {
Description: "VLAN ID for the network.",
Type: schema.TypeInt,
Optional: true,
ConflictsWith: []string{"network_id"},
Deprecated: "Set network_id instead of vlan_id for controller version >= 6.",
},
"wlan_group_id": {
Description: "ID of the WLAN group to use for this network.",
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"ap_group_ids"},
Deprecated: "Set ap_group_ids instead of wlan_group_id for controller version >= 6.",
},
},
}
}
func resourceWLANGetResourceData(d *schema.ResourceData) (*unifi.WLAN, error) {
vlan := d.Get("vlan_id").(int)
func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*unifi.WLAN, error) {
c := meta.(*client)
security := d.Get("security").(string)
passphrase := d.Get("passphrase").(string)
@@ -158,20 +181,46 @@ func resourceWLANGetResourceData(d *schema.ResourceData) (*unifi.WLAN, error) {
macFilterList = nil
}
// version specific fields and validation
networkID := d.Get("network_id").(string)
vlan := d.Get("vlan_id").(int)
apGroupIDs, err := setToStringSlice(d.Get("ap_group_ids").(*schema.Set))
if err != nil {
return nil, err
}
wlanGroupID := d.Get("wlan_group_id").(string)
switch v := c.ControllerVersion(); {
case v.GreaterThanOrEqual(controllerV6):
if wlanGroupID != "" {
return nil, fmt.Errorf("wlan_group_id is not supported on controller version %q", v)
}
if vlan != 0 {
return nil, fmt.Errorf("vlan_id %d is not supported on controller version %q", vlan, v)
}
case v.GreaterThanOrEqual(controllerV5):
if networkID != "" {
return nil, fmt.Errorf("network_id is not supported on controller version %q", v)
}
if len(apGroupIDs) > 0 {
return nil, fmt.Errorf("ap_group_ids is not supported on controller version %q", v)
}
default:
return nil, fmt.Errorf("controller version %q not supported", v)
}
schedule, err := listToScheduleStrings(d.Get("schedule").([]interface{}))
if err != nil {
return nil, fmt.Errorf("unable to process schedule block: %w", err)
}
log.Printf("[TRACE] TF Schedule: %#v", schedule)
return &unifi.WLAN{
Name: d.Get("name").(string),
VLAN: vlan,
XPassphrase: passphrase,
HideSSID: d.Get("hide_ssid").(bool),
IsGuest: d.Get("is_guest").(bool),
WLANGroupID: d.Get("wlan_group_id").(string),
NetworkID: networkID,
ApGroupIDs: apGroupIDs,
UserGroupID: d.Get("user_group_id").(string),
Security: security,
MulticastEnhanceEnabled: d.Get("multicast_enhance").(bool),
@@ -182,6 +231,9 @@ func resourceWLANGetResourceData(d *schema.ResourceData) (*unifi.WLAN, error) {
Schedule: schedule,
ScheduleEnabled: len(schedule) > 0,
// v5
VLAN: vlan,
WLANGroupID: wlanGroupID,
VLANEnabled: vlan != 0 && vlan != 1,
// TODO: add to schema
@@ -200,7 +252,7 @@ func resourceWLANGetResourceData(d *schema.ResourceData) (*unifi.WLAN, error) {
func resourceWLANCreate(d *schema.ResourceData, meta interface{}) error {
c := meta.(*client)
req, err := resourceWLANGetResourceData(d)
req, err := resourceWLANGetResourceData(d, meta)
if err != nil {
return err
}
@@ -212,10 +264,12 @@ func resourceWLANCreate(d *schema.ResourceData, meta interface{}) error {
d.SetId(resp.ID)
return resourceWLANSetResourceData(resp, d)
return resourceWLANSetResourceData(resp, d, meta)
}
func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData) error {
func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData, meta interface{}) error {
// c := meta.(*client)
vlan := 0
if resp.VLANEnabled {
vlan = resp.VLAN
@@ -236,20 +290,19 @@ func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData) error
macFilterPolicy = resp.MACFilterPolicy
}
log.Printf("[TRACE] API Schedule: %#v", resp.Schedule)
apGroupIDs := stringSliceToSet(resp.ApGroupIDs)
log.Printf("[TRACE] API Schedule: %#v", resp.Schedule)
schedule, err := listFromScheduleStrings(resp.Schedule)
if err != nil {
return fmt.Errorf("unable to parse schedule: %w", err)
}
d.Set("name", resp.Name)
d.Set("vlan_id", vlan)
d.Set("user_group_id", resp.UserGroupID)
d.Set("passphrase", passphrase)
d.Set("hide_ssid", resp.HideSSID)
d.Set("is_guest", resp.IsGuest)
d.Set("wlan_group_id", resp.WLANGroupID)
d.Set("user_group_id", resp.UserGroupID)
d.Set("security", security)
d.Set("multicast_enhance", resp.MulticastEnhanceEnabled)
d.Set("mac_filter_enabled", macFilterEnabled)
@@ -258,6 +311,15 @@ func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData) error
d.Set("radius_profile_id", resp.RADIUSProfileID)
d.Set("schedule", schedule)
// switch v := c.ControllerVersion(); {
// case v.GreaterThanOrEqual(controllerV6):
d.Set("ap_group_ids", apGroupIDs)
d.Set("network_id", resp.NetworkID)
// case v.GreaterThanOrEqual(controllerV5):
d.Set("vlan_id", vlan)
d.Set("wlan_group_id", resp.WLANGroupID)
// }
return nil
}
@@ -275,13 +337,13 @@ func resourceWLANRead(d *schema.ResourceData, meta interface{}) error {
return err
}
return resourceWLANSetResourceData(resp, d)
return resourceWLANSetResourceData(resp, d, meta)
}
func resourceWLANUpdate(d *schema.ResourceData, meta interface{}) error {
c := meta.(*client)
req, err := resourceWLANGetResourceData(d)
req, err := resourceWLANGetResourceData(d, meta)
if err != nil {
return err
}
@@ -294,7 +356,7 @@ func resourceWLANUpdate(d *schema.ResourceData, meta interface{}) error {
return err
}
return resourceWLANSetResourceData(resp, d)
return resourceWLANSetResourceData(resp, d, meta)
}
func resourceWLANDelete(d *schema.ResourceData, meta interface{}) error {

View File

@@ -1,6 +1,7 @@
package provider
import (
"fmt"
"os"
"strconv"
"testing"
@@ -28,21 +29,22 @@ func init() {
wlanConcurrency = make(chan struct{}, wc)
}
func wlanPreCheck(t *testing.T) func() {
return func() {
if cap(wlanConcurrency) == 0 {
t.Skip("concurrency for WLAN testing set to 0")
}
preCheck(t)
wlanConcurrency <- struct{}{}
func wlanPreCheck(t *testing.T) {
if cap(wlanConcurrency) == 0 {
t.Skip("concurrency for WLAN testing set to 0")
}
wlanConcurrency <- struct{}{}
}
func TestAccWLAN_wpapsk(t *testing.T) {
vlanID := getTestVLAN(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: wlanPreCheck(t),
PreCheck: func() {
preCheck(t)
preCheckV6Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
@@ -52,7 +54,7 @@ func TestAccWLAN_wpapsk(t *testing.T) {
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_wpapsk,
Config: testAccWLANConfig_wpapsk(vlanID),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
@@ -63,8 +65,13 @@ func TestAccWLAN_wpapsk(t *testing.T) {
}
func TestAccWLAN_open(t *testing.T) {
vlanID := getTestVLAN(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: wlanPreCheck(t),
PreCheck: func() {
preCheck(t)
preCheckV6Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
@@ -74,21 +81,21 @@ func TestAccWLAN_open(t *testing.T) {
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_open,
Config: testAccWLANConfig_open(vlanID),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_open_mac_filter,
Config: testAccWLANConfig_open_mac_filter(vlanID),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_open,
Config: testAccWLANConfig_open(vlanID),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
@@ -99,8 +106,13 @@ func TestAccWLAN_open(t *testing.T) {
}
func TestAccWLAN_change_security(t *testing.T) {
vlanID := getTestVLAN(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: wlanPreCheck(t),
PreCheck: func() {
preCheck(t)
preCheckV6Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
@@ -110,21 +122,21 @@ func TestAccWLAN_change_security(t *testing.T) {
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_wpapsk,
Config: testAccWLANConfig_wpapsk(vlanID),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_open,
Config: testAccWLANConfig_open(vlanID),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_wpapsk,
Config: testAccWLANConfig_wpapsk(vlanID),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
@@ -134,8 +146,13 @@ func TestAccWLAN_change_security(t *testing.T) {
}
func TestAccWLAN_schedule(t *testing.T) {
vlanID := getTestVLAN(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: wlanPreCheck(t),
PreCheck: func() {
preCheck(t)
preCheckV6Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
@@ -145,7 +162,7 @@ func TestAccWLAN_schedule(t *testing.T) {
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_schedule,
Config: testAccWLANConfig_schedule(vlanID),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
@@ -160,8 +177,14 @@ func TestAccWLAN_wpaeap(t *testing.T) {
t.Skip("UNIFI_TEST_RADIUS not set, skipping RADIUS test")
}
vlanID := getTestVLAN(t)
resource.ParallelTest(t, resource.TestCase{
PreCheck: wlanPreCheck(t),
PreCheck: func() {
preCheck(t)
preCheckV6Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
@@ -171,7 +194,7 @@ func TestAccWLAN_wpaeap(t *testing.T) {
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_wpaeap,
Config: testAccWLANConfig_wpaeap(vlanID),
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
@@ -181,27 +204,38 @@ func TestAccWLAN_wpaeap(t *testing.T) {
})
}
const testAccWLANConfig_wpapsk = `
data "unifi_wlan_group" "default" {
func testAccWLANConfig_wpapsk(vlanID int) 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", 4, %[1]d)
vlan_id = %[1]d
}
resource "unifi_wlan" "test" {
name = "tfacc-wpapsk"
vlan_id = 202
network_id = unifi_network.test.id
passphrase = "12345678"
wlan_group_id = data.unifi_wlan_group.default.id
ap_group_ids = [data.unifi_ap_group.default.id]
user_group_id = data.unifi_user_group.default.id
security = "wpapsk"
multicast_enhance = true
}
`
`, vlanID)
}
const testAccWLANConfig_wpaeap = `
data "unifi_wlan_group" "default" {
func testAccWLANConfig_wpaeap(vlanID int) string {
return fmt.Sprintf(`
data "unifi_ap_group" "default" {
}
data "unifi_user_group" "default" {
@@ -210,45 +244,73 @@ data "unifi_user_group" "default" {
data "unifi_radius_profile" "default" {
}
resource "unifi_network" "test" {
name = "tfacc"
purpose = "corporate"
subnet = cidrsubnet("10.0.0.0/8", 4, %[1]d)
vlan_id = %[1]d
}
resource "unifi_wlan" "test" {
name = "tfacc-wpapsk"
vlan_id = 202
network_id = unifi_network.test.id
passphrase = "12345678"
wlan_group_id = data.unifi_wlan_group.default.id
ap_group_ids = [data.unifi_ap_group.default.id]
user_group_id = data.unifi_user_group.default.id
security = "wpaeap"
radius_profile_id = data.unifi_radius_profile.default.id
}
`
`, vlanID)
}
const testAccWLANConfig_open = `
data "unifi_wlan_group" "default" {
func testAccWLANConfig_open(vlanID int) 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", 4, %[1]d)
vlan_id = %[1]d
}
resource "unifi_wlan" "test" {
name = "tfacc-open"
vlan_id = 202
wlan_group_id = data.unifi_wlan_group.default.id
network_id = unifi_network.test.id
ap_group_ids = [data.unifi_ap_group.default.id]
user_group_id = data.unifi_user_group.default.id
security = "open"
}
`
`, vlanID)
}
const testAccWLANConfig_schedule = `
data "unifi_wlan_group" "default" {
func testAccWLANConfig_schedule(vlanID int) 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", 4, %[1]d)
vlan_id = %[1]d
}
resource "unifi_wlan" "test" {
name = "tfacc-open-schedule"
vlan_id = 202
wlan_group_id = data.unifi_wlan_group.default.id
network_id = unifi_network.test.id
ap_group_ids = [data.unifi_ap_group.default.id]
user_group_id = data.unifi_user_group.default.id
security = "open"
@@ -264,19 +326,29 @@ resource "unifi_wlan" "test" {
block_end = "17:00"
}
}
`
`, vlanID)
}
const testAccWLANConfig_open_mac_filter = `
data "unifi_wlan_group" "default" {
func testAccWLANConfig_open_mac_filter(vlanID int) 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", 4, %[1]d)
vlan_id = %[1]d
}
resource "unifi_wlan" "test" {
name = "tfacc-open"
vlan_id = 202
wlan_group_id = data.unifi_wlan_group.default.id
network_id = unifi_network.test.id
ap_group_ids = [data.unifi_ap_group.default.id]
user_group_id = data.unifi_user_group.default.id
security = "open"
@@ -284,4 +356,5 @@ resource "unifi_wlan" "test" {
mac_filter_list = ["ab:cd:ef:12:34:56"]
mac_filter_policy = "allow"
}
`
`, vlanID)
}

View File

@@ -0,0 +1,275 @@
package provider
import (
"os"
"testing"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)
func TestAccWLAN_v5_wpapsk(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
preCheck(t)
preCheckV5Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
<-wlanConcurrency
return nil
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_v5_wpapsk,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
},
})
}
func TestAccWLAN_v5_open(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
preCheck(t)
preCheckV5Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
<-wlanConcurrency
return nil
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_v5_open,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_v5_open_mac_filter,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_v5_open,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
},
})
}
func TestAccWLAN_v5_change_security(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
preCheck(t)
preCheckV5Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
<-wlanConcurrency
return nil
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_v5_wpapsk,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_v5_open,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
{
Config: testAccWLANConfig_v5_wpapsk,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
},
})
}
func TestAccWLAN_v5_schedule(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
preCheck(t)
preCheckV5Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
<-wlanConcurrency
return nil
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_v5_schedule,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
},
})
}
func TestAccWLAN_v5_wpaeap(t *testing.T) {
if os.Getenv("UNIFI_TEST_RADIUS") == "" {
t.Skip("UNIFI_TEST_RADIUS not set, skipping RADIUS test")
}
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
preCheck(t)
preCheckV5Only(t)
wlanPreCheck(t)
},
ProviderFactories: providerFactories,
CheckDestroy: func(*terraform.State) error {
// TODO: actual CheckDestroy
<-wlanConcurrency
return nil
},
Steps: []resource.TestStep{
{
Config: testAccWLANConfig_v5_wpaeap,
Check: resource.ComposeTestCheckFunc(
// testCheckNetworkExists(t, "name"),
),
},
importStep("unifi_wlan.test"),
},
})
}
const testAccWLANConfig_v5_wpapsk = `
data "unifi_wlan_group" "default" {
}
data "unifi_user_group" "default" {
}
resource "unifi_wlan" "test" {
name = "tfacc-wpapsk"
vlan_id = 202
passphrase = "12345678"
wlan_group_id = data.unifi_wlan_group.default.id
user_group_id = data.unifi_user_group.default.id
security = "wpapsk"
multicast_enhance = true
}
`
const testAccWLANConfig_v5_wpaeap = `
data "unifi_wlan_group" "default" {
}
data "unifi_user_group" "default" {
}
data "unifi_radius_profile" "default" {
}
resource "unifi_wlan" "test" {
name = "tfacc-wpapsk"
vlan_id = 202
passphrase = "12345678"
wlan_group_id = data.unifi_wlan_group.default.id
user_group_id = data.unifi_user_group.default.id
security = "wpaeap"
radius_profile_id = data.unifi_radius_profile.default.id
}
`
const testAccWLANConfig_v5_open = `
data "unifi_wlan_group" "default" {
}
data "unifi_user_group" "default" {
}
resource "unifi_wlan" "test" {
name = "tfacc-open"
vlan_id = 202
wlan_group_id = data.unifi_wlan_group.default.id
user_group_id = data.unifi_user_group.default.id
security = "open"
}
`
const testAccWLANConfig_v5_schedule = `
data "unifi_wlan_group" "default" {
}
data "unifi_user_group" "default" {
}
resource "unifi_wlan" "test" {
name = "tfacc-open-schedule"
vlan_id = 202
wlan_group_id = data.unifi_wlan_group.default.id
user_group_id = data.unifi_user_group.default.id
security = "open"
schedule {
day_of_week = "mon"
block_start = "03:00"
block_end = "9:00"
}
schedule {
day_of_week = "wed"
block_start = "13:00"
block_end = "17:00"
}
}
`
const testAccWLANConfig_v5_open_mac_filter = `
data "unifi_wlan_group" "default" {
}
data "unifi_user_group" "default" {
}
resource "unifi_wlan" "test" {
name = "tfacc-open"
vlan_id = 202
wlan_group_id = data.unifi_wlan_group.default.id
user_group_id = data.unifi_user_group.default.id
security = "open"
mac_filter_enabled = true
mac_filter_list = ["ab:cd:ef:12:34:56"]
mac_filter_policy = "allow"
}
`