Make provider package internal
This commit is contained in:
53
internal/provider/data_user_group.go
Normal file
53
internal/provider/data_user_group.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func dataUserGroup() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Read: dataUserGroupRead,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "Default",
|
||||
},
|
||||
|
||||
"qos_rate_max_down": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"qos_rate_max_up": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataUserGroupRead(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
|
||||
groups, err := c.c.ListUserGroup(c.site)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, g := range groups {
|
||||
if g.Name == name {
|
||||
d.SetId(g.ID)
|
||||
|
||||
d.Set("qos_rate_max_down", g.QOSRateMaxDown)
|
||||
d.Set("qos_rate_max_up", g.QOSRateMaxUp)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("user group not found with name %s", name)
|
||||
}
|
||||
28
internal/provider/data_user_group_test.go
Normal file
28
internal/provider/data_user_group_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccDataUserGroup_default(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
PreCheck: func() { preCheck(t) },
|
||||
Providers: providers,
|
||||
// TODO: CheckDestroy: ,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccDataUserGroupConfig_default,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const testAccDataUserGroupConfig_default = `
|
||||
data "unifi_user_group" "default" {
|
||||
}
|
||||
`
|
||||
40
internal/provider/data_wlan_group.go
Normal file
40
internal/provider/data_wlan_group.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func dataWLANGroup() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Read: dataWLANGroupRead,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "Default",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataWLANGroupRead(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
|
||||
groups, err := c.c.ListWLANGroup(c.site)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, g := range groups {
|
||||
if g.Name == name {
|
||||
d.SetId(g.ID)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("WLAN group not found with name %s", name)
|
||||
}
|
||||
28
internal/provider/data_wlan_group_test.go
Normal file
28
internal/provider/data_wlan_group_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccDataWLANGroup_default(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
PreCheck: func() { preCheck(t) },
|
||||
Providers: providers,
|
||||
// TODO: CheckDestroy: ,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccDataWLANGroupConfig_default,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const testAccDataWLANGroupConfig_default = `
|
||||
data "unifi_wlan_group" "default" {
|
||||
}
|
||||
`
|
||||
111
internal/provider/lazy_client.go
Normal file
111
internal/provider/lazy_client.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/paultyng/terraform-provider-unifi/unifi"
|
||||
)
|
||||
|
||||
type lazyClient struct {
|
||||
baseURL string
|
||||
user string
|
||||
pass string
|
||||
|
||||
once sync.Once
|
||||
inner *unifi.Client
|
||||
}
|
||||
|
||||
func (c *lazyClient) init() error {
|
||||
var err error
|
||||
c.once.Do(func() {
|
||||
c.inner = &unifi.Client{}
|
||||
err = c.inner.SetBaseURL(c.baseURL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = c.inner.Login(c.user, c.pass)
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *lazyClient) ListUserGroup(site string) ([]unifi.UserGroup, error) {
|
||||
c.init()
|
||||
return c.inner.ListUserGroup(site)
|
||||
}
|
||||
func (c *lazyClient) ListWLANGroup(site string) ([]unifi.WLANGroup, error) {
|
||||
c.init()
|
||||
return c.inner.ListWLANGroup(site)
|
||||
}
|
||||
func (c *lazyClient) DeleteNetwork(site, id, name string) error {
|
||||
c.init()
|
||||
return c.inner.DeleteNetwork(site, id, name)
|
||||
}
|
||||
func (c *lazyClient) CreateNetwork(site string, d *unifi.Network) (*unifi.Network, error) {
|
||||
c.init()
|
||||
return c.inner.CreateNetwork(site, d)
|
||||
}
|
||||
func (c *lazyClient) GetNetwork(site, id string) (*unifi.Network, error) {
|
||||
c.init()
|
||||
return c.inner.GetNetwork(site, id)
|
||||
}
|
||||
func (c *lazyClient) UpdateNetwork(site string, d *unifi.Network) (*unifi.Network, error) {
|
||||
c.init()
|
||||
return c.inner.UpdateNetwork(site, d)
|
||||
}
|
||||
func (c *lazyClient) DeleteWLAN(site, id string) error {
|
||||
c.init()
|
||||
return c.inner.DeleteWLAN(site, id)
|
||||
}
|
||||
func (c *lazyClient) CreateWLAN(site string, d *unifi.WLAN) (*unifi.WLAN, error) {
|
||||
c.init()
|
||||
return c.inner.CreateWLAN(site, d)
|
||||
}
|
||||
func (c *lazyClient) GetWLAN(site, id string) (*unifi.WLAN, error) {
|
||||
c.init()
|
||||
return c.inner.GetWLAN(site, id)
|
||||
}
|
||||
func (c *lazyClient) DeleteUserGroup(site, id string) error {
|
||||
c.init()
|
||||
return c.inner.DeleteUserGroup(site, id)
|
||||
}
|
||||
func (c *lazyClient) CreateUserGroup(site string, d *unifi.UserGroup) (*unifi.UserGroup, error) {
|
||||
c.init()
|
||||
return c.inner.CreateUserGroup(site, d)
|
||||
}
|
||||
func (c *lazyClient) GetUserGroup(site, id string) (*unifi.UserGroup, error) {
|
||||
c.init()
|
||||
return c.inner.GetUserGroup(site, id)
|
||||
}
|
||||
func (c *lazyClient) UpdateUserGroup(site string, d *unifi.UserGroup) (*unifi.UserGroup, error) {
|
||||
c.init()
|
||||
return c.inner.UpdateUserGroup(site, d)
|
||||
}
|
||||
func (c *lazyClient) GetUser(site, id string) (*unifi.User, error) {
|
||||
c.init()
|
||||
return c.inner.GetUser(site, id)
|
||||
}
|
||||
func (c *lazyClient) GetUserByMAC(site, mac string) (*unifi.User, error) {
|
||||
c.init()
|
||||
return c.inner.GetUserByMAC(site, mac)
|
||||
}
|
||||
func (c *lazyClient) CreateUser(site string, d *unifi.User) (*unifi.User, error) {
|
||||
c.init()
|
||||
return c.inner.CreateUser(site, d)
|
||||
}
|
||||
func (c *lazyClient) UpdateUser(site string, d *unifi.User) (*unifi.User, error) {
|
||||
c.init()
|
||||
return c.inner.UpdateUser(site, d)
|
||||
}
|
||||
func (c *lazyClient) DeleteUserByMAC(site, mac string) error {
|
||||
c.init()
|
||||
return c.inner.DeleteUserByMAC(site, mac)
|
||||
}
|
||||
func (c *lazyClient) BlockUserByMAC(site, mac string) error {
|
||||
c.init()
|
||||
return c.inner.BlockUserByMAC(site, mac)
|
||||
}
|
||||
func (c *lazyClient) UnblockUserByMAC(site, mac string) error {
|
||||
c.init()
|
||||
return c.inner.UnblockUserByMAC(site, mac)
|
||||
}
|
||||
107
internal/provider/provider.go
Normal file
107
internal/provider/provider.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
// "fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||
|
||||
"github.com/paultyng/terraform-provider-unifi/unifi"
|
||||
)
|
||||
|
||||
func Provider() terraform.ResourceProvider {
|
||||
p := &schema.Provider{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_USERNAME", ""),
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_PASSWORD", ""),
|
||||
},
|
||||
"api_url": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_API", ""),
|
||||
},
|
||||
"site": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_SITE", "default"),
|
||||
},
|
||||
// "allow_insecure": {
|
||||
// Type: schema.TypeBool,
|
||||
// Optional: true,
|
||||
// Default: false,
|
||||
// },
|
||||
},
|
||||
DataSourcesMap: map[string]*schema.Resource{
|
||||
"unifi_user_group": dataUserGroup(),
|
||||
"unifi_wlan_group": dataWLANGroup(),
|
||||
},
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"unifi_network": resourceNetwork(),
|
||||
"unifi_user_group": resourceUserGroup(),
|
||||
"unifi_user": resourceUser(),
|
||||
"unifi_wlan": resourceWLAN(),
|
||||
},
|
||||
}
|
||||
p.ConfigureFunc = configure(p)
|
||||
return p
|
||||
}
|
||||
|
||||
func configure(p *schema.Provider) schema.ConfigureFunc {
|
||||
return func(d *schema.ResourceData) (interface{}, error) {
|
||||
user := d.Get("username").(string)
|
||||
pass := d.Get("password").(string)
|
||||
baseURL := d.Get("api_url").(string)
|
||||
site := d.Get("site").(string)
|
||||
//insecure := d.Get("allow_insecure").(bool)
|
||||
|
||||
c := &client{
|
||||
c: &lazyClient{
|
||||
user: user,
|
||||
pass: pass,
|
||||
baseURL: baseURL,
|
||||
},
|
||||
site: site,
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
type unifiClient interface {
|
||||
ListUserGroup(site string) ([]unifi.UserGroup, error)
|
||||
DeleteUserGroup(site, id string) error
|
||||
CreateUserGroup(site string, d *unifi.UserGroup) (*unifi.UserGroup, error)
|
||||
GetUserGroup(site, id string) (*unifi.UserGroup, error)
|
||||
UpdateUserGroup(site string, d *unifi.UserGroup) (*unifi.UserGroup, error)
|
||||
|
||||
ListWLANGroup(site string) ([]unifi.WLANGroup, error)
|
||||
|
||||
DeleteNetwork(site, id, name string) error
|
||||
CreateNetwork(site string, d *unifi.Network) (*unifi.Network, error)
|
||||
GetNetwork(site, id string) (*unifi.Network, error)
|
||||
UpdateNetwork(site string, d *unifi.Network) (*unifi.Network, error)
|
||||
|
||||
DeleteWLAN(site, id string) error
|
||||
CreateWLAN(site string, d *unifi.WLAN) (*unifi.WLAN, error)
|
||||
GetWLAN(site, id string) (*unifi.WLAN, error)
|
||||
|
||||
GetUser(site, id string) (*unifi.User, error)
|
||||
GetUserByMAC(site, mac string) (*unifi.User, error)
|
||||
CreateUser(site string, d *unifi.User) (*unifi.User, error)
|
||||
BlockUserByMAC(site, mac string) error
|
||||
UnblockUserByMAC(site, mac string) error
|
||||
UpdateUser(site string, d *unifi.User) (*unifi.User, error)
|
||||
DeleteUserByMAC(site, mac string) error
|
||||
}
|
||||
|
||||
type client struct {
|
||||
c unifiClient
|
||||
site string
|
||||
}
|
||||
74
internal/provider/provider_test.go
Normal file
74
internal/provider/provider_test.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||
|
||||
"github.com/paultyng/terraform-provider-unifi/unifi"
|
||||
)
|
||||
|
||||
var providers map[string]terraform.ResourceProvider
|
||||
var testClient *unifi.Client
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if os.Getenv("TF_ACC") == "" {
|
||||
// short circuit non acceptance test runs
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
providers = map[string]terraform.ResourceProvider{
|
||||
"unifi": Provider(),
|
||||
}
|
||||
|
||||
user := os.Getenv("UNIFI_USERNAME")
|
||||
pass := os.Getenv("UNIFI_PASSWORD")
|
||||
baseURL := os.Getenv("UNIFI_API")
|
||||
|
||||
testClient = &unifi.Client{}
|
||||
testClient.SetBaseURL(baseURL)
|
||||
err := testClient.Login(user, pass)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func TestProvider(t *testing.T) {
|
||||
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func importStep(name string, ignore ...string) resource.TestStep {
|
||||
step := resource.TestStep{
|
||||
ResourceName: name,
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
}
|
||||
|
||||
if len(ignore) > 0 {
|
||||
step.ImportStateVerifyIgnore = ignore
|
||||
}
|
||||
|
||||
return step
|
||||
}
|
||||
|
||||
func preCheck(t *testing.T) {
|
||||
variables := []string{
|
||||
"UNIFI_USERNAME",
|
||||
"UNIFI_PASSWORD",
|
||||
"UNIFI_API",
|
||||
}
|
||||
|
||||
for _, variable := range variables {
|
||||
value := os.Getenv(variable)
|
||||
if value == "" {
|
||||
t.Fatalf("`%s` must be set for acceptance tests!", variable)
|
||||
}
|
||||
}
|
||||
}
|
||||
185
internal/provider/resource_network.go
Normal file
185
internal/provider/resource_network.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
|
||||
"github.com/paultyng/terraform-provider-unifi/unifi"
|
||||
)
|
||||
|
||||
func resourceNetwork() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceNetworkCreate,
|
||||
Read: resourceNetworkRead,
|
||||
Update: resourceNetworkUpdate,
|
||||
Delete: resourceNetworkDelete,
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"purpose": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"corporate", "guest", "vlan-only"}, false),
|
||||
},
|
||||
"vlan_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
"subnet": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"network_group": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "LAN",
|
||||
},
|
||||
"dhcp_start": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"dhcp_stop": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"dhcp_enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"dhcp_lease": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: 86400,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceNetworkCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
req, err := resourceNetworkGetResourceData(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateNetwork(c.site, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(resp.ID)
|
||||
|
||||
return resourceNetworkSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceNetworkGetResourceData(d *schema.ResourceData) (*unifi.Network, error) {
|
||||
vlan := d.Get("vlan_id").(int)
|
||||
|
||||
return &unifi.Network{
|
||||
Name: d.Get("name").(string),
|
||||
Purpose: d.Get("purpose").(string),
|
||||
VLAN: fmt.Sprintf("%d", d.Get("vlan_id").(int)),
|
||||
IPSubnet: d.Get("subnet").(string),
|
||||
NetworkGroup: d.Get("network_group").(string),
|
||||
DHCPDStart: d.Get("dhcp_start").(string),
|
||||
DHCPDStop: d.Get("dhcp_stop").(string),
|
||||
DHCPDEnabled: d.Get("dhcp_enabled").(bool),
|
||||
DHCPDLeaseTime: d.Get("dhcp_lease").(int),
|
||||
|
||||
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"
|
||||
}, nil
|
||||
}
|
||||
|
||||
func resourceNetworkSetResourceData(resp *unifi.Network, d *schema.ResourceData) error {
|
||||
var err error
|
||||
vlan := 0
|
||||
if resp.VLANEnabled {
|
||||
vlan, err = strconv.Atoi(resp.VLAN)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
dhcpLease := resp.DHCPDLeaseTime
|
||||
if resp.DHCPDEnabled && dhcpLease == 0 {
|
||||
dhcpLease = 86400
|
||||
}
|
||||
|
||||
d.Set("name", resp.Name)
|
||||
d.Set("purpose", resp.Purpose)
|
||||
d.Set("vlan_id", vlan)
|
||||
d.Set("subnet", resp.IPSubnet)
|
||||
d.Set("network_group", resp.NetworkGroup)
|
||||
d.Set("dhcp_start", resp.DHCPDStart)
|
||||
d.Set("dhcp_stop", resp.DHCPDStop)
|
||||
d.Set("dhcp_enabled", resp.DHCPDEnabled)
|
||||
d.Set("dhcp_lease", dhcpLease)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceNetworkRead(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
resp, err := c.c.GetNetwork(c.site, id)
|
||||
if _, ok := err.(*unifi.NotFoundError); ok {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceNetworkSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceNetworkUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
req, err := resourceNetworkGetResourceData(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.ID = d.Id()
|
||||
req.SiteID = c.site
|
||||
|
||||
resp, err := c.c.UpdateNetwork(c.site, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceNetworkSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceNetworkDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
id := d.Id()
|
||||
|
||||
err := c.c.DeleteNetwork(c.site, id, name)
|
||||
if _, ok := err.(*unifi.NotFoundError); ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
78
internal/provider/resource_network_test.go
Normal file
78
internal/provider/resource_network_test.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||
|
||||
"github.com/paultyng/terraform-provider-unifi/unifi"
|
||||
)
|
||||
|
||||
func TestAccNetwork_basic(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
Providers: providers,
|
||||
PreCheck: func() { preCheck(t) },
|
||||
// TODO: CheckDestroy: ,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccNetworkConfig("10.0.202.1/24", 202),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
resource.TestCheckResourceAttr("unifi_network.test", "subnet", "10.0.202.1/24"),
|
||||
resource.TestCheckResourceAttr("unifi_network.test", "vlan_id", "202"),
|
||||
),
|
||||
},
|
||||
importStep("unifi_network.test"),
|
||||
{
|
||||
Config: testAccNetworkConfig("10.0.203.1/24", 203),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testCheckNetworkExists(t, "tfacc", nil),
|
||||
resource.TestCheckResourceAttr("unifi_network.test", "subnet", "10.0.203.1/24"),
|
||||
resource.TestCheckResourceAttr("unifi_network.test", "vlan_id", "203"),
|
||||
),
|
||||
},
|
||||
importStep("unifi_network.test"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testCheckNetworkExists(t *testing.T, name string, network *unifi.Network) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
networks, err := testClient.ListNetwork("default")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, net := range networks {
|
||||
if net.Name == name {
|
||||
if network != nil {
|
||||
*network = net
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("unable to find network %q", name)
|
||||
}
|
||||
}
|
||||
|
||||
func testAccNetworkConfig(subnet string, vlan int) 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
|
||||
}
|
||||
`, subnet, vlan)
|
||||
}
|
||||
223
internal/provider/resource_user.go
Normal file
223
internal/provider/resource_user.go
Normal file
@@ -0,0 +1,223 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
|
||||
"github.com/paultyng/terraform-provider-unifi/unifi"
|
||||
)
|
||||
|
||||
func resourceUser() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceUserCreate,
|
||||
Read: resourceUserRead,
|
||||
Update: resourceUserUpdate,
|
||||
Delete: resourceUserDelete,
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"mac": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
|
||||
old = strings.TrimSpace(strings.ReplaceAll(strings.ToLower(old), "-", ":"))
|
||||
new = strings.TrimSpace(strings.ReplaceAll(strings.ToLower(new), "-", ":"))
|
||||
return old == new
|
||||
},
|
||||
// Validation:
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"user_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"note": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"fixed_ip": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
// TODO: Validate
|
||||
},
|
||||
"network_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"blocked": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
// these are "meta" attributes that control TF UX
|
||||
"allow_existing": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
},
|
||||
"skip_forget_on_destroy": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceUserCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
req, err := resourceUserGetResourceData(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
allowExisting := d.Get("allow_existing").(bool)
|
||||
|
||||
resp, err := c.c.CreateUser(c.site, req)
|
||||
if err != nil {
|
||||
apiErr, ok := err.(*unifi.APIError)
|
||||
if !ok || (apiErr.Message != "api.err.MacUsed" || !allowExisting) {
|
||||
return err
|
||||
}
|
||||
|
||||
// mac in use, just absorb it
|
||||
mac := d.Get("mac").(string)
|
||||
existing, err := c.c.GetUserByMAC(c.site, mac)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.ID = existing.ID
|
||||
req.SiteID = existing.SiteID
|
||||
|
||||
resp, err = c.c.UpdateUser(c.site, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
d.SetId(resp.ID)
|
||||
|
||||
if d.Get("blocked").(bool) {
|
||||
err := c.c.BlockUserByMAC(c.site, d.Get("mac").(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return resourceUserSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceUserGetResourceData(d *schema.ResourceData) (*unifi.User, error) {
|
||||
fixedIP := d.Get("fixed_ip").(string)
|
||||
|
||||
return &unifi.User{
|
||||
MAC: d.Get("mac").(string),
|
||||
Name: d.Get("name").(string),
|
||||
UserGroupID: d.Get("user_group_id").(string),
|
||||
Note: d.Get("note").(string),
|
||||
FixedIP: fixedIP,
|
||||
UseFixedIP: fixedIP != "",
|
||||
NetworkID: d.Get("network_id").(string),
|
||||
// not sure if this matters/works
|
||||
Blocked: d.Get("blocked").(bool),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func resourceUserSetResourceData(resp *unifi.User, d *schema.ResourceData) error {
|
||||
fixedIP := ""
|
||||
if resp.UseFixedIP {
|
||||
fixedIP = resp.FixedIP
|
||||
}
|
||||
|
||||
d.Set("mac", resp.MAC)
|
||||
d.Set("name", resp.Name)
|
||||
d.Set("user_group_id", resp.UserGroupID)
|
||||
d.Set("note", resp.Note)
|
||||
d.Set("fixed_ip", fixedIP)
|
||||
d.Set("network_id", resp.NetworkID)
|
||||
d.Set("blocked", resp.Blocked)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceUserRead(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
resp, err := c.c.GetUser(c.site, id)
|
||||
if _, ok := err.(*unifi.NotFoundError); ok {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceUserSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceUserUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
if d.HasChange("blocked") {
|
||||
mac := d.Get("mac").(string)
|
||||
if d.Get("blocked").(bool) {
|
||||
err := c.c.BlockUserByMAC(c.site, mac)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err := c.c.UnblockUserByMAC(c.site, mac)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req, err := resourceUserGetResourceData(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.ID = d.Id()
|
||||
req.SiteID = c.site
|
||||
|
||||
resp, err := c.c.UpdateUser(c.site, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceUserSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceUserDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
if d.Get("skip_forget_on_destroy").(bool) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// lookup MAC instead of trusting state
|
||||
u, err := c.c.GetUser(c.site, id)
|
||||
if _, ok := err.(*unifi.NotFoundError); ok {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = c.c.DeleteUserByMAC(c.site, u.MAC)
|
||||
return err
|
||||
}
|
||||
120
internal/provider/resource_user_group.go
Normal file
120
internal/provider/resource_user_group.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
|
||||
"github.com/paultyng/terraform-provider-unifi/unifi"
|
||||
)
|
||||
|
||||
func resourceUserGroup() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceUserGroupCreate,
|
||||
Read: resourceUserGroupRead,
|
||||
Update: resourceUserGroupUpdate,
|
||||
Delete: resourceUserGroupDelete,
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"qos_rate_max_down": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: -1,
|
||||
// TODO: validate does not equal 0,1
|
||||
},
|
||||
"qos_rate_max_up": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: -1,
|
||||
// TODO: validate does not equal 0,1
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceUserGroupCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
req, err := resourceUserGroupGetResourceData(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateUserGroup(c.site, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(resp.ID)
|
||||
|
||||
return resourceUserGroupSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceUserGroupGetResourceData(d *schema.ResourceData) (*unifi.UserGroup, error) {
|
||||
return &unifi.UserGroup{
|
||||
Name: d.Get("name").(string),
|
||||
QOSRateMaxDown: d.Get("qos_rate_max_down").(int),
|
||||
QOSRateMaxUp: d.Get("qos_rate_max_up").(int),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func resourceUserGroupSetResourceData(resp *unifi.UserGroup, d *schema.ResourceData) error {
|
||||
d.Set("name", resp.Name)
|
||||
d.Set("qos_rate_max_down", resp.QOSRateMaxDown)
|
||||
d.Set("qos_rate_max_up", resp.QOSRateMaxUp)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceUserGroupRead(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
resp, err := c.c.GetUserGroup(c.site, id)
|
||||
if _, ok := err.(*unifi.NotFoundError); ok {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceUserGroupSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceUserGroupUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
req, err := resourceUserGroupGetResourceData(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.ID = d.Id()
|
||||
req.SiteID = c.site
|
||||
|
||||
resp, err := c.c.UpdateUserGroup(c.site, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceUserGroupSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceUserGroupDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
err := c.c.DeleteUserGroup(c.site, id)
|
||||
if _, ok := err.(*unifi.NotFoundError); ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
46
internal/provider/resource_user_group_test.go
Normal file
46
internal/provider/resource_user_group_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccUserGroup_basic(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
Providers: providers,
|
||||
PreCheck: func() { preCheck(t) },
|
||||
// TODO: CheckDestroy: ,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccUserGroupConfig,
|
||||
// Check: resource.ComposeTestCheckFunc(
|
||||
// // testCheckUserGroupExists(t, "name"),
|
||||
// ),
|
||||
},
|
||||
{
|
||||
Config: testAccUserGroupConfig_qos,
|
||||
},
|
||||
importStep("unifi_user_group.test"),
|
||||
{
|
||||
Config: testAccUserGroupConfig,
|
||||
},
|
||||
importStep("unifi_user_group.test"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const testAccUserGroupConfig = `
|
||||
resource "unifi_user_group" "test" {
|
||||
name = "tfacc"
|
||||
}
|
||||
`
|
||||
|
||||
const testAccUserGroupConfig_qos = `
|
||||
resource "unifi_user_group" "test" {
|
||||
name = "tfacc"
|
||||
|
||||
qos_rate_max_up = 2000
|
||||
qos_rate_max_down = 50
|
||||
}
|
||||
`
|
||||
245
internal/provider/resource_user_test.go
Normal file
245
internal/provider/resource_user_test.go
Normal file
@@ -0,0 +1,245 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||
|
||||
"github.com/paultyng/terraform-provider-unifi/unifi"
|
||||
)
|
||||
|
||||
func userImportStep(name string) resource.TestStep {
|
||||
return importStep(name, "allow_existing", "skip_forget_on_destroy")
|
||||
}
|
||||
|
||||
// for test MAC addresses, see https://tools.ietf.org/html/rfc7042#section-2.1.2
|
||||
|
||||
func TestAccUser_basic(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
Providers: providers,
|
||||
PreCheck: func() { preCheck(t) },
|
||||
// TODO: CheckDestroy: ,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccUserConfig("00:00:5E:00:53:00", "tfacc", "tfacc note"),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
resource.TestCheckResourceAttr("unifi_user.test", "note", "tfacc note"),
|
||||
),
|
||||
},
|
||||
userImportStep("unifi_user.test"),
|
||||
{
|
||||
Config: testAccUserConfig("00:00:5E:00:53:00", "tfacc-2", "tfacc note 2"),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("unifi_user.test", "note", "tfacc note 2"),
|
||||
),
|
||||
},
|
||||
userImportStep("unifi_user.test"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccUser_fixed_ip(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
Providers: providers,
|
||||
PreCheck: func() { preCheck(t) },
|
||||
// TODO: CheckDestroy: ,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccUserConfig("00:00:5E:00:53:10", "tfacc", "tfacc fixed ip"),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
resource.TestCheckResourceAttr("unifi_user.test", "fixed_ip", ""),
|
||||
),
|
||||
},
|
||||
userImportStep("unifi_user.test"),
|
||||
{
|
||||
Config: testAccUserConfig_fixedIP("00:00:5E:00:53:10"),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
resource.TestCheckResourceAttr("unifi_user.test", "fixed_ip", "10.1.10.50"),
|
||||
),
|
||||
},
|
||||
userImportStep("unifi_user.test"),
|
||||
{
|
||||
// this passes the network again even though its not used
|
||||
// to avoid a destroy order of operations issue, can
|
||||
// maybe work it out some other way
|
||||
Config: testAccUserConfig_network + testAccUserConfig("00:00:5E:00:53:10", "tfacc", "tfacc fixed ip"),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
resource.TestCheckResourceAttr("unifi_user.test", "fixed_ip", ""),
|
||||
),
|
||||
},
|
||||
userImportStep("unifi_user.test"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccUser_blocking(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
Providers: providers,
|
||||
PreCheck: func() { preCheck(t) },
|
||||
// TODO: CheckDestroy: ,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccUserConfig_block("00:00:5E:00:53:20", false),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
resource.TestCheckResourceAttr("unifi_user.test", "blocked", "false"),
|
||||
),
|
||||
},
|
||||
userImportStep("unifi_user.test"),
|
||||
{
|
||||
Config: testAccUserConfig_block("00:00:5E:00:53:20", true),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
resource.TestCheckResourceAttr("unifi_user.test", "blocked", "true"),
|
||||
),
|
||||
},
|
||||
userImportStep("unifi_user.test"),
|
||||
{
|
||||
Config: testAccUserConfig_block("00:00:5E:00:53:20", false),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
resource.TestCheckResourceAttr("unifi_user.test", "blocked", "false"),
|
||||
),
|
||||
},
|
||||
userImportStep("unifi_user.test"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccUser_existing_mac_allow(t *testing.T) {
|
||||
testMAC := "00:00:5e:00:53:30"
|
||||
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
Providers: providers,
|
||||
PreCheck: func() {
|
||||
preCheck(t)
|
||||
|
||||
_, err := testClient.CreateUser("default", &unifi.User{
|
||||
MAC: testMAC,
|
||||
Name: "tfacc-existing",
|
||||
Note: "tfacc-existing",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
},
|
||||
CheckDestroy: func(*terraform.State) error {
|
||||
// TODO: CheckDestroy: ,
|
||||
|
||||
return testClient.DeleteUserByMAC("default", testMAC)
|
||||
},
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccUserConfig_existing(testMAC, "tfacc", "tfacc note", true, true),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
resource.TestCheckResourceAttr("unifi_user.test", "note", "tfacc note"),
|
||||
),
|
||||
},
|
||||
userImportStep("unifi_user.test"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccUser_existing_mac_deny(t *testing.T) {
|
||||
testMAC := "00:00:5e:00:53:40"
|
||||
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
Providers: providers,
|
||||
PreCheck: func() {
|
||||
preCheck(t)
|
||||
|
||||
_, err := testClient.CreateUser("default", &unifi.User{
|
||||
MAC: testMAC,
|
||||
Name: "tfacc-existing",
|
||||
Note: "tfacc-existing",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
},
|
||||
CheckDestroy: func(*terraform.State) error {
|
||||
// TODO: CheckDestroy: ,
|
||||
|
||||
return testClient.DeleteUserByMAC("default", testMAC)
|
||||
},
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccUserConfig_existing(testMAC, "tfacc", "tfacc note", false, false),
|
||||
ExpectError: regexp.MustCompile("api\\.err\\.MacUsed"),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccUserConfig(mac, name, note string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "unifi_user" "test" {
|
||||
mac = "%s"
|
||||
name = "%s"
|
||||
note = "%s"
|
||||
}
|
||||
`, mac, name, note)
|
||||
}
|
||||
|
||||
const testAccUserConfig_network = `
|
||||
variable "subnet" {
|
||||
default = "10.1.10.1/24"
|
||||
}
|
||||
|
||||
resource "unifi_network" "test" {
|
||||
name = "tfaccfixedip"
|
||||
purpose = "corporate"
|
||||
|
||||
vlan_id = 66
|
||||
subnet = var.subnet
|
||||
dhcp_start = cidrhost(var.subnet, 6)
|
||||
dhcp_stop = cidrhost(var.subnet, 254)
|
||||
dhcp_enabled = true
|
||||
}
|
||||
`
|
||||
|
||||
func testAccUserConfig_fixedIP(mac string) string {
|
||||
return fmt.Sprintf(testAccUserConfig_network+`
|
||||
resource "unifi_user" "test" {
|
||||
mac = "%s"
|
||||
name = "tfacc"
|
||||
note = "tfacc fixed ip"
|
||||
|
||||
fixed_ip = "10.1.10.50"
|
||||
network_id = unifi_network.test.id
|
||||
}
|
||||
`, mac)
|
||||
}
|
||||
|
||||
func testAccUserConfig_block(mac string, blocked bool) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "unifi_user" "test" {
|
||||
mac = "%s"
|
||||
name = "tfacc"
|
||||
note = "tfacc block %t"
|
||||
|
||||
blocked = %t
|
||||
}
|
||||
`, mac, blocked, blocked)
|
||||
}
|
||||
|
||||
func testAccUserConfig_existing(mac, name, note string, allow, skip bool) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "unifi_user" "test" {
|
||||
mac = "%s"
|
||||
name = "%s"
|
||||
note = "%s"
|
||||
|
||||
allow_existing = %t
|
||||
skip_forget_on_destroy = %t
|
||||
}
|
||||
`, mac, name, note, allow, skip)
|
||||
}
|
||||
156
internal/provider/resource_wlan.go
Normal file
156
internal/provider/resource_wlan.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
|
||||
"github.com/paultyng/terraform-provider-unifi/unifi"
|
||||
)
|
||||
|
||||
func resourceWLAN() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceWLANCreate,
|
||||
Read: resourceWLANRead,
|
||||
Update: resourceWLANUpdate,
|
||||
Delete: resourceWLANDelete,
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"vlan_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: 1,
|
||||
},
|
||||
"wlan_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"user_group_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"security": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"wpapsk", "wpaeap", "open"}, false),
|
||||
},
|
||||
"passphrase": {
|
||||
Type: schema.TypeString,
|
||||
// only required if security != open
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
"hide_ssid": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
"is_guest": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceWLANCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
vlan := d.Get("vlan_id").(int)
|
||||
|
||||
req := &unifi.WLAN{
|
||||
Name: d.Get("name").(string),
|
||||
VLAN: fmt.Sprintf("%d", vlan),
|
||||
XPassphrase: d.Get("passphrase").(string),
|
||||
HideSSID: d.Get("hide_ssid").(bool),
|
||||
IsGuest: d.Get("is_guest").(bool),
|
||||
WLANGroupID: d.Get("wlan_group_id").(string),
|
||||
UserGroupID: d.Get("user_group_id").(string),
|
||||
Security: d.Get("security").(string),
|
||||
|
||||
VLANEnabled: vlan != 0 && vlan != 1,
|
||||
|
||||
// TODO: add to schema
|
||||
WPAEnc: "ccmp",
|
||||
WPAMode: "wpa2",
|
||||
Enabled: true,
|
||||
NameCombineEnabled: true,
|
||||
|
||||
GroupRekey: 3600,
|
||||
DTIMMode: "default",
|
||||
No2GhzOui: true,
|
||||
MinrateNgCckRatesEnabled: true,
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateWLAN(c.site, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(resp.ID)
|
||||
|
||||
return resourceWLANSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData) error {
|
||||
var err error
|
||||
vlan := 0
|
||||
if resp.VLANEnabled {
|
||||
vlan, err = strconv.Atoi(resp.VLAN)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
d.Set("name", resp.Name)
|
||||
d.Set("vlan_id", vlan)
|
||||
d.Set("passphrase", resp.XPassphrase)
|
||||
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", resp.Security)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceWLANRead(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
resp, err := c.c.GetWLAN(c.site, id)
|
||||
if _, ok := err.(*unifi.NotFoundError); ok {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceWLANSetResourceData(resp, d)
|
||||
}
|
||||
|
||||
func resourceWLANUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func resourceWLANDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
c := meta.(*client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
err := c.c.DeleteWLAN(c.site, id)
|
||||
if _, ok := err.(*unifi.NotFoundError); ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
110
internal/provider/resource_wlan_test.go
Normal file
110
internal/provider/resource_wlan_test.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||
)
|
||||
|
||||
var wlanConcurrency chan struct{}
|
||||
|
||||
func init() {
|
||||
wcs := os.Getenv("UNIFI_ACC_WLAN_CONCURRENCY")
|
||||
if wcs == "" {
|
||||
// default concurrent SSIDs
|
||||
wcs = "1"
|
||||
}
|
||||
wc, err := strconv.Atoi(wcs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
wlanConcurrency = make(chan struct{}, wc)
|
||||
}
|
||||
|
||||
func TestAccWLAN_wpapsk(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
Providers: providers,
|
||||
PreCheck: func() {
|
||||
preCheck(t)
|
||||
|
||||
wlanConcurrency <- struct{}{}
|
||||
},
|
||||
CheckDestroy: func(*terraform.State) error {
|
||||
// TODO: actual CheckDestroy
|
||||
|
||||
<-wlanConcurrency
|
||||
return nil
|
||||
},
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccWLANConfig_wpapsk,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
),
|
||||
},
|
||||
importStep("unifi_wlan.test"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccWLAN_open(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
Providers: providers,
|
||||
PreCheck: func() {
|
||||
preCheck(t)
|
||||
|
||||
wlanConcurrency <- struct{}{}
|
||||
},
|
||||
CheckDestroy: func(*terraform.State) error {
|
||||
// TODO: actual CheckDestroy
|
||||
|
||||
<-wlanConcurrency
|
||||
return nil
|
||||
},
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccWLANConfig_open,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
// testCheckNetworkExists(t, "name"),
|
||||
),
|
||||
},
|
||||
importStep("unifi_wlan.test"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const testAccWLANConfig_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"
|
||||
}
|
||||
`
|
||||
|
||||
const testAccWLANConfig_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"
|
||||
}
|
||||
`
|
||||
Reference in New Issue
Block a user