Skip to content

Commit

Permalink
feat: create users in the build-in radius server (#286)
Browse files Browse the repository at this point in the history
* feat: account resource with data source

* Adjust docs and validation

* add import test steps

* adjust radius capitalization in docs

Co-authored-by: Paul Tyng <paul@paultyng.net>
  • Loading branch information
bullshit and paultyng committed Oct 23, 2022
1 parent aa54354 commit 115b743
Show file tree
Hide file tree
Showing 12 changed files with 520 additions and 13 deletions.
34 changes: 34 additions & 0 deletions docs/data-sources/account.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "unifi_account Data Source - terraform-provider-unifi"
subcategory: ""
description: |-
unifi_account data source can be used to retrieve RADIUS user accounts
---

# unifi_account (Data Source)

`unifi_account` data source can be used to retrieve RADIUS user accounts



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String) The name of the account to look up

### Optional

- `site` (String) The name of the site the account is associated with.

### Read-Only

- `id` (String) The ID of this account.
- `network_id` (String) ID of the network for this account
- `password` (String, Sensitive) The password of the account.
- `tunnel_medium_type` (Number) See RFC2868 section 3.2
- `tunnel_type` (Number) See RFC2868 section 3.1


2 changes: 1 addition & 1 deletion docs/data-sources/radius_profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ description: |-
### Optional

- `name` (String) The name of the RADIUS profile to look up. Defaults to `Default`.
- `site` (String) The name of the site the radius profile is associated with.
- `site` (String) The name of the site the RADIUS profile is associated with.

### Read-Only

Expand Down
45 changes: 45 additions & 0 deletions docs/resources/account.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "unifi_account Resource - terraform-provider-unifi"
subcategory: ""
description: |-
unifi_account manages a RADIUS user account
To authenticate devices based on MAC address, use the MAC address as the username and password under client creation.
Convert lowercase letters to uppercase, and also remove colons or periods from the MAC address.
ATTENTION: If the user profile does not include a VLAN, the client will fall back to the untagged VLAN.
NOTE: MAC-based authentication accounts can only be used for wireless and wired clients. L2TP remote access does not apply.
---

# unifi_account (Resource)

`unifi_account` manages a RADIUS user account

To authenticate devices based on MAC address, use the MAC address as the username and password under client creation.
Convert lowercase letters to uppercase, and also remove colons or periods from the MAC address.

ATTENTION: If the user profile does not include a VLAN, the client will fall back to the untagged VLAN.

NOTE: MAC-based authentication accounts can only be used for wireless and wired clients. L2TP remote access does not apply.



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String) The name of the account.
- `password` (String, Sensitive) The password of the account.

### Optional

- `network_id` (String) ID of the network for this account
- `site` (String) The name of the site to associate the account with.
- `tunnel_medium_type` (Number) See [RFC 2868](https://www.rfc-editor.org/rfc/rfc2868) section 3.2 Defaults to `6`.
- `tunnel_type` (Number) See [RFC 2868](https://www.rfc-editor.org/rfc/rfc2868) section 3.1 Defaults to `13`.

### Read-Only

- `id` (String) The ID of the account.


10 changes: 5 additions & 5 deletions docs/resources/radius_profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
page_title: "unifi_radius_profile Resource - terraform-provider-unifi"
subcategory: ""
description: |-
unifi_radius_profile manages radius profiles.
unifi_radius_profile manages RADIUS profiles.
---

# unifi_radius_profile (Resource)

`unifi_radius_profile` manages radius profiles.
`unifi_radius_profile` manages RADIUS profiles.



Expand All @@ -21,14 +21,14 @@ description: |-

### Optional

- `accounting_enabled` (Boolean) Specifies whether to use radius accounting. Defaults to `false`.
- `accounting_enabled` (Boolean) Specifies whether to use RADIUS accounting. Defaults to `false`.
- `acct_server` (Block List) RADIUS accounting servers. (see [below for nested schema](#nestedblock--acct_server))
- `auth_server` (Block List) RADIUS authentication servers. (see [below for nested schema](#nestedblock--auth_server))
- `interim_update_enabled` (Boolean) Specifies whether to use interim_update. Defaults to `false`.
- `interim_update_interval` (Number) Specifies interim_update interval. Defaults to `3600`.
- `site` (String) The name of the site to associate the settings with.
- `use_usg_acct_server` (Boolean) Specifies whether to use usg as a radius accounting server. Defaults to `false`.
- `use_usg_auth_server` (Boolean) Specifies whether to use usg as a radius authentication server. Defaults to `false`.
- `use_usg_acct_server` (Boolean) Specifies whether to use usg as a RADIUS accounting server. Defaults to `false`.
- `use_usg_auth_server` (Boolean) Specifies whether to use usg as a RADIUS authentication server. Defaults to `false`.
- `vlan_enabled` (Boolean) Specifies whether to use vlan on wired connections. Defaults to `false`.
- `vlan_wlan_mode` (String) Specifies whether to use vlan on wireless connections. Must be one of `disabled`, `optional`, or `required`. Defaults to ``.

Expand Down
86 changes: 86 additions & 0 deletions internal/provider/data_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package provider

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataAccount() *schema.Resource {
return &schema.Resource{
Description: "`unifi_account` data source can be used to retrieve RADIUS user accounts",

ReadContext: dataAccountRead,

Schema: map[string]*schema.Schema{
"id": {
Description: "The ID of this account.",
Type: schema.TypeString,
Computed: true,
},
"site": {
Description: "The name of the site the account is associated with.",
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"name": {
Description: "The name of the account to look up",
Type: schema.TypeString,
Required: true,
},

"password": {
Description: "The password of the account.",
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
"tunnel_type": {
Description: "See RFC2868 section 3.1", // @TODO: better documentation https://help.ui.com/hc/en-us/articles/360015268353-UniFi-USG-UDM-Configuring-RADIUS-Server#6
Type: schema.TypeInt,
Computed: true,
},
"tunnel_medium_type": {
Description: "See RFC2868 section 3.2", // @TODO: better documentation https://help.ui.com/hc/en-us/articles/360015268353-UniFi-USG-UDM-Configuring-RADIUS-Server#6
Type: schema.TypeInt,
Computed: true,
},
"network_id": {
Description: "ID of the network for this account",
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataAccountRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
c := meta.(*client)

name := d.Get("name").(string)
site := d.Get("site").(string)
if site == "" {
site = c.site
}

accounts, err := c.c.ListAccounts(ctx, site)
if err != nil {
return diag.FromErr(err)
}
for _, account := range accounts {
if account.Name == name {
d.SetId(account.ID)
d.Set("name", account.Name)
d.Set("password", account.XPassword)
d.Set("tunnel_type", account.TunnelType)
d.Set("tunnel_medium_type", account.TunnelMediumType)
d.Set("network_id", account.NetworkID)
d.Set("site", site)
return nil
}
}

return diag.Errorf("Account not found with name %s", name)
}
71 changes: 71 additions & 0 deletions internal/provider/data_account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package provider

import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"testing"
)

func TestAccDataAccount_default(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
preCheck(t)
},
ProviderFactories: providerFactories,
// TODO: CheckDestroy: ,
Steps: []resource.TestStep{
{
Config: testAccDataAccountConfig("tfusertest", "secure_1234"),
Check: resource.ComposeTestCheckFunc(),
},
},
})
}

func TestAccDataAccount_mac(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
preCheck(t)
},
ProviderFactories: providerFactories,
// TODO: CheckDestroy: ,
Steps: []resource.TestStep{
{
Config: testAccDataMacAccountConfig("00B0D06FC226"),
Check: resource.ComposeTestCheckFunc(),
},
},
})
}

func testAccDataAccountConfig(name, password string) string {
return fmt.Sprintf(`
resource "unifi_account" "test" {
name = "%s"
password = "%s"
}
data "unifi_account" "test" {
name = "%s"
depends_on = [
unifi_account.test
]
}
`, name, password, name)
}

func testAccDataMacAccountConfig(mac string) string {
return fmt.Sprintf(`
resource "unifi_account" "test" {
name = "%s"
password = "%s"
}
data "unifi_account" "test" {
name = "%s"
depends_on = [
unifi_account.test
]
}
`, mac, mac, mac)
}
2 changes: 1 addition & 1 deletion internal/provider/data_radius_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func dataRADIUSProfile() *schema.Resource {
Computed: true,
},
"site": {
Description: "The name of the site the radius profile is associated with.",
Description: "The name of the site the RADIUS profile is associated with.",
Type: schema.TypeString,
Computed: true,
Optional: true,
Expand Down
30 changes: 30 additions & 0 deletions internal/provider/lazy_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,36 @@ func (c *lazyClient) UpdateRADIUSProfile(ctx context.Context, site string, d *un
}
return c.inner.UpdateRADIUSProfile(ctx, site, d)
}
func (c *lazyClient) ListAccounts(ctx context.Context, site string) ([]unifi.Account, error) {
if err := c.init(ctx); err != nil {
return nil, err
}
return c.inner.ListAccount(ctx, site)
}
func (c *lazyClient) GetAccount(ctx context.Context, site, id string) (*unifi.Account, error) {
if err := c.init(ctx); err != nil {
return nil, err
}
return c.inner.GetAccount(ctx, site, id)
}
func (c *lazyClient) DeleteAccount(ctx context.Context, site, id string) error {
if err := c.init(ctx); err != nil {
return err
}
return c.inner.DeleteAccount(ctx, site, id)
}
func (c *lazyClient) CreateAccount(ctx context.Context, site string, d *unifi.Account) (*unifi.Account, error) {
if err := c.init(ctx); err != nil {
return nil, err
}
return c.inner.CreateAccount(ctx, site, d)
}
func (c *lazyClient) UpdateAccount(ctx context.Context, site string, d *unifi.Account) (*unifi.Account, error) {
if err := c.init(ctx); err != nil {
return nil, err
}
return c.inner.UpdateAccount(ctx, site, d)
}
func (c *lazyClient) GetSite(ctx context.Context, id string) (*unifi.Site, error) {
if err := c.init(ctx); err != nil {
return nil, err
Expand Down
8 changes: 8 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func New(version string) func() *schema.Provider {
"unifi_radius_profile": dataRADIUSProfile(),
"unifi_user_group": dataUserGroup(),
"unifi_user": dataUser(),
"unifi_account": dataAccount(),
},
ResourcesMap: map[string]*schema.Resource{
// TODO: "unifi_ap_group"
Expand All @@ -91,6 +92,7 @@ func New(version string) func() *schema.Provider {
"unifi_user_group": resourceUserGroup(),
"unifi_user": resourceUser(),
"unifi_wlan": resourceWLAN(),
"unifi_account": resourceAccount(),

"unifi_setting_mgmt": resourceSettingMgmt(),
"unifi_setting_radius": resourceSettingRadius(),
Expand Down Expand Up @@ -187,6 +189,12 @@ type unifiClient interface {
CreateRADIUSProfile(ctx context.Context, site string, d *unifi.RADIUSProfile) (*unifi.RADIUSProfile, error)
UpdateRADIUSProfile(ctx context.Context, site string, d *unifi.RADIUSProfile) (*unifi.RADIUSProfile, error)

ListAccounts(ctx context.Context, site string) ([]unifi.Account, error)
GetAccount(ctx context.Context, site, id string) (*unifi.Account, error)
DeleteAccount(ctx context.Context, site, id string) error
CreateAccount(ctx context.Context, site string, d *unifi.Account) (*unifi.Account, error)
UpdateAccount(ctx context.Context, site string, d *unifi.Account) (*unifi.Account, error)

GetSite(ctx context.Context, id string) (*unifi.Site, error)
ListSites(ctx context.Context) ([]unifi.Site, error)
CreateSite(ctx context.Context, Description string) ([]unifi.Site, error)
Expand Down
Loading

0 comments on commit 115b743

Please sign in to comment.