diff --git a/README.md b/README.md index 6e0b067..5cc6b81 100644 --- a/README.md +++ b/README.md @@ -13,159 +13,3 @@ You can download a pre-built binary from the [releases](https://github.com/pault If you want to build from source, you can simply use `go build` in the root of the repository. To use an external provider binary with Terraform ([until the provider registry is GA](https://www.hashicorp.com/blog/announcing-providers-in-the-new-terraform-registry/)), you need to place the binary in a [plugin location for Terraform](https://www.terraform.io/docs/configuration/providers.html#third-party-plugins) to find it. - -## Examples - -### Clients (Users) with optional fixed IPs from CSV - -```terraform -locals { - userscsv = csvdecode(file("${path.module}/users.csv")) - users = { for user in local.userscsv : user.mac => user } -} - -resource "unifi_user" "user" { - for_each = local.users - - mac = each.key - name = each.value.name - # append an optional additional note - note = trimspace("${each.value.note}\n\nmanaged by TF") - - fixed_ip = each.value.fixed_ip - # this assumes there is a unifi_network for_each with names - network_id = each.value.network != "" ? unifi_network.vlan[each.value.network].id : "" - - allow_existing = true - skip_forget_on_destroy = true -} -``` - -```csv -mac,name,note,network,fixed_ip -00:00:00:00:00:00,My Device,custom note,,, -00:00:00:00:00:00,My Device,custom note,network name to lookup,10.0.3.4 -``` - -### WIFI (WLAN) and Network for VLAN - -This example sets up a WIFI SSID and VLAN with bandwidth throttling: - -```terraform -variable "vlan_id" { - default = 10 -} - -data "unifi_wlan_group" "default" { -} - -resource "unifi_user_group" "wifi" { - name = "wifi" - - qos_rate_max_down = 10000000 - qos_rate_max_up = 2000000 -} - -resource "unifi_wlan" "wifi" { - name = "myssid" - vlan_id = var.vlan_id - passphrase = "12345678" - wlan_group_id = data.unifi_wlan_group.default.id - user_group_id = unifi_user_group.wifi.id - security = "wpapsk" -} - -resource "unifi_network" "vlan" { - name = "wifi-vlan" - purpose = "corporate" - - subnet = "10.0.0.1/24" - vlan_id = var.vlan_id - dhcp_start = "10.0.0.6" - dhcp_stop = "10.0.0.254" - dhcp_enabled = true -} -``` - -## Provider configuration - -```terraform -provider "unifi" { - username = "user" // optionally use UNIFI_USERNAME env var - password = "pass" // optionally use UNIFI_PASSWORD env var - api_url = "https://localhost:8443/api/" // optionally use UNIFI_API env var - - // if you are not configuring the default site, you can change the site - site = "foo" // optionally use UNIFI_SITE env var -} -``` - -## Resources - -### unifi_network - -Example: - -```terraform -resource "unifi_network" "test" { - name = "foo" - purpose = "corporate" - - subnet = "10.0.202.1/24" - vlan_id = 202 - dhcp_start = "10.0.202.6" - dhcp_stop = "10.0.202.254" - dhcp_enabled = true -} -``` - -### unifi_user - -User's (called "Clients" in the UI), are unique as they are "created" when observed, so the resource defaults to allowing itself to just take over management of a MAC address, but this can be turned off. - -Example: - -```terraform -resource "unifi_user" "test" { - mac = "00:00:5e:00:53:10" - name = "some client" - note = "my note" - - fixed_ip = "10.1.10.50" - network_id = unifi_network.my_vlan.id -} -``` - -### unifi_user_group - -Example: - -```terraform -resource "unifi_user_group" "test" { - name = "foo" - - qos_rate_max_down = 2000 # 2mbps - qos_rate_max_up = 10 # 10kbps -} -``` - -### unifi_wlan - -Example: - -```terraform -data "unifi_wlan_group" "default" { -} - -data "unifi_user_group" "default" { -} - -resource "unifi_wlan" "test" { - name = "foo" - 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" -} -``` diff --git a/docs/guides/csv-users.html.markdown.tmpl b/docs/guides/csv-users.html.markdown.tmpl new file mode 100644 index 0000000..060976d --- /dev/null +++ b/docs/guides/csv-users.html.markdown.tmpl @@ -0,0 +1,16 @@ +--- +subcategory: "" +page_title: "Manage Users/Clients in a CSV - Unifi Provider" +description: |- + An example of using a CSV to manage all of your users of your network. +--- + +# Manage Users in a CSV + +Given a CSV file with the following content: + +{{ codefile "csv" "examples/csv_users/users.csv" }} + +You could create/manage a `unifi_user` for every row/MAC address in the CSV with the following config: + +{{ tffile "examples/csv_users/users.tf" }} diff --git a/docs/index.html.markdown.tmpl b/docs/index.html.markdown.tmpl new file mode 100644 index 0000000..a60e95f --- /dev/null +++ b/docs/index.html.markdown.tmpl @@ -0,0 +1,14 @@ +--- +layout: "" +page_title: "Provider: Unifi" +description: |- + The Unifi provider provides resources to interact with a Unifi controller API. +--- + +# Unifi Provider + +The Unifi provider provides resources to interact with a Unifi controller API. + +## Example Usage + +{{tffile "examples/provider/provider.tf"}} diff --git a/examples/csv_users/users.csv b/examples/csv_users/users.csv new file mode 100644 index 0000000..92fb444 --- /dev/null +++ b/examples/csv_users/users.csv @@ -0,0 +1,3 @@ +mac,name,note,network,fixed_ip +00:00:00:00:00:00,My Device,custom note,,, +00:00:00:00:00:00,My Device,custom note,network name to lookup,10.0.3.4 diff --git a/examples/csv_users/users.tf b/examples/csv_users/users.tf new file mode 100644 index 0000000..7b73f78 --- /dev/null +++ b/examples/csv_users/users.tf @@ -0,0 +1,20 @@ +locals { + userscsv = csvdecode(file("${path.module}/users.csv")) + users = { for user in local.userscsv : user.mac => user } +} + +resource "unifi_user" "user" { + for_each = local.users + + mac = each.key + name = each.value.name + # append an optional additional note + note = trimspace("${each.value.note}\n\nmanaged by TF") + + fixed_ip = each.value.fixed_ip + # this assumes there is a unifi_network for_each with names + network_id = each.value.network != "" ? unifi_network.vlan[each.value.network].id : "" + + allow_existing = true + skip_forget_on_destroy = true +} \ No newline at end of file diff --git a/examples/datasources/unifi_wlan_group/datasource.tf b/examples/datasources/unifi_wlan_group/datasource.tf new file mode 100644 index 0000000..c985a7f --- /dev/null +++ b/examples/datasources/unifi_wlan_group/datasource.tf @@ -0,0 +1,2 @@ +data "unifi_wlan_group" "default" { +} \ No newline at end of file diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf new file mode 100644 index 0000000..b038131 --- /dev/null +++ b/examples/provider/provider.tf @@ -0,0 +1,8 @@ +provider "unifi" { + username = var.username # optionally use UNIFI_USERNAME env var + password = var.password # optionally use UNIFI_PASSWORD env var + api_url = var.api_url # optionally use UNIFI_API env var + + # if you are not configuring the default site, you can change the site + # site = "foo" or optionally use UNIFI_SITE env var +} \ No newline at end of file diff --git a/examples/provider/test.tf b/examples/provider/test.tf new file mode 100644 index 0000000..c985a7f --- /dev/null +++ b/examples/provider/test.tf @@ -0,0 +1,2 @@ +data "unifi_wlan_group" "default" { +} \ No newline at end of file diff --git a/examples/provider/variables.tf b/examples/provider/variables.tf new file mode 100644 index 0000000..a448f11 --- /dev/null +++ b/examples/provider/variables.tf @@ -0,0 +1,8 @@ +variable "username" { +} + +variable "password" { +} + +variable "api_url" { +} \ No newline at end of file diff --git a/examples/resources/unifi_network/resource.tf b/examples/resources/unifi_network/resource.tf new file mode 100644 index 0000000..d6c0878 --- /dev/null +++ b/examples/resources/unifi_network/resource.tf @@ -0,0 +1,14 @@ +variable "vlan_id" { + default = 10 +} + +resource "unifi_network" "vlan" { + name = "wifi-vlan" + purpose = "corporate" + + subnet = "10.0.0.1/24" + vlan_id = var.vlan_id + dhcp_start = "10.0.0.6" + dhcp_stop = "10.0.0.254" + dhcp_enabled = true +} \ No newline at end of file diff --git a/examples/resources/unifi_user/resource.tf b/examples/resources/unifi_user/resource.tf new file mode 100644 index 0000000..f1f2f8b --- /dev/null +++ b/examples/resources/unifi_user/resource.tf @@ -0,0 +1,8 @@ +resource "unifi_user" "test" { + mac = "01:23:45:67:89:AB" + name = "some client" + note = "my note" + + fixed_ip = "10.1.10.50" + network_id = unifi_network.my_vlan.id +} \ No newline at end of file diff --git a/examples/resources/unifi_user/test.tf b/examples/resources/unifi_user/test.tf new file mode 100644 index 0000000..ecaa4ec --- /dev/null +++ b/examples/resources/unifi_user/test.tf @@ -0,0 +1,14 @@ +variable "vlan_id" { + default = 10 +} + +resource "unifi_network" "my_vlan" { + name = "wifi-vlan" + purpose = "corporate" + + subnet = "10.0.0.1/24" + vlan_id = var.vlan_id + dhcp_start = "10.0.0.6" + dhcp_stop = "10.0.0.254" + dhcp_enabled = true +} \ No newline at end of file diff --git a/examples/resources/unifi_user_group/resource.tf b/examples/resources/unifi_user_group/resource.tf new file mode 100644 index 0000000..8b90ef0 --- /dev/null +++ b/examples/resources/unifi_user_group/resource.tf @@ -0,0 +1,6 @@ +resource "unifi_user_group" "wifi" { + name = "wifi" + + qos_rate_max_down = 2000 # 2mbps + qos_rate_max_up = 10 # 10kbps +} \ No newline at end of file diff --git a/examples/resources/unifi_wlan/resource.tf b/examples/resources/unifi_wlan/resource.tf new file mode 100644 index 0000000..c4bc9c3 --- /dev/null +++ b/examples/resources/unifi_wlan/resource.tf @@ -0,0 +1,14 @@ +data "unifi_wlan_group" "default" { +} + +data "unifi_user_group" "default" { +} + +resource "unifi_wlan" "wifi" { + name = "myssid" + vlan_id = 10 + passphrase = "12345678" + wlan_group_id = data.unifi_wlan_group.default.id + user_group_id = data.unifi_user_group.default.id + security = "wpapsk" +} diff --git a/go.mod b/go.mod index 748dc9b..0db28d7 100644 --- a/go.mod +++ b/go.mod @@ -9,12 +9,14 @@ require ( github.com/go-test/deep v1.0.4 // indirect github.com/hashicorp/go-hclog v0.10.1 // indirect github.com/hashicorp/hcl/v2 v2.2.0 // indirect + github.com/hashicorp/terraform-json v0.5.0 // indirect github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.0-rc.1.0.20200513175959-048e70e44356 github.com/hashicorp/yamux v0.0.0-20190923154419-df201c70410d // indirect github.com/mattn/go-isatty v0.0.11 // indirect github.com/paultyng/go-unifi v1.3.0 github.com/stretchr/testify v1.4.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect + github.com/zclconf/go-cty v1.4.0 // indirect google.golang.org/appengine v1.6.5 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.2.7 // indirect diff --git a/go.sum b/go.sum index a8056d5..72ca619 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFU github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/apparentlymart/go-textseg/v12 v12.0.0 h1:bNEQyAGak9tojivJNkoqWErVCQbjdL7GzRt3F8NvfJ0= +github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/aws/aws-sdk-go v1.15.78 h1:LaXy6lWR0YK7LKyuU0QWy2ws/LWTPfYV/UgfiBu4tvY= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= @@ -104,6 +106,8 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/terraform-json v0.4.0 h1:KNh29iNxozP5adfUFBJ4/fWd0Cu3taGgjHB38JYqOF4= github.com/hashicorp/terraform-json v0.4.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= +github.com/hashicorp/terraform-json v0.5.0 h1:7TV3/F3y7QVSuN4r9BEXqnWqrAyeOtON8f0wvREtyzs= +github.com/hashicorp/terraform-json v0.5.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.0-rc.1.0.20200513175959-048e70e44356 h1:sVX14BRZf6dFYzUzi8zl2Lx1SPo1Eoq/HXrG6+7oyqo= github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.0-rc.1.0.20200513175959-048e70e44356/go.mod h1:UJ9o0QBh28qqmV3eLZJfjPXJXjo5IRpD1lMM2QDf0yQ= github.com/hashicorp/terraform-plugin-test v1.3.0 h1:hU5LoxrOn9qvOo+LTKN6mSav2J+dAMprbdxJPEQvp4U= @@ -182,6 +186,8 @@ github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLE github.com/zclconf/go-cty v1.1.1/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= 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.0 h1:+q+tmgyUB94HIdH/uVTIi/+kt3pt4sHwEZAcTyLoGsQ= +github.com/zclconf/go-cty v1.4.0/go.mod h1:nHzOclRkoj++EU9ZjSrZvRG0BXIWt8c7loYc0qXAFGQ= 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= diff --git a/internal/provider/data_radius_profile.go b/internal/provider/data_radius_profile.go index d6299af..e92ad12 100644 --- a/internal/provider/data_radius_profile.go +++ b/internal/provider/data_radius_profile.go @@ -17,9 +17,10 @@ unifi_radius_profile data source can be used to retrieve the ID for a RADIUS pro Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Optional: true, - Default: "Default", + Description: "The name of the RADIUS profile to look up.", + Type: schema.TypeString, + Optional: true, + Default: "Default", }, }, } diff --git a/internal/provider/data_user_group.go b/internal/provider/data_user_group.go index 35d67ff..9879f6b 100644 --- a/internal/provider/data_user_group.go +++ b/internal/provider/data_user_group.go @@ -17,9 +17,10 @@ unifi_user_group data source can be used to retrieve the ID for a user group by Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Optional: true, - Default: "Default", + Description: "The name of the user group to look up.", + Type: schema.TypeString, + Optional: true, + Default: "Default", }, "qos_rate_max_down": { diff --git a/internal/provider/data_wlan_group.go b/internal/provider/data_wlan_group.go index ea0fe80..bb87bb7 100644 --- a/internal/provider/data_wlan_group.go +++ b/internal/provider/data_wlan_group.go @@ -17,9 +17,10 @@ unifi_wlan_group data source can be used to retrieve the ID for a WLAN group by Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Optional: true, - Default: "Default", + Description: "The name of the WLAN group to look up.", + Type: schema.TypeString, + Optional: true, + Default: "Default", }, }, } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index fc1b6ba..e426721 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -2,39 +2,59 @@ package provider import ( "context" + "fmt" + "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/paultyng/go-unifi/unifi" ) +func init() { + schema.DescriptionKind = 1 + + schema.SchemaDescriptionBuilder = func(s *schema.Schema) string { + desc := s.Description + if s.Default != nil { + desc += fmt.Sprintf(" Defaults to `%v`.", s.Default) + } + return strings.TrimSpace(desc) + } +} + func Provider() *schema.Provider { p := &schema.Provider{ Schema: map[string]*schema.Schema{ "username": { + Description: "Local user name for the Unifi controller API. Can be specified with the `UNIFI_USERNAME` " + + "environment variable.", Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_USERNAME", ""), }, "password": { + Description: "Password for the user accessing the API. Can be specified with the `UNIFI_PASSWORD` " + + "environment variable.", Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_PASSWORD", ""), }, "api_url": { - Description: "URL of the controller API.", + Description: "URL of the controller API. Can be specified with the `UNIFI_API` environment variable.", Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_API", ""), }, "site": { + Description: "The site in the Unifi controller this provider will manage. Can be specified with " + + "the `UNIFI_SITE` environment variable. Default: `default`", Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_SITE", "default"), }, "allow_insecure": { - Description: "Skip verification of TLS certificates of API requests. " + - "You may need to set this to `true` if you are using your local API without " + - "setting up a signed certificate.", + Description: "Skip verification of TLS certificates of API requests. You may need to set this to `true` " + + "if you are using your local API without setting up a signed certificate. Can be specified with the " + + "`UNIFI_INSECURE` environment variable.", Type: schema.TypeBool, Optional: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_INSECURE", false), diff --git a/internal/provider/resource_firewall_group.go b/internal/provider/resource_firewall_group.go index f4d29eb..8eb24f2 100644 --- a/internal/provider/resource_firewall_group.go +++ b/internal/provider/resource_firewall_group.go @@ -23,18 +23,21 @@ unifi_firewall_group manages groups of addresses or ports for use in firewall ru Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, + Description: "The name of the firewall group.", + Type: schema.TypeString, + Required: true, }, "type": { + Description: "The type of the firewall group. Must be one of: `address-group`, `port-group`, or `ipv6-address-group`.", Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{"address-group", "port-group", "ipv6-address-group"}, false), }, "members": { - Type: schema.TypeSet, - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Description: "The members of the firewall group.", + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, } diff --git a/internal/provider/resource_firewall_rule.go b/internal/provider/resource_firewall_rule.go index f308622..cb9d541 100644 --- a/internal/provider/resource_firewall_rule.go +++ b/internal/provider/resource_firewall_rule.go @@ -26,25 +26,33 @@ unifi_firewall_rule manages an individual firewall rule on the gateway. Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, + Description: "The name of the firewall rule.", + Type: schema.TypeString, + Required: true, }, "action": { + Description: "The action of the firewall rule. Must be one of `drop`, `accept`, or `reject`.", Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{"drop", "accept", "reject"}, false), }, "ruleset": { + Description: "The ruleset for the rule. This is from the perspective of the security gateway. " + + "Must be one of `WAN_IN`, `WAN_OUT`, `WAN_LOCAL`, `LAN_IN`, `LAN_OUT`, `LAN_LOCAL`, `GUEST_IN`, " + + "`GUEST_OUT`, `GUEST_LOCAL`, `WANv6_IN`, `WANv6_OUT`, `WANv6_LOCAL`, `LANv6_IN`, `LANv6_OUT`, " + + "`LANv6_LOCAL`, `GUESTv6_IN`, `GUESTv6_OUT`, or `GUESTv6_LOCAL`.", Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{"WAN_IN", "WAN_OUT", "WAN_LOCAL", "LAN_IN", "LAN_OUT", "LAN_LOCAL", "GUEST_IN", "GUEST_OUT", "GUEST_LOCAL", "WANv6_IN", "WANv6_OUT", "WANv6_LOCAL", "LANv6_IN", "LANv6_OUT", "LANv6_LOCAL", "GUESTv6_IN", "GUESTv6_OUT", "GUESTv6_LOCAL"}, false), }, "rule_index": { - Type: schema.TypeInt, - Required: true, + Description: "The index of the rule. Must be >= 2000 < 3000 or >= 4000 < 5000.", + Type: schema.TypeInt, + Required: true, // 2[0-9]{3}|4[0-9]{3} }, "protocol": { + Description: "The protocol of the rule.", Type: schema.TypeString, Required: true, ValidateFunc: validation.StringMatch(firewallRuleProtocolRegexp, "must be a valid protocol"), @@ -52,72 +60,87 @@ unifi_firewall_rule manages an individual firewall rule on the gateway. // sources "src_network_id": { - Type: schema.TypeString, - Optional: true, + Description: "The source network ID for the firewall rule.", + Type: schema.TypeString, + Optional: true, }, "src_network_type": { + Description: "The source network type of the firewall rule. Can be one of `ADDRv4` or `NETv4`.", Type: schema.TypeString, Optional: true, Default: "NETv4", ValidateFunc: validation.StringInSlice([]string{"ADDRv4", "NETv4"}, false), }, "src_firewall_group_ids": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Description: "The source firewall group IDs for the firewall rule.", + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "src_address": { - Type: schema.TypeString, - Optional: true, + Description: "The source address for the firewall rule.", + Type: schema.TypeString, + Optional: true, }, "src_mac": { - Type: schema.TypeString, - Optional: true, + Description: "The source MAC address of the firewall rule.", + Type: schema.TypeString, + Optional: true, }, // destinations "dst_network_id": { - Type: schema.TypeString, - Optional: true, + Description: "The destination network ID of the firewall rule.", + Type: schema.TypeString, + Optional: true, }, "dst_network_type": { + Description: "The destination network type of the firewall rule. Can be one of `ADDRv4` or `NETv4`.", Type: schema.TypeString, Optional: true, Default: "NETv4", ValidateFunc: validation.StringInSlice([]string{"ADDRv4", "NETv4"}, false), }, "dst_firewall_group_ids": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Description: "The destination firewall group IDs of the firewall rule.", + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "dst_address": { - Type: schema.TypeString, - Optional: true, + Description: "The destination address of the firewall rule.", + Type: schema.TypeString, + Optional: true, }, // advanced "logging": { - Type: schema.TypeBool, - Optional: true, + Description: "Enable logging for the firewall rule.", + Type: schema.TypeBool, + Optional: true, }, "state_established": { - Type: schema.TypeBool, - Optional: true, + Description: "Match where the state is established.", + Type: schema.TypeBool, + Optional: true, }, "state_invalid": { - Type: schema.TypeBool, - Optional: true, + Description: "Match where the state is invalid.", + Type: schema.TypeBool, + Optional: true, }, "state_new": { - Type: schema.TypeBool, - Optional: true, + Description: "Match where the state is new.", + Type: schema.TypeBool, + Optional: true, }, "state_related": { - Type: schema.TypeBool, - Optional: true, + Description: "Match where the state is related.", + Type: schema.TypeBool, + Optional: true, }, "ip_sec": { + Description: "Specify whether the rule matches on IPsec packets. Can be one of `match-ipset` or `match-none`.", Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{"match-ipsec", "match-none"}, false), diff --git a/internal/provider/resource_network.go b/internal/provider/resource_network.go index 853135e..afdf2bf 100644 --- a/internal/provider/resource_network.go +++ b/internal/provider/resource_network.go @@ -25,49 +25,60 @@ unifi_network manages LAN/VLAN networks. Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, + Description: "The name of the network.", + Type: schema.TypeString, + Required: true, }, "purpose": { + Description: "The purpose of the network. Must be one of `corporate`, `guest`, or `vlan-only`.", Type: schema.TypeString, Required: true, ForceNew: true, ValidateFunc: validation.StringInSlice([]string{"corporate", "guest", "vlan-only"}, false), }, "vlan_id": { - Type: schema.TypeInt, - Optional: true, + Description: "The VLAN ID of the network.", + Type: schema.TypeInt, + Optional: true, }, "subnet": { + Description: "The subnet of the network. Must be a valid CIDR address.", Type: schema.TypeString, Optional: true, DiffSuppressFunc: cidrDiffSuppress, }, "network_group": { - Type: schema.TypeString, - Optional: true, - Default: "LAN", + Description: "The group of the network.", + Type: schema.TypeString, + Optional: true, + Default: "LAN", }, "dhcp_start": { + Description: "The IPv4 address where the DHCP range of addresses starts.", Type: schema.TypeString, Optional: true, ValidateFunc: validation.IsIPv4Address, }, "dhcp_stop": { + Description: "The IPv4 address where the DHCP range of addresses stops.", Type: schema.TypeString, Optional: true, ValidateFunc: validation.IsIPv4Address, }, "dhcp_enabled": { - Type: schema.TypeBool, - Optional: true, + Description: "Specifies whether DHCP is enabled or not on this network.", + Type: schema.TypeBool, + Optional: true, }, "dhcp_lease": { - Type: schema.TypeInt, - Optional: true, - Default: 86400, + Description: "Specifies the lease time for DHCP addresses.", + Type: schema.TypeInt, + Optional: true, + Default: 86400, }, "dhcp_dns": { + Description: "Specifies the IPv4 addresses for the DNS server to be returned from the DHCP " + + "server. Leave blank to disable this feature.", Type: schema.TypeList, Optional: true, MaxItems: 4, @@ -81,12 +92,14 @@ unifi_network manages LAN/VLAN networks. }, }, "domain_name": { - Type: schema.TypeString, - Optional: true, + Description: "The domain name of this network.", + Type: schema.TypeString, + Optional: true, }, "igmp_snooping": { - Type: schema.TypeBool, - Optional: true, + Description: "Specifies whether IGMP snooping is enabled or not.", + Type: schema.TypeBool, + Optional: true, }, }, } diff --git a/internal/provider/resource_port_forward.go b/internal/provider/resource_port_forward.go index 4d1764d..b061f05 100644 --- a/internal/provider/resource_port_forward.go +++ b/internal/provider/resource_port_forward.go @@ -24,48 +24,60 @@ unifi_port_forward manages a port forwarding rule on the gateway. Schema: map[string]*schema.Schema{ "dst_port": { + Description: "The destination port for the forwarding.", Type: schema.TypeString, Optional: true, ValidateFunc: validatePortRange, }, + // TODO: remove this, disabled rules should just be deleted. "enabled": { - Type: schema.TypeBool, - Optional: true, + Description: "Specifies whether the port forwarding rule is enabled or not.", + Type: schema.TypeBool, + Optional: true, + Deprecated: "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": { + Description: "The IPv4 address to forward traffic to.", Type: schema.TypeString, Optional: true, ValidateFunc: validation.IsIPv4Address, }, "fwd_port": { + Description: "The port to forward traffic to.", Type: schema.TypeString, Optional: true, ValidateFunc: validatePortRange, }, "log": { - Type: schema.TypeBool, - Default: false, - Optional: true, + Description: "Specifies whether to log forwarded traffic or not.", + Type: schema.TypeBool, + Default: false, + Optional: true, }, "name": { - Type: schema.TypeString, - Optional: true, + Description: "The name of the port forwarding rule.", + Type: schema.TypeString, + Optional: true, }, "port_forward_interface": { + Description: "The port forwarding interface. Can be `wan`, `wan2`, or `both`.", Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{"wan", "wan2", "both"}, false), }, "protocol": { + Description: "The protocol for the port forwarding rule. Can be `tcp`, `udp`, or `tcp_udp`.", Type: schema.TypeString, Optional: true, Default: "tcp_udp", ValidateFunc: validation.StringInSlice([]string{"tcp_udp", "tcp", "udp"}, false), }, "src_ip": { - Type: schema.TypeString, - Optional: true, - Default: "any", + Description: "The source IPv4 address of the port forwarding rule. For all traffic, specify `any`.", + Type: schema.TypeString, + Optional: true, + Default: "any", ValidateFunc: validation.Any( validation.StringInSlice([]string{"any"}, false), validation.IsIPv4Address, diff --git a/internal/provider/resource_user.go b/internal/provider/resource_user.go index 4b7e235..85468ab 100644 --- a/internal/provider/resource_user.go +++ b/internal/provider/resource_user.go @@ -28,6 +28,7 @@ itself to just take over management of a MAC address, but this can be turned off Schema: map[string]*schema.Schema{ "mac": { + Description: "The MAC address of the user.", Type: schema.TypeString, Required: true, ForceNew: true, @@ -35,52 +36,62 @@ itself to just take over management of a MAC address, but this can be turned off ValidateFunc: validation.StringMatch(macAddressRegexp, "Mac address is invalid"), }, "name": { - Type: schema.TypeString, - Required: true, + Description: "The name of the user.", + Type: schema.TypeString, + Required: true, }, "user_group_id": { - Type: schema.TypeString, - Optional: true, + Description: "The user group ID for the user.", + Type: schema.TypeString, + Optional: true, }, "note": { - Type: schema.TypeString, - Optional: true, + Description: "A note with additional information for the user.", + Type: schema.TypeString, + Optional: true, }, // TODO: combine this with output IP for a single attribute ip_address? "fixed_ip": { + Description: "A fixed IPv4 address for this user.", Type: schema.TypeString, Optional: true, ValidateFunc: validation.IsIPv4Address, }, "network_id": { - Type: schema.TypeString, - Optional: true, + Description: "The network ID for this user.", + Type: schema.TypeString, + Optional: true, }, "blocked": { - Type: schema.TypeBool, - Optional: true, + Description: "Specifies whether this user should be blocked from the network.", + Type: schema.TypeBool, + Optional: true, }, // these are "meta" attributes that control TF UX "allow_existing": { - Type: schema.TypeBool, - Optional: true, - Default: true, + Description: "Specifies whether this resource should just take over control of an existing user.", + Type: schema.TypeBool, + Optional: true, + Default: true, }, "skip_forget_on_destroy": { - Type: schema.TypeBool, - Optional: true, - Default: false, + Description: "Specifies whether this resource should tell the controller to \"forget\" the user on destroy.", + Type: schema.TypeBool, + Optional: true, + Default: false, }, // computed only attributes "hostname": { - Type: schema.TypeString, - Computed: true, + Description: "The hostname of the user.", + Type: schema.TypeString, + Computed: true, }, "ip": { - Type: schema.TypeString, - Computed: true, + Description: "The IP address of the user.", + Type: schema.TypeString, + Computed: true, }, }, } diff --git a/internal/provider/resource_user_group.go b/internal/provider/resource_user_group.go index 7469989..190d2db 100644 --- a/internal/provider/resource_user_group.go +++ b/internal/provider/resource_user_group.go @@ -24,19 +24,22 @@ to limit bandwidth for groups of users. Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, + Description: "The name of the user group.", + Type: schema.TypeString, + Required: true, }, "qos_rate_max_down": { - Type: schema.TypeInt, - Optional: true, - Default: -1, + Description: "The QOS maximum download rate.", + 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, + Description: "The QOS maximum upload rate.", + Type: schema.TypeInt, + Optional: true, + Default: -1, // TODO: validate does not equal 0,1 }, }, diff --git a/internal/provider/resource_wlan.go b/internal/provider/resource_wlan.go index 54c603b..9383855 100644 --- a/internal/provider/resource_wlan.go +++ b/internal/provider/resource_wlan.go @@ -31,7 +31,7 @@ unifi_wlan manages a WiFi network / SSID. Required: true, }, "vlan_id": { - Description: "VLAN ID for the network, defaults to `1`.", + Description: "VLAN ID for the network.", Type: schema.TypeInt, Optional: true, Default: 1, @@ -97,6 +97,8 @@ unifi_wlan manages a WiFi network / SSID. ValidateFunc: validation.StringInSlice([]string{"allow", "deny"}, false), }, "radius_profile_id": { + Description: "ID of the RADIUS profile to use when security `wpaeap`. You can query this via the " + + "`unifi_radius_profile` data source.", Type: schema.TypeString, Optional: true, }, diff --git a/website/docs/d/radius_profile.html.markdown b/website/docs/d/radius_profile.html.markdown new file mode 100644 index 0000000..fb81278 --- /dev/null +++ b/website/docs/d/radius_profile.html.markdown @@ -0,0 +1,22 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_radius_profile" +description: |- + unifi_radius_profile data source can be used to retrieve the ID for a RADIUS profile by name. +--- + +# Resource: `unifi_radius_profile` + +unifi_radius_profile data source can be used to retrieve the ID for a RADIUS profile by name. + + + +## Schema + +### Optional + +- **id** (String, Optional) +- **name** (String, Optional) The name of the RADIUS profile to look up. Defaults to `Default`. + + diff --git a/website/docs/d/user_group.html.markdown b/website/docs/d/user_group.html.markdown new file mode 100644 index 0000000..565d433 --- /dev/null +++ b/website/docs/d/user_group.html.markdown @@ -0,0 +1,27 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_user_group" +description: |- + unifi_user_group data source can be used to retrieve the ID for a user group by name. +--- + +# Resource: `unifi_user_group` + +unifi_user_group data source can be used to retrieve the ID for a user group by name. + + + +## Schema + +### Optional + +- **id** (String, Optional) +- **name** (String, Optional) The name of the user group to look up. Defaults to `Default`. + +### Read-only + +- **qos_rate_max_down** (Number, Read-only) +- **qos_rate_max_up** (Number, Read-only) + + diff --git a/website/docs/d/wlan_group.html.markdown b/website/docs/d/wlan_group.html.markdown new file mode 100644 index 0000000..e92a3d6 --- /dev/null +++ b/website/docs/d/wlan_group.html.markdown @@ -0,0 +1,27 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_wlan_group" +description: |- + unifi_wlan_group data source can be used to retrieve the ID for a WLAN group by name. +--- + +# Resource: `unifi_wlan_group` + +unifi_wlan_group data source can be used to retrieve the ID for a WLAN group by name. + +## Example Usage + +```terraform +data "unifi_wlan_group" "default" { +} +``` + +## Schema + +### Optional + +- **id** (String, Optional) +- **name** (String, Optional) The name of the WLAN group to look up. Defaults to `Default`. + + diff --git a/website/docs/guides/csv-users.html.markdown b/website/docs/guides/csv-users.html.markdown new file mode 100644 index 0000000..ceee802 --- /dev/null +++ b/website/docs/guides/csv-users.html.markdown @@ -0,0 +1,41 @@ +--- +subcategory: "" +page_title: "Manage Users/Clients in a CSV - Unifi Provider" +description: |- + An example of using a CSV to manage all of your users of your network. +--- + +# Manage Users in a CSV + +Given a CSV file with the following content: + +```csv +mac,name,note,network,fixed_ip +00:00:00:00:00:00,My Device,custom note,,, +00:00:00:00:00:00,My Device,custom note,network name to lookup,10.0.3.4 +``` + +You could create/manage a `unifi_user` for every row/MAC address in the CSV with the following config: + +```terraform +locals { + userscsv = csvdecode(file("${path.module}/users.csv")) + users = { for user in local.userscsv : user.mac => user } +} + +resource "unifi_user" "user" { + for_each = local.users + + mac = each.key + name = each.value.name + # append an optional additional note + note = trimspace("${each.value.note}\n\nmanaged by TF") + + fixed_ip = each.value.fixed_ip + # this assumes there is a unifi_network for_each with names + network_id = each.value.network != "" ? unifi_network.vlan[each.value.network].id : "" + + allow_existing = true + skip_forget_on_destroy = true +} +``` diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown new file mode 100644 index 0000000..6702851 --- /dev/null +++ b/website/docs/index.html.markdown @@ -0,0 +1,23 @@ +--- +layout: "" +page_title: "Provider: Unifi" +description: |- + The Unifi provider provides resources to interact with a Unifi controller API. +--- + +# Unifi Provider + +The Unifi provider provides resources to interact with a Unifi controller API. + +## Example Usage + +```terraform +provider "unifi" { + username = var.username # optionally use UNIFI_USERNAME env var + password = var.password # optionally use UNIFI_PASSWORD env var + api_url = var.api_url # optionally use UNIFI_API env var + + # if you are not configuring the default site, you can change the site + # site = "foo" or optionally use UNIFI_SITE env var +} +``` diff --git a/website/docs/r/firewall_group.html.markdown b/website/docs/r/firewall_group.html.markdown new file mode 100644 index 0000000..d36fdef --- /dev/null +++ b/website/docs/r/firewall_group.html.markdown @@ -0,0 +1,27 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_firewall_group" +description: |- + unifi_firewall_group manages groups of addresses or ports for use in firewall rules (unifi_firewall_rule). +--- + +# Resource: `unifi_firewall_group` + +unifi_firewall_group manages groups of addresses or ports for use in firewall rules (unifi_firewall_rule). + + + +## Schema + +### Required + +- **members** (Set of String, Required) The members of the firewall group. +- **name** (String, Required) The name of the firewall group. +- **type** (String, Required) The type of the firewall group. Must be one of: `address-group`, `port-group`, or `ipv6-address-group`. + +### Optional + +- **id** (String, Optional) + + diff --git a/website/docs/r/firewall_rule.html.markdown b/website/docs/r/firewall_rule.html.markdown new file mode 100644 index 0000000..5966159 --- /dev/null +++ b/website/docs/r/firewall_rule.html.markdown @@ -0,0 +1,44 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_firewall_rule" +description: |- + unifi_firewall_rule manages an individual firewall rule on the gateway. +--- + +# Resource: `unifi_firewall_rule` + +unifi_firewall_rule manages an individual firewall rule on the gateway. + + + +## Schema + +### Required + +- **action** (String, Required) The action of the firewall rule. Must be one of `drop`, `accept`, or `reject`. +- **name** (String, Required) The name of the firewall rule. +- **protocol** (String, Required) The protocol of the rule. +- **rule_index** (Number, Required) The index of the rule. Must be >= 2000 < 3000 or >= 4000 < 5000. +- **ruleset** (String, Required) The ruleset for the rule. This is from the perspective of the security gateway. Must be one of `WAN_IN`, `WAN_OUT`, `WAN_LOCAL`, `LAN_IN`, `LAN_OUT`, `LAN_LOCAL`, `GUEST_IN`, `GUEST_OUT`, `GUEST_LOCAL`, `WANv6_IN`, `WANv6_OUT`, `WANv6_LOCAL`, `LANv6_IN`, `LANv6_OUT`, `LANv6_LOCAL`, `GUESTv6_IN`, `GUESTv6_OUT`, or `GUESTv6_LOCAL`. + +### Optional + +- **dst_address** (String, Optional) The destination address of the firewall rule. +- **dst_firewall_group_ids** (Set of String, Optional) The destination firewall group IDs of the firewall rule. +- **dst_network_id** (String, Optional) The destination network ID of the firewall rule. +- **dst_network_type** (String, Optional) The destination network type of the firewall rule. Can be one of `ADDRv4` or `NETv4`. Defaults to `NETv4`. +- **id** (String, Optional) +- **ip_sec** (String, Optional) Specify whether the rule matches on IPsec packets. Can be one of `match-ipset` or `match-none`. +- **logging** (Boolean, Optional) Enable logging for the firewall rule. +- **src_address** (String, Optional) The source address for the firewall rule. +- **src_firewall_group_ids** (Set of String, Optional) The source firewall group IDs for the firewall rule. +- **src_mac** (String, Optional) The source MAC address of the firewall rule. +- **src_network_id** (String, Optional) The source network ID for the firewall rule. +- **src_network_type** (String, Optional) The source network type of the firewall rule. Can be one of `ADDRv4` or `NETv4`. Defaults to `NETv4`. +- **state_established** (Boolean, Optional) Match where the state is established. +- **state_invalid** (Boolean, Optional) Match where the state is invalid. +- **state_new** (Boolean, Optional) Match where the state is new. +- **state_related** (Boolean, Optional) Match where the state is related. + + diff --git a/website/docs/r/network.html.markdown b/website/docs/r/network.html.markdown new file mode 100644 index 0000000..8d1c9b0 --- /dev/null +++ b/website/docs/r/network.html.markdown @@ -0,0 +1,53 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_network" +description: |- + unifi_network manages LAN/VLAN networks. +--- + +# Resource: `unifi_network` + +unifi_network manages LAN/VLAN networks. + +## Example Usage + +```terraform +variable "vlan_id" { + default = 10 +} + +resource "unifi_network" "vlan" { + name = "wifi-vlan" + purpose = "corporate" + + subnet = "10.0.0.1/24" + vlan_id = var.vlan_id + dhcp_start = "10.0.0.6" + dhcp_stop = "10.0.0.254" + dhcp_enabled = true +} +``` + +## Schema + +### Required + +- **name** (String, Required) The name of the network. +- **purpose** (String, Required) The purpose of the network. Must be one of `corporate`, `guest`, or `vlan-only`. + +### Optional + +- **dhcp_dns** (List of String, Optional) Specifies the IPv4 addresses for the DNS server to be returned from the DHCP server. Leave blank to disable this feature. +- **dhcp_enabled** (Boolean, Optional) Specifies whether DHCP is enabled or not on this network. +- **dhcp_lease** (Number, Optional) Specifies the lease time for DHCP addresses. Defaults to `86400`. +- **dhcp_start** (String, Optional) The IPv4 address where the DHCP range of addresses starts. +- **dhcp_stop** (String, Optional) The IPv4 address where the DHCP range of addresses stops. +- **domain_name** (String, Optional) The domain name of this network. +- **id** (String, Optional) +- **igmp_snooping** (Boolean, Optional) Specifies whether IGMP snooping is enabled or not. +- **network_group** (String, Optional) The group of the network. Defaults to `LAN`. +- **subnet** (String, Optional) The subnet of the network. Must be a valid CIDR address. +- **vlan_id** (Number, Optional) The VLAN ID of the network. + + diff --git a/website/docs/r/port_forward.html.markdown b/website/docs/r/port_forward.html.markdown new file mode 100644 index 0000000..a77585f --- /dev/null +++ b/website/docs/r/port_forward.html.markdown @@ -0,0 +1,30 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_port_forward" +description: |- + unifi_port_forward manages a port forwarding rule on the gateway. +--- + +# Resource: `unifi_port_forward` + +unifi_port_forward manages a port forwarding rule on the gateway. + + + +## Schema + +### 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. +- **fwd_ip** (String, Optional) The IPv4 address to forward traffic to. +- **fwd_port** (String, Optional) The port to forward traffic to. +- **id** (String, Optional) +- **log** (Boolean, Optional) Specifies whether to log forwarded traffic or not. Defaults to `false`. +- **name** (String, Optional) The name of the port forwarding rule. +- **port_forward_interface** (String, Optional) The port forwarding interface. Can be `wan`, `wan2`, or `both`. +- **protocol** (String, Optional) The protocol for the port forwarding rule. Can be `tcp`, `udp`, or `tcp_udp`. Defaults to `tcp_udp`. +- **src_ip** (String, Optional) The source IPv4 address of the port forwarding rule. For all traffic, specify `any`. Defaults to `any`. + + diff --git a/website/docs/r/user.html.markdown b/website/docs/r/user.html.markdown new file mode 100644 index 0000000..67de54c --- /dev/null +++ b/website/docs/r/user.html.markdown @@ -0,0 +1,57 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_user" +description: |- + unifi_user manages a user (or "client" in the UI) of the network, these are identified +by unique MAC addresses. + +Users are "created" in the controller when observed on the network, so the resource defaults to allowing +itself to just take over management of a MAC address, but this can be turned off. +--- + +# Resource: `unifi_user` + +unifi_user manages a user (or "client" in the UI) of the network, these are identified +by unique MAC addresses. + +Users are "created" in the controller when observed on the network, so the resource defaults to allowing +itself to just take over management of a MAC address, but this can be turned off. + +## Example Usage + +```terraform +resource "unifi_user" "test" { + mac = "01:23:45:67:89:AB" + name = "some client" + note = "my note" + + fixed_ip = "10.1.10.50" + network_id = unifi_network.my_vlan.id +} +``` + +## Schema + +### Required + +- **mac** (String, Required) The MAC address of the user. +- **name** (String, Required) The name of the user. + +### Optional + +- **allow_existing** (Boolean, Optional) Specifies whether this resource should just take over control of an existing user. Defaults to `true`. +- **blocked** (Boolean, Optional) Specifies whether this user should be blocked from the network. +- **fixed_ip** (String, Optional) A fixed IPv4 address for this user. +- **id** (String, Optional) +- **network_id** (String, Optional) The network ID for this user. +- **note** (String, Optional) A note with additional information for the user. +- **skip_forget_on_destroy** (Boolean, Optional) Specifies whether this resource should tell the controller to "forget" the user on destroy. Defaults to `false`. +- **user_group_id** (String, Optional) The user group ID for the user. + +### Read-only + +- **hostname** (String, Read-only) The hostname of the user. +- **ip** (String, Read-only) The IP address of the user. + + diff --git a/website/docs/r/user_group.html.markdown b/website/docs/r/user_group.html.markdown new file mode 100644 index 0000000..b24e894 --- /dev/null +++ b/website/docs/r/user_group.html.markdown @@ -0,0 +1,38 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_user_group" +description: |- + unifi_user_group manages a user group (called "client group" in the UI), which can be used +to limit bandwidth for groups of users. +--- + +# Resource: `unifi_user_group` + +unifi_user_group manages a user group (called "client group" in the UI), which can be used +to limit bandwidth for groups of users. + +## Example Usage + +```terraform +resource "unifi_user_group" "wifi" { + name = "wifi" + + qos_rate_max_down = 2000 # 2mbps + qos_rate_max_up = 10 # 10kbps +} +``` + +## Schema + +### Required + +- **name** (String, Required) The name of the user group. + +### Optional + +- **id** (String, Optional) +- **qos_rate_max_down** (Number, Optional) The QOS maximum download rate. Defaults to `-1`. +- **qos_rate_max_up** (Number, Optional) The QOS maximum upload rate. Defaults to `-1`. + + diff --git a/website/docs/r/wlan.html.markdown b/website/docs/r/wlan.html.markdown new file mode 100644 index 0000000..7b737ef --- /dev/null +++ b/website/docs/r/wlan.html.markdown @@ -0,0 +1,63 @@ +--- +subcategory: "" +layout: "" +page_title: "terraform-provider-unifi: unifi_wlan" +description: |- + unifi_wlan manages a WiFi network / SSID. +--- + +# Resource: `unifi_wlan` + +unifi_wlan manages a WiFi network / SSID. + +## Example Usage + +```terraform +data "unifi_wlan_group" "default" { +} + +data "unifi_user_group" "default" { +} + +resource "unifi_wlan" "wifi" { + name = "myssid" + vlan_id = 10 + passphrase = "12345678" + wlan_group_id = data.unifi_wlan_group.default.id + user_group_id = data.unifi_user_group.default.id + security = "wpapsk" +} +``` + +## Schema + +### Required + +- **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 + +- **hide_ssid** (Boolean, Optional) Indicates whether or not to hide the SSID from broadcast. +- **id** (String, Optional) +- **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. +- **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) +- **vlan_id** (Number, Optional) VLAN ID for the network. Defaults to `1`. + +### Nested Schema for `schedule` + +Required: + +- **block_end** (String, Required) Time of day to end the block. +- **block_start** (String, Required) Time of day to start the block. +- **day_of_week** (String, Required) Day of week for the block. Valid values are `sun`, `mon`, `tue`, `wed`, `thu`, `fri`, `sat`. + +