feat: initialize Terraform Plugin Framework (#23)
* feat: initialize Terraform Plugin Framework * fix docker-compose path for tests * fix: ensure documentation can be generated with old provider SDK and new plugin framework * lint
This commit is contained in:
committed by
GitHub
parent
ccde06a322
commit
325d7b7f20
@@ -8,7 +8,7 @@ description: |-
|
||||
|
||||
# unifi_account (Data Source)
|
||||
|
||||
`unifi_account` data source can be used to retrieve RADIUS user accounts
|
||||
unifi_account data source can be used to retrieve RADIUS user accounts
|
||||
|
||||
|
||||
|
||||
@@ -30,5 +30,3 @@ description: |-
|
||||
- `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
|
||||
|
||||
|
||||
|
||||
@@ -28,5 +28,3 @@ data "unifi_ap_group" "default" {
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this AP group.
|
||||
|
||||
|
||||
|
||||
@@ -83,5 +83,3 @@ data "unifi_network" "my_network" {
|
||||
- `wan_type_v6` (String) Specifies the IPV6 WAN connection type. Must be one of either `disabled`, `static`, or `dhcpv6`.
|
||||
- `wan_username` (String) Specifies the IPV4 WAN username.
|
||||
- `x_wan_password` (String) Specifies the IPV4 WAN password.
|
||||
|
||||
|
||||
|
||||
@@ -28,5 +28,3 @@ data "unifi_port_profile" "all" {
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this port profile.
|
||||
|
||||
|
||||
|
||||
@@ -23,5 +23,3 @@ description: |-
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this AP group.
|
||||
|
||||
|
||||
|
||||
@@ -42,5 +42,3 @@ data "unifi_user" "client" {
|
||||
- `network_id` (String) The network ID for this user.
|
||||
- `note` (String) A note with additional information for the user.
|
||||
- `user_group_id` (String) The user group ID for the user.
|
||||
|
||||
|
||||
|
||||
@@ -25,5 +25,3 @@ description: |-
|
||||
- `id` (String) The ID of this AP group.
|
||||
- `qos_rate_max_down` (Number)
|
||||
- `qos_rate_max_up` (Number)
|
||||
|
||||
|
||||
|
||||
@@ -13,16 +13,14 @@ It is not recommended to use your own account for management of your controller.
|
||||
Terraform is recommended. You can create a **Limited Admin** with **Local Access Only** and
|
||||
provide that information for authentication. Two-factor authentication is not supported in the provider.
|
||||
|
||||
It is recommended to use API Key authentication, if you are on controller version 9.0.108 or higher.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```terraform
|
||||
provider "unifi" {
|
||||
api_key = var.api_key # optionally use UNIFI_API_KEY env var
|
||||
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
|
||||
api_key = var.api_key # optionally use UNIFI_API_KEY env var
|
||||
api_url = var.api_url # optionally use UNIFI_API env var
|
||||
|
||||
# you may need to allow insecure TLS communications unless you have configured
|
||||
# certificates for your controller
|
||||
@@ -33,25 +31,14 @@ provider "unifi" {
|
||||
}
|
||||
```
|
||||
|
||||
### Obtaining an API Key
|
||||
|
||||
1. Open your Site in UniFi Site Manager
|
||||
2. Click on Control Plane -> Admins & Users.
|
||||
3. Select your Admin user.
|
||||
4. Click Create API Key.
|
||||
5. Add a name for your API Key.
|
||||
6. Copy the key and store it securely, as it will only be displayed once.
|
||||
7. Click Done to ensure the key is hashed and securely stored.
|
||||
8. Use the API Key 🎉
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `allow_insecure` (Boolean) 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.
|
||||
- `api_key` (String) API key for the user accessing the API. Can be specified with the `UNIFI_API_KEY` environment variable. Requires controller version 9.0.108 or higher and `username` and `password` to be empty
|
||||
- `api_key` (String, Sensitive) API Key for the user accessing the API. Can be specified with the `UNIFI_API_KEY` environment variable. Controller version 9.0.108 or later is required.
|
||||
- `api_url` (String) URL of the controller API. Can be specified with the `UNIFI_API` environment variable. You should **NOT** supply the path (`/api`), the SDK will discover the appropriate paths. This is to support UDM Pro style API paths as well as more standard controller paths.
|
||||
- `password` (String) Password for the user accessing the API. Can be specified with the `UNIFI_PASSWORD` environment variable.
|
||||
- `password` (String, Sensitive) Password for the user accessing the API. Can be specified with the `UNIFI_PASSWORD` environment variable.
|
||||
- `site` (String) The site in the Unifi controller this provider will manage. Can be specified with the `UNIFI_SITE` environment variable. Default: `default`
|
||||
- `username` (String) Local user name for the Unifi controller API. Can be specified with the `UNIFI_USERNAME` environment variable.
|
||||
|
||||
@@ -41,5 +41,3 @@ NOTE: MAC-based authentication accounts can only be used for wireless and wired
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of the account.
|
||||
|
||||
|
||||
|
||||
@@ -90,6 +90,5 @@ Optional:
|
||||
- `aggregate_num_ports` (Number) Number of ports in the aggregate.
|
||||
- `name` (String) Human-readable name of the port.
|
||||
- `op_mode` (String) Operating mode of the port, valid values are `switch`, `mirror`, and `aggregate`. Defaults to `switch`.
|
||||
- `poe_mode` (String) PoE mode of the port; valid values are `auto`, `pasv24`, `passthrough`, and `off`.
|
||||
- `port_profile_id` (String) ID of the Port Profile used on this port.
|
||||
|
||||
|
||||
|
||||
@@ -43,5 +43,3 @@ resource "unifi_dynamic_dns" "test" {
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of the dynamic DNS.
|
||||
|
||||
|
||||
|
||||
@@ -41,5 +41,3 @@ resource "unifi_firewall_group" "can_print" {
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of the firewall group.
|
||||
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ resource "unifi_network" "wan" {
|
||||
- `dhcpd_boot_filename` (String) Specifies the file to PXE boot from on the dhcpd_boot_server.
|
||||
- `dhcpd_boot_server` (String) Specifies the IPv4 address of a TFTP server to network boot from.
|
||||
- `domain_name` (String) The domain name of this network.
|
||||
- `enabled` (Boolean) Specifies whether this network is enabled or not. Defaults to `true`.
|
||||
- `igmp_snooping` (Boolean) Specifies whether IGMP snooping is enabled or not.
|
||||
- `internet_access_enabled` (Boolean) Specifies whether this network should be allowed to access the internet or not. Defaults to `true`.
|
||||
- `intra_network_access_enabled` (Boolean) Specifies whether this network should be allowed to access other local networks or not. Defaults to `true`.
|
||||
- `ipv6_interface_type` (String) Specifies which type of IPv6 connection to use. Must be one of either `static`, `pd`, or `none`. Defaults to `none`.
|
||||
- `ipv6_pd_interface` (String) Specifies which WAN interface to use for IPv6 PD. Must be one of either `wan` or `wan2`.
|
||||
- `ipv6_pd_prefixid` (String) Specifies the IPv6 Prefix ID.
|
||||
@@ -82,6 +82,7 @@ resource "unifi_network" "wan" {
|
||||
- `ipv6_static_subnet` (String) Specifies the static IPv6 subnet when `ipv6_interface_type` is 'static'.
|
||||
- `multicast_dns` (Boolean) Specifies whether Multicast DNS (mDNS) is enabled or not on the network (Controller >=v7).
|
||||
- `network_group` (String) The group of the network. Defaults to `LAN`.
|
||||
- `network_isolation_enabled` (Boolean) Specifies whether this network should be isolated from other networks or not. Defaults to `false`.
|
||||
- `site` (String) The name of the site to associate the network with.
|
||||
- `subnet` (String) The subnet of the network. Must be a valid CIDR address.
|
||||
- `vlan_id` (Number) The VLAN ID of the network.
|
||||
|
||||
@@ -31,5 +31,3 @@ description: |-
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of the port forwarding rule.
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ resource "unifi_port_profile" "poe_disabled" {
|
||||
- `dot1x_idle_timeout` (Number) The timeout, in seconds, to use when using the MAC Based 802.1X control. Can be between 0 and 65535 Defaults to `300`.
|
||||
- `egress_rate_limit_kbps` (Number) The egress rate limit, in kpbs, for the port profile. Can be between `64` and `9999999`.
|
||||
- `egress_rate_limit_kbps_enabled` (Boolean) Enable egress rate limiting for the port profile. Defaults to `false`.
|
||||
- `excluded_network_ids` (Set of String) List of network IDs to exclude on the port profile when forward is set to customize.
|
||||
- `forward` (String) The type forwarding to use for the port profile. Can be `all`, `native`, `customize` or `disabled`. Defaults to `native`.
|
||||
- `full_duplex` (Boolean) Enable full duplex for the port profile. Defaults to `false`.
|
||||
- `isolation` (Boolean) Enable port isolation for the port profile. Defaults to `false`.
|
||||
@@ -62,7 +63,7 @@ resource "unifi_port_profile" "poe_disabled" {
|
||||
- `priority_queue3_level` (Number) The priority queue 3 level for the port profile. Can be between 0 and 100.
|
||||
- `priority_queue4_level` (Number) The priority queue 4 level for the port profile. Can be between 0 and 100.
|
||||
- `site` (String) The name of the site to associate the port profile with.
|
||||
- `speed` (Number) The link speed to set for the port profile. Can be one of `10`, `100`, `1000`, `2500`, `5000`, `10000`, `20000`, `25000`, `40000`, `50000` or `100000`
|
||||
- `speed` (Number) The link speed to set for the port profile in Mbps. Can be one of `10`, `100`, `1000`, `2500`, `5000`, `10000`, `20000`, `25000`, `40000`, `50000` or `100000`. When `autoneg` is true, this setting is ignored.
|
||||
- `stormctrl_bcast_enabled` (Boolean) Enable broadcast Storm Control for the port profile. Defaults to `false`.
|
||||
- `stormctrl_bcast_level` (Number) The broadcast Storm Control level for the port profile. Can be between 0 and 100.
|
||||
- `stormctrl_bcast_rate` (Number) The broadcast Storm Control rate for the port profile. Can be between 0 and 14880000.
|
||||
@@ -74,11 +75,9 @@ resource "unifi_port_profile" "poe_disabled" {
|
||||
- `stormctrl_ucast_level` (Number) The unknown unicast Storm Control level for the port profile. Can be between 0 and 100.
|
||||
- `stormctrl_ucast_rate` (Number) The unknown unicast Storm Control rate for the port profile. Can be between 0 and 14880000.
|
||||
- `stp_port_mode` (Boolean) Enable spanning tree protocol on the port profile. Defaults to `true`.
|
||||
- `tagged_networkconf_ids` (Set of String) The IDs of networks to tag traffic with for the port profile.
|
||||
- `tagged_vlan_mgmt` (String) The VLAN management type for the port profile. Can be one of 'auto', 'block_all', or 'custom'.
|
||||
- `voice_networkconf_id` (String) The ID of network to use as the voice network on the port profile.
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of the port profile.
|
||||
|
||||
|
||||
|
||||
@@ -60,5 +60,3 @@ Required:
|
||||
Optional:
|
||||
|
||||
- `port` (Number) Port of authentication service. Defaults to `1812`.
|
||||
|
||||
|
||||
|
||||
@@ -49,5 +49,3 @@ Optional:
|
||||
|
||||
- `comment` (String) Comment.
|
||||
- `key` (String) Public SSH key.
|
||||
|
||||
|
||||
|
||||
@@ -29,5 +29,3 @@ description: |-
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of the settings.
|
||||
|
||||
|
||||
|
||||
@@ -18,14 +18,9 @@ description: |-
|
||||
### Optional
|
||||
|
||||
- `dhcp_relay_servers` (List of String) The DHCP relay servers.
|
||||
- `firewall_guest_default_log` (Boolean) Whether the guest firewall log is enabled.
|
||||
- `firewall_lan_default_log` (Boolean) Whether the LAN firewall log is enabled.
|
||||
- `firewall_wan_default_log` (Boolean) Whether the WAN firewall log is enabled.
|
||||
- `multicast_dns_enabled` (Boolean) Whether multicast DNS is enabled.
|
||||
- `site` (String) The name of the site to associate the settings with.
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of the settings.
|
||||
|
||||
|
||||
|
||||
@@ -56,5 +56,3 @@ resource "unifi_static_route" "interface" {
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of the static route.
|
||||
|
||||
|
||||
|
||||
@@ -52,5 +52,3 @@ resource "unifi_user" "test" {
|
||||
- `hostname` (String) The hostname of the user.
|
||||
- `id` (String) The ID of the user.
|
||||
- `ip` (String) The IP address of the user.
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ resource "unifi_wlan" "wifi" {
|
||||
|
||||
### Required
|
||||
|
||||
- `name` (String) The SSID of the network.
|
||||
- `name` (String) The SSID of the network. SSID length must be between 1 and 32 characters.
|
||||
- `security` (String) The type of WiFi security for this network. Valid values are: `wpapsk`, `wpaeap`, and `open`.
|
||||
- `user_group_id` (String) ID of the user group to use for this network.
|
||||
|
||||
|
||||
3
go.mod
3
go.mod
@@ -193,8 +193,11 @@ require (
|
||||
github.com/hashicorp/logutils v1.0.0 // indirect
|
||||
github.com/hashicorp/terraform-exec v0.22.0 // indirect
|
||||
github.com/hashicorp/terraform-json v0.24.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-framework v1.14.1 // indirect
|
||||
github.com/hashicorp/terraform-plugin-framework-validators v0.17.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-go v0.26.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-mux v0.18.0 // indirect
|
||||
github.com/hashicorp/terraform-registry-address v0.2.4 // indirect
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||
|
||||
6
go.sum
6
go.sum
@@ -492,10 +492,16 @@ github.com/hashicorp/terraform-json v0.24.0 h1:rUiyF+x1kYawXeRth6fKFm/MdfBS6+lW4
|
||||
github.com/hashicorp/terraform-json v0.24.0/go.mod h1:Nfj5ubo9xbu9uiAoZVBsNOjvNKB66Oyrvtit74kC7ow=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.20.1 h1:Fq7E/HrU8kuZu3hNliZGwloFWSYfWEOWnylFhYQIoys=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.20.1/go.mod h1:Yz6HoK7/EgzSrHPB9J/lWFzwl9/xep2OPnc5jaJDV90=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.14.1 h1:jaT1yvU/kEKEsxnbrn4ZHlgcxyIfjvZ41BLdlLk52fY=
|
||||
github.com/hashicorp/terraform-plugin-framework v1.14.1/go.mod h1:xNUKmvTs6ldbwTuId5euAtg37dTxuyj3LHS3uj7BHQ4=
|
||||
github.com/hashicorp/terraform-plugin-framework-validators v0.17.0 h1:0uYQcqqgW3BMyyve07WJgpKorXST3zkpzvrOnf3mpbg=
|
||||
github.com/hashicorp/terraform-plugin-framework-validators v0.17.0/go.mod h1:VwdfgE/5Zxm43flraNa0VjcvKQOGVrcO4X8peIri0T0=
|
||||
github.com/hashicorp/terraform-plugin-go v0.26.0 h1:cuIzCv4qwigug3OS7iKhpGAbZTiypAfFQmw8aE65O2M=
|
||||
github.com/hashicorp/terraform-plugin-go v0.26.0/go.mod h1:+CXjuLDiFgqR+GcrM5a2E2Kal5t5q2jb0E3D57tTdNY=
|
||||
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
|
||||
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
|
||||
github.com/hashicorp/terraform-plugin-mux v0.18.0 h1:7491JFSpWyAe0v9YqBT+kel7mzHAbO5EpxxT0cUL/Ms=
|
||||
github.com/hashicorp/terraform-plugin-mux v0.18.0/go.mod h1:Ho1g4Rr8qv0qTJlcRKfjjXTIO67LNbDtM6r+zHUNHJQ=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1 h1:WNMsTLkZf/3ydlgsuXePa3jvZFwAJhruxTxP/c1Viuw=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1/go.mod h1:P6o64QS97plG44iFzSM6rAn6VJIC/Sy9a9IkEtl79K4=
|
||||
github.com/hashicorp/terraform-plugin-testing v1.11.0 h1:MeDT5W3YHbONJt2aPQyaBsgQeAIckwPX41EUHXEn29A=
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func cidrValidate(raw interface{}, key string) ([]string, []error) {
|
||||
v, ok := raw.(string)
|
||||
if !ok {
|
||||
return nil, []error{fmt.Errorf("expected string, got %T", raw)}
|
||||
}
|
||||
|
||||
_, _, err := net.ParseCIDR(v)
|
||||
if err != nil {
|
||||
return nil, []error{err}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func cidrDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
|
||||
_, oldNet, err := net.ParseCIDR(old)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
_, newNet, err := net.ParseCIDR(new)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return oldNet.String() == newNet.String()
|
||||
}
|
||||
|
||||
func cidrZeroBased(cidr string) string {
|
||||
_, cidrNet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return cidrNet.String()
|
||||
}
|
||||
|
||||
func cidrOneBased(cidr string) string {
|
||||
_, cidrNet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
cidrNet.IP[3]++
|
||||
|
||||
return cidrNet.String()
|
||||
}
|
||||
78
internal/provider/client.go
Normal file
78
internal/provider/client.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/go-version"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func IsServerErrorContains(err error, messageContains string) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
var se *unifi.ServerError
|
||||
if errors.As(err, &se) {
|
||||
if strings.Contains(se.Message, messageContains) {
|
||||
return true
|
||||
}
|
||||
// check details
|
||||
if se.Details != nil {
|
||||
for _, m := range se.Details {
|
||||
if strings.Contains(m.Message, messageContains) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ClientConfig struct {
|
||||
Username string
|
||||
Password string
|
||||
ApiKey string
|
||||
Url string
|
||||
Site string
|
||||
Insecure bool
|
||||
HttpConfigurer func() http.RoundTripper
|
||||
}
|
||||
|
||||
func NewClient(cfg *ClientConfig) (*Client, error) {
|
||||
unifiClient, err := unifi.NewClient(&unifi.ClientConfig{
|
||||
URL: cfg.Url,
|
||||
User: cfg.Username,
|
||||
Password: cfg.Password,
|
||||
APIKey: cfg.ApiKey,
|
||||
HttpRoundTripperProvider: cfg.HttpConfigurer,
|
||||
ValidationMode: unifi.DisableValidation,
|
||||
Logger: unifi.NewDefaultLogger(unifi.WarnLevel),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = CheckMinimumControllerVersion(unifiClient.Version())
|
||||
log.Printf("[TRACE] Unifi controller version: %q", unifiClient.Version())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c := &Client{
|
||||
Client: unifiClient,
|
||||
Site: cfg.Site,
|
||||
Version: version.Must(version.NewVersion(unifiClient.Version())),
|
||||
}
|
||||
if cfg.ApiKey != "" && !c.SupportsApiKeyAuthentication() {
|
||||
return nil, fmt.Errorf("API key authentication is not supported on this controller version: %s, you must be on %s or higher", c.Version, ControllerVersionApiKeyAuth)
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
unifi.Client
|
||||
Site string
|
||||
Version *version.Version
|
||||
}
|
||||
@@ -11,37 +11,37 @@ func asVersion(versionString string) *version.Version {
|
||||
}
|
||||
|
||||
var (
|
||||
controllerV6 = asVersion("6.0.0")
|
||||
controllerV7 = asVersion("7.0.0")
|
||||
controllerVersionApiKeyAuth = asVersion("9.0.108")
|
||||
ControllerV6 = asVersion("6.0.0")
|
||||
ControllerV7 = asVersion("7.0.0")
|
||||
ControllerVersionApiKeyAuth = asVersion("9.0.108")
|
||||
|
||||
// https://community.ui.com/releases/UniFi-Network-Controller-6-1-61/62f1ad38-1ac5-430c-94b0-becbb8f71d7d
|
||||
controllerVersionWPA3 = asVersion("6.1.61")
|
||||
ControllerVersionWPA3 = asVersion("6.1.61")
|
||||
)
|
||||
|
||||
func (c *client) IsControllerV6() bool {
|
||||
return c.version.GreaterThanOrEqual(controllerV6)
|
||||
func (c *Client) IsControllerV6() bool {
|
||||
return c.Version.GreaterThanOrEqual(ControllerV6)
|
||||
}
|
||||
|
||||
func (c *client) IsControllerV7() bool {
|
||||
return c.version.GreaterThanOrEqual(controllerV7)
|
||||
func (c *Client) IsControllerV7() bool {
|
||||
return c.Version.GreaterThanOrEqual(ControllerV7)
|
||||
}
|
||||
|
||||
func (c *client) SupportsApiKeyAuthentication() bool {
|
||||
return c.version.GreaterThanOrEqual(controllerVersionApiKeyAuth)
|
||||
func (c *Client) SupportsApiKeyAuthentication() bool {
|
||||
return c.Version.GreaterThanOrEqual(ControllerVersionApiKeyAuth)
|
||||
}
|
||||
|
||||
func (c *client) SupportsWPA3() bool {
|
||||
return c.version.GreaterThanOrEqual(controllerVersionWPA3)
|
||||
func (c *Client) SupportsWPA3() bool {
|
||||
return c.Version.GreaterThanOrEqual(ControllerVersionWPA3)
|
||||
}
|
||||
|
||||
func checkMinimumControllerVersion(versionString string) error {
|
||||
func CheckMinimumControllerVersion(versionString string) error {
|
||||
v, err := version.NewVersion(versionString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.LessThan(controllerV6) {
|
||||
return fmt.Errorf("Controller version %q or greater is required to use the provider, found %q.", controllerV6, v)
|
||||
if v.LessThan(ControllerV6) {
|
||||
return fmt.Errorf("Controller version %q or greater is required to use the provider, found %q.", ControllerV6, v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,216 +1,13 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/hashicorp/go-version"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
const (
|
||||
ProviderUsernameDescription = "Local user name for the Unifi controller API. Can be specified with the `UNIFI_USERNAME` environment variable."
|
||||
ProviderPasswordDescription = "Password for the user accessing the API. Can be specified with the `UNIFI_PASSWORD` environment variable."
|
||||
ProviderAPIKeyDescription = "API Key for the user accessing the API. Can be specified with the `UNIFI_API_KEY` environment variable. Controller version 9.0.108 or later is required."
|
||||
ProviderAPIURLDescription = "URL of the controller API. Can be specified with the `UNIFI_API` environment variable. " +
|
||||
"You should **NOT** supply the path (`/api`), the SDK will discover the appropriate paths. This is to support UDM Pro style API paths as well as more standard controller paths."
|
||||
ProviderSiteDescription = "The site in the Unifi controller this provider will manage. Can be specified with the `UNIFI_SITE` environment variable. Default: `default`"
|
||||
ProviderAllowInsecureDescription = "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."
|
||||
)
|
||||
|
||||
func init() {
|
||||
schema.DescriptionKind = schema.StringMarkdown
|
||||
|
||||
schema.SchemaDescriptionBuilder = func(s *schema.Schema) string {
|
||||
desc := s.Description
|
||||
if s.Default != nil {
|
||||
desc += fmt.Sprintf(" Defaults to `%v`.", s.Default)
|
||||
}
|
||||
if s.Deprecated != "" {
|
||||
desc += " " + s.Deprecated
|
||||
}
|
||||
return strings.TrimSpace(desc)
|
||||
}
|
||||
}
|
||||
|
||||
func New(version string) func() *schema.Provider {
|
||||
return func() *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,
|
||||
Optional: 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,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_PASSWORD", ""),
|
||||
},
|
||||
"api_key": {
|
||||
Description: "API Key for the user accessing the API. Can be specified with the `UNIFI_API_KEY` " +
|
||||
"environment variable. Controller version 9.0.108 or later is required.",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_API_KEY", ""),
|
||||
},
|
||||
"api_url": {
|
||||
Description: "URL of the controller API. Can be specified with the `UNIFI_API` environment variable. " +
|
||||
"You should **NOT** supply the path (`/api`), the SDK will discover the appropriate paths. This is " +
|
||||
"to support UDM Pro style API paths as well as more standard controller paths.",
|
||||
|
||||
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. Can be specified with the " +
|
||||
"`UNIFI_INSECURE` environment variable.",
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_INSECURE", false),
|
||||
},
|
||||
},
|
||||
DataSourcesMap: map[string]*schema.Resource{
|
||||
"unifi_ap_group": dataAPGroup(),
|
||||
"unifi_network": dataNetwork(),
|
||||
"unifi_port_profile": dataPortProfile(),
|
||||
"unifi_radius_profile": dataRADIUSProfile(),
|
||||
"unifi_user_group": dataUserGroup(),
|
||||
"unifi_user": dataUser(),
|
||||
"unifi_account": dataAccount(),
|
||||
},
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
// TODO: "unifi_ap_group"
|
||||
"unifi_device": resourceDevice(),
|
||||
"unifi_dynamic_dns": resourceDynamicDNS(),
|
||||
"unifi_firewall_group": resourceFirewallGroup(),
|
||||
"unifi_firewall_rule": resourceFirewallRule(),
|
||||
"unifi_network": resourceNetwork(),
|
||||
"unifi_port_forward": resourcePortForward(),
|
||||
"unifi_port_profile": resourcePortProfile(),
|
||||
"unifi_radius_profile": resourceRadiusProfile(),
|
||||
"unifi_site": resourceSite(),
|
||||
"unifi_static_route": resourceStaticRoute(),
|
||||
"unifi_user_group": resourceUserGroup(),
|
||||
"unifi_user": resourceUser(),
|
||||
"unifi_wlan": resourceWLAN(),
|
||||
"unifi_account": resourceAccount(),
|
||||
|
||||
"unifi_setting_mgmt": resourceSettingMgmt(),
|
||||
"unifi_setting_radius": resourceSettingRadius(),
|
||||
"unifi_setting_usg": resourceSettingUsg(),
|
||||
},
|
||||
}
|
||||
|
||||
p.ConfigureContextFunc = configure(version, p)
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func createHTTPTransport(insecure bool, subsystem string) http.RoundTripper {
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: insecure,
|
||||
},
|
||||
}
|
||||
|
||||
t := logging.NewSubsystemLoggingHTTPTransport(subsystem, transport)
|
||||
return t
|
||||
}
|
||||
|
||||
func configure(v string, p *schema.Provider) schema.ConfigureContextFunc {
|
||||
return func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
|
||||
user := d.Get("username").(string)
|
||||
pass := d.Get("password").(string)
|
||||
apiKey := d.Get("api_key").(string)
|
||||
if apiKey != "" && (user != "" || pass != "") {
|
||||
return nil, diag.FromErr(errors.New("only one of `username`/`password` or `api_key` can be set"))
|
||||
} else if apiKey == "" && (user == "" || pass == "") {
|
||||
return nil, diag.FromErr(errors.New("either `username` and `password` or `api_key` must be set"))
|
||||
}
|
||||
baseURL := d.Get("api_url").(string)
|
||||
site := d.Get("site").(string)
|
||||
insecure := d.Get("allow_insecure").(bool)
|
||||
unifiClient, err := unifi.NewClient(&unifi.ClientConfig{
|
||||
URL: baseURL,
|
||||
User: user,
|
||||
Password: pass,
|
||||
APIKey: apiKey,
|
||||
HttpRoundTripperProvider: func() http.RoundTripper {
|
||||
return createHTTPTransport(insecure, "unifi")
|
||||
},
|
||||
ValidationMode: unifi.DisableValidation,
|
||||
Logger: unifi.NewDefaultLogger(unifi.WarnLevel),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, diag.FromErr(err)
|
||||
}
|
||||
err = checkMinimumControllerVersion(unifiClient.Version())
|
||||
log.Printf("[TRACE] Unifi controller version: %q", unifiClient.Version())
|
||||
if err != nil {
|
||||
return nil, diag.FromErr(err)
|
||||
}
|
||||
c := &client{
|
||||
c: unifiClient,
|
||||
site: site,
|
||||
version: version.Must(version.NewVersion(unifiClient.Version())),
|
||||
}
|
||||
if apiKey != "" && !c.SupportsApiKeyAuthentication() {
|
||||
return nil, diag.FromErr(fmt.Errorf("API key authentication is not supported on this controller version: %s, you must be on %s or higher", c.version, controllerVersionApiKeyAuth))
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
func IsServerErrorContains(err error, messageContains string) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
var se *unifi.ServerError
|
||||
if errors.As(err, &se) {
|
||||
if strings.Contains(se.Message, messageContains) {
|
||||
return true
|
||||
}
|
||||
// check details
|
||||
if se.Details != nil {
|
||||
for _, m := range se.Details {
|
||||
if strings.Contains(m.Message, messageContains) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type client struct {
|
||||
c unifi.Client
|
||||
site string
|
||||
version *version.Version
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -1,7 +1,8 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
|
||||
func dataAccount() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Description: "`unifi_account` data source can be used to retrieve RADIUS user accounts",
|
||||
Description: "unifi_account data source can be used to retrieve RADIUS user accounts",
|
||||
|
||||
ReadContext: dataAccountRead,
|
||||
|
||||
@@ -57,15 +58,15 @@ func dataAccount() *schema.Resource {
|
||||
}
|
||||
|
||||
func dataAccountRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
accounts, err := c.c.ListAccount(ctx, site)
|
||||
accounts, err := c.ListAccount(ctx, site)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,7 +1,8 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -35,15 +36,15 @@ func dataAPGroup() *schema.Resource {
|
||||
}
|
||||
|
||||
func dataAPGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
groups, err := c.c.ListAPGroup(ctx, site)
|
||||
groups, err := c.ListAPGroup(ctx, site)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -1,7 +1,9 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -279,19 +281,19 @@ func dataNetwork() *schema.Resource {
|
||||
}
|
||||
|
||||
func dataNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
site := d.Get("site").(string)
|
||||
id := d.Get("id").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
if (name == "" && id == "") || (name != "" && id != "") {
|
||||
return diag.Errorf("One of 'name' OR 'id' is required")
|
||||
}
|
||||
|
||||
networks, err := c.c.ListNetwork(ctx, site)
|
||||
networks, err := c.ListNetwork(ctx, site)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -327,7 +329,7 @@ func dataNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface
|
||||
d.Set("name", n.Name)
|
||||
d.Set("purpose", n.Purpose)
|
||||
d.Set("vlan_id", n.VLAN)
|
||||
d.Set("subnet", cidrZeroBased(n.IPSubnet))
|
||||
d.Set("subnet", utils.CidrZeroBased(n.IPSubnet))
|
||||
d.Set("network_group", n.NetworkGroup)
|
||||
d.Set("dhcp_dns", dhcpDNS)
|
||||
d.Set("dhcp_start", n.DHCPDStart)
|
||||
@@ -1,7 +1,8 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
@@ -14,7 +15,7 @@ func TestAccDataNetwork_byName(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing version: %s", err)
|
||||
}
|
||||
if v.LessThan(controllerV7) {
|
||||
if v.LessThan(provider.ControllerV7) {
|
||||
defaultName = "LAN"
|
||||
}
|
||||
|
||||
@@ -41,7 +42,7 @@ func TestAccDataNetwork_byID(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing version: %s", err)
|
||||
}
|
||||
if v.LessThan(controllerV7) {
|
||||
if v.LessThan(provider.ControllerV7) {
|
||||
defaultName = "LAN"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -36,15 +37,15 @@ func dataPortProfile() *schema.Resource {
|
||||
}
|
||||
|
||||
func dataPortProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
groups, err := c.c.ListPortProfile(ctx, site)
|
||||
groups, err := c.ListPortProfile(ctx, site)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -1,7 +1,8 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -36,15 +37,15 @@ func dataRADIUSProfile() *schema.Resource {
|
||||
}
|
||||
|
||||
func dataRADIUSProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
profiles, err := c.c.ListRADIUSProfile(ctx, site)
|
||||
profiles, err := c.ListRADIUSProfile(ctx, site)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -91,20 +92,20 @@ func dataUser() *schema.Resource {
|
||||
}
|
||||
|
||||
func dataUserRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
mac := d.Get("mac").(string)
|
||||
|
||||
macResp, err := c.c.GetUserByMAC(ctx, site, strings.ToLower(mac))
|
||||
macResp, err := c.GetUserByMAC(ctx, site, strings.ToLower(mac))
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
resp, err := c.c.GetUser(ctx, site, macResp.ID)
|
||||
resp, err := c.GetUser(ctx, site, macResp.ID)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
@@ -45,15 +46,15 @@ func dataUserGroup() *schema.Resource {
|
||||
}
|
||||
|
||||
func dataUserGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
groups, err := c.c.ListUserGroup(ctx, site)
|
||||
groups, err := c.ListUserGroup(ctx, site)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
20
internal/provider/v1/diff_suppressions.go
Normal file
20
internal/provider/v1/diff_suppressions.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"net"
|
||||
)
|
||||
|
||||
func cidrDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
|
||||
_, oldNet, err := net.ParseCIDR(old)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
_, newNet, err := net.ParseCIDR(new)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return oldNet.String() == newNet.String()
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
165
internal/provider/v1/provider.go
Normal file
165
internal/provider/v1/provider.go
Normal file
@@ -0,0 +1,165 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func init() {
|
||||
schema.DescriptionKind = schema.StringMarkdown
|
||||
|
||||
schema.SchemaDescriptionBuilder = func(s *schema.Schema) string {
|
||||
desc := s.Description
|
||||
if s.Default != nil {
|
||||
desc += fmt.Sprintf(" Defaults to `%v`.", s.Default)
|
||||
}
|
||||
if s.Deprecated != "" {
|
||||
desc += " " + s.Deprecated
|
||||
}
|
||||
return strings.TrimSpace(desc)
|
||||
}
|
||||
}
|
||||
|
||||
func New(version string) func() *schema.Provider {
|
||||
return func() *schema.Provider {
|
||||
p := &schema.Provider{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"username": {
|
||||
Description: provider.ProviderUsernameDescription,
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_USERNAME", ""),
|
||||
},
|
||||
"password": {
|
||||
Description: provider.ProviderPasswordDescription,
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_PASSWORD", ""),
|
||||
},
|
||||
"api_key": {
|
||||
Description: provider.ProviderAPIKeyDescription,
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_API_KEY", ""),
|
||||
},
|
||||
"api_url": {
|
||||
Description: provider.ProviderAPIURLDescription,
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_API", ""),
|
||||
},
|
||||
"site": {
|
||||
Description: provider.ProviderSiteDescription,
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_SITE", "default"),
|
||||
},
|
||||
"allow_insecure": {
|
||||
Description: provider.ProviderAllowInsecureDescription,
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("UNIFI_INSECURE", false),
|
||||
},
|
||||
},
|
||||
DataSourcesMap: map[string]*schema.Resource{
|
||||
"unifi_ap_group": dataAPGroup(),
|
||||
"unifi_network": dataNetwork(),
|
||||
"unifi_port_profile": dataPortProfile(),
|
||||
"unifi_radius_profile": dataRADIUSProfile(),
|
||||
"unifi_user_group": dataUserGroup(),
|
||||
"unifi_user": dataUser(),
|
||||
"unifi_account": dataAccount(),
|
||||
},
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
// TODO: "unifi_ap_group"
|
||||
"unifi_device": resourceDevice(),
|
||||
"unifi_dynamic_dns": resourceDynamicDNS(),
|
||||
"unifi_firewall_group": resourceFirewallGroup(),
|
||||
"unifi_firewall_rule": resourceFirewallRule(),
|
||||
"unifi_network": resourceNetwork(),
|
||||
"unifi_port_forward": resourcePortForward(),
|
||||
"unifi_port_profile": resourcePortProfile(),
|
||||
"unifi_radius_profile": resourceRadiusProfile(),
|
||||
"unifi_site": resourceSite(),
|
||||
"unifi_static_route": resourceStaticRoute(),
|
||||
"unifi_user_group": resourceUserGroup(),
|
||||
"unifi_user": resourceUser(),
|
||||
"unifi_wlan": resourceWLAN(),
|
||||
"unifi_account": resourceAccount(),
|
||||
|
||||
"unifi_setting_mgmt": resourceSettingMgmt(),
|
||||
"unifi_setting_radius": resourceSettingRadius(),
|
||||
"unifi_setting_usg": resourceSettingUsg(),
|
||||
},
|
||||
}
|
||||
|
||||
p.ConfigureContextFunc = configure(version, p)
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func createHTTPTransport(insecure bool, subsystem string) http.RoundTripper {
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: insecure,
|
||||
},
|
||||
}
|
||||
|
||||
t := logging.NewSubsystemLoggingHTTPTransport(subsystem, transport)
|
||||
return t
|
||||
}
|
||||
|
||||
func configure(v string, p *schema.Provider) schema.ConfigureContextFunc {
|
||||
return func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
|
||||
user := d.Get("username").(string)
|
||||
pass := d.Get("password").(string)
|
||||
apiKey := d.Get("api_key").(string)
|
||||
if apiKey != "" && (user != "" || pass != "") {
|
||||
return nil, diag.FromErr(errors.New("only one of `username`/`password` or `api_key` can be set"))
|
||||
} else if apiKey == "" && (user == "" || pass == "") {
|
||||
return nil, diag.FromErr(errors.New("either `username` and `password` or `api_key` must be set"))
|
||||
}
|
||||
baseURL := d.Get("api_url").(string)
|
||||
site := d.Get("site").(string)
|
||||
insecure := d.Get("allow_insecure").(bool)
|
||||
|
||||
c, err := provider.NewClient(&provider.ClientConfig{
|
||||
Username: user,
|
||||
Password: pass,
|
||||
ApiKey: apiKey,
|
||||
Url: baseURL,
|
||||
Site: site,
|
||||
HttpConfigurer: func() http.RoundTripper {
|
||||
return createHTTPTransport(insecure, "unifi")
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, diag.FromErr(err)
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -38,7 +38,7 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
func runAcceptanceTests(m *testing.M) int {
|
||||
dc, err := compose.NewDockerCompose("../../docker-compose.yaml")
|
||||
dc, err := compose.NewDockerCompose("../../../docker-compose.yaml")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -74,7 +75,7 @@ func resourceAccount() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceAccountGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -83,10 +84,10 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, meta int
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateAccount(ctx, site, req)
|
||||
resp, err := c.CreateAccount(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -97,11 +98,11 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, meta int
|
||||
}
|
||||
|
||||
func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
req, err := resourceAccountGetResourceData(d)
|
||||
@@ -112,7 +113,7 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, meta int
|
||||
req.ID = d.Id()
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateAccount(ctx, site, req)
|
||||
resp, err := c.UpdateAccount(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -121,16 +122,16 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, meta int
|
||||
}
|
||||
|
||||
func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
//name := d.Get("name").(string)
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
id := d.Id()
|
||||
err := c.c.DeleteAccount(ctx, site, id)
|
||||
err := c.DeleteAccount(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil
|
||||
}
|
||||
@@ -138,16 +139,16 @@ func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, meta int
|
||||
}
|
||||
|
||||
func resourceAccountRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetAccount(ctx, site, id)
|
||||
resp, err := c.GetAccount(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,9 +1,10 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -138,11 +139,11 @@ func resourceDevice() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceDeviceImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
id := d.Id()
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
if colons := strings.Count(id, ":"); colons == 1 || colons == 6 {
|
||||
@@ -154,7 +155,7 @@ func resourceDeviceImport(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
if macAddressRegexp.MatchString(id) {
|
||||
// look up id by mac
|
||||
mac := cleanMAC(id)
|
||||
device, err := c.c.GetDeviceByMAC(ctx, site, mac)
|
||||
device, err := c.GetDeviceByMAC(ctx, site, mac)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -174,11 +175,11 @@ func resourceDeviceImport(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
}
|
||||
|
||||
func resourceDeviceCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
mac := d.Get("mac").(string)
|
||||
@@ -187,7 +188,7 @@ func resourceDeviceCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
}
|
||||
|
||||
mac = cleanMAC(mac)
|
||||
device, err := c.c.GetDeviceByMAC(ctx, site, mac)
|
||||
device, err := c.GetDeviceByMAC(ctx, site, mac)
|
||||
|
||||
if device == nil {
|
||||
return diag.Errorf("device not found using mac %q", mac)
|
||||
@@ -201,7 +202,7 @@ func resourceDeviceCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
return diag.Errorf("Device must be adopted before it can be managed")
|
||||
}
|
||||
|
||||
err := c.c.AdoptDevice(ctx, site, mac)
|
||||
err := c.AdoptDevice(ctx, site, mac)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -217,11 +218,11 @@ func resourceDeviceCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
}
|
||||
|
||||
func resourceDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
req, err := resourceDeviceGetResourceData(d)
|
||||
@@ -232,7 +233,7 @@ func resourceDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
req.ID = d.Id()
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateDevice(ctx, site, req)
|
||||
resp, err := c.UpdateDevice(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -246,7 +247,7 @@ func resourceDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
}
|
||||
|
||||
func resourceDeviceDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
if !d.Get("forget_on_destroy").(bool) {
|
||||
return nil
|
||||
@@ -256,10 +257,10 @@ func resourceDeviceDelete(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
mac := d.Get("mac").(string)
|
||||
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
err := c.c.ForgetDevice(ctx, site, mac)
|
||||
err := c.ForgetDevice(ctx, site, mac)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -273,16 +274,16 @@ func resourceDeviceDelete(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
}
|
||||
|
||||
func resourceDeviceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetDevice(ctx, site, id)
|
||||
resp, err := c.GetDevice(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -388,13 +389,13 @@ func fromPortOverride(po unifi.DevicePortOverrides) (map[string]interface{}, err
|
||||
}
|
||||
|
||||
func waitForDeviceState(ctx context.Context, d *schema.ResourceData, meta interface{}, targetState unifi.DeviceState, pendingStates []unifi.DeviceState, timeout time.Duration) (*unifi.Device, error) {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
mac := d.Get("mac").(string)
|
||||
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
// Always consider unknown to be a pending state.
|
||||
@@ -409,7 +410,7 @@ func waitForDeviceState(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
Pending: pending,
|
||||
Target: []string{targetState.String()},
|
||||
Refresh: func() (interface{}, string, error) {
|
||||
device, err := c.c.GetDeviceByMAC(ctx, site, mac)
|
||||
device, err := c.GetDeviceByMAC(ctx, site, mac)
|
||||
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
err = nil
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,8 +1,9 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -75,7 +76,7 @@ func resourceDynamicDNS() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceDynamicDNSCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceDynamicDNSGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -84,10 +85,10 @@ func resourceDynamicDNSCreate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateDynamicDNS(ctx, site, req)
|
||||
resp, err := c.CreateDynamicDNS(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -126,16 +127,16 @@ func resourceDynamicDNSSetResourceData(resp *unifi.DynamicDNS, d *schema.Resourc
|
||||
}
|
||||
|
||||
func resourceDynamicDNSRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetDynamicDNS(ctx, site, id)
|
||||
resp, err := c.GetDynamicDNS(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -148,7 +149,7 @@ func resourceDynamicDNSRead(ctx context.Context, d *schema.ResourceData, meta in
|
||||
}
|
||||
|
||||
func resourceDynamicDNSUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceDynamicDNSGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -159,11 +160,11 @@ func resourceDynamicDNSUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateDynamicDNS(ctx, site, req)
|
||||
resp, err := c.UpdateDynamicDNS(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -172,15 +173,15 @@ func resourceDynamicDNSUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourceDynamicDNSDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
err := c.c.DeleteDynamicDNS(ctx, site, id)
|
||||
err := c.DeleteDynamicDNS(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -1,8 +1,10 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -57,7 +59,7 @@ func resourceFirewallGroup() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceFirewallGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceFirewallGroupGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -66,12 +68,12 @@ func resourceFirewallGroupCreate(ctx context.Context, d *schema.ResourceData, me
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateFirewallGroup(ctx, site, req)
|
||||
resp, err := c.CreateFirewallGroup(ctx, site, req)
|
||||
if err != nil {
|
||||
if IsServerErrorContains(err, "api.err.FirewallGroupExisted") {
|
||||
if provider.IsServerErrorContains(err, "api.err.FirewallGroupExisted") {
|
||||
return diag.Errorf("firewall groups must have unique names: %s", err)
|
||||
}
|
||||
return diag.FromErr(err)
|
||||
@@ -83,7 +85,7 @@ func resourceFirewallGroupCreate(ctx context.Context, d *schema.ResourceData, me
|
||||
}
|
||||
|
||||
func resourceFirewallGroupGetResourceData(d *schema.ResourceData) (*unifi.FirewallGroup, error) {
|
||||
members, err := setToStringSlice(d.Get("members").(*schema.Set))
|
||||
members, err := utils.SetToStringSlice(d.Get("members").(*schema.Set))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -99,22 +101,22 @@ func resourceFirewallGroupSetResourceData(resp *unifi.FirewallGroup, d *schema.R
|
||||
d.Set("site", site)
|
||||
d.Set("name", resp.Name)
|
||||
d.Set("type", resp.GroupType)
|
||||
d.Set("members", stringSliceToSet(resp.GroupMembers))
|
||||
d.Set("members", utils.StringSliceToSet(resp.GroupMembers))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceFirewallGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetFirewallGroup(ctx, site, id)
|
||||
resp, err := c.GetFirewallGroup(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -127,7 +129,7 @@ func resourceFirewallGroupRead(ctx context.Context, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourceFirewallGroupUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceFirewallGroupGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -138,11 +140,11 @@ func resourceFirewallGroupUpdate(ctx context.Context, d *schema.ResourceData, me
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateFirewallGroup(ctx, site, req)
|
||||
resp, err := c.UpdateFirewallGroup(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -151,16 +153,16 @@ func resourceFirewallGroupUpdate(ctx context.Context, d *schema.ResourceData, me
|
||||
}
|
||||
|
||||
func resourceFirewallGroupDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
err := c.c.DeleteFirewallGroup(ctx, site, id)
|
||||
err := c.DeleteFirewallGroup(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,8 +1,10 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
"regexp"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
@@ -210,7 +212,7 @@ func resourceFirewallRule() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceFirewallRuleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceFirewallRuleGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -219,12 +221,12 @@ func resourceFirewallRuleCreate(ctx context.Context, d *schema.ResourceData, met
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateFirewallRule(ctx, site, req)
|
||||
resp, err := c.CreateFirewallRule(ctx, site, req)
|
||||
if err != nil {
|
||||
if IsServerErrorContains(err, "api.err.FirewallGroupTypeExists") {
|
||||
if provider.IsServerErrorContains(err, "api.err.FirewallGroupTypeExists") {
|
||||
return diag.Errorf("firewall rule groups must be of different group types (ie. a port group and address group): %s", err)
|
||||
}
|
||||
|
||||
@@ -237,12 +239,12 @@ func resourceFirewallRuleCreate(ctx context.Context, d *schema.ResourceData, met
|
||||
}
|
||||
|
||||
func resourceFirewallRuleGetResourceData(d *schema.ResourceData) (*unifi.FirewallRule, error) {
|
||||
srcFirewallGroupIDs, err := setToStringSlice(d.Get("src_firewall_group_ids").(*schema.Set))
|
||||
srcFirewallGroupIDs, err := utils.SetToStringSlice(d.Get("src_firewall_group_ids").(*schema.Set))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dstFirewallGroupIDs, err := setToStringSlice(d.Get("dst_firewall_group_ids").(*schema.Set))
|
||||
dstFirewallGroupIDs, err := utils.SetToStringSlice(d.Get("dst_firewall_group_ids").(*schema.Set))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -300,7 +302,7 @@ func resourceFirewallRuleSetResourceData(resp *unifi.FirewallRule, d *schema.Res
|
||||
d.Set("state_related", resp.StateRelated)
|
||||
|
||||
d.Set("src_network_type", resp.SrcNetworkType)
|
||||
d.Set("src_firewall_group_ids", stringSliceToSet(resp.SrcFirewallGroupIDs))
|
||||
d.Set("src_firewall_group_ids", utils.StringSliceToSet(resp.SrcFirewallGroupIDs))
|
||||
d.Set("src_mac", resp.SrcMACAddress)
|
||||
d.Set("src_address", resp.SrcAddress)
|
||||
d.Set("src_address_ipv6", resp.SrcAddressIPV6)
|
||||
@@ -308,7 +310,7 @@ func resourceFirewallRuleSetResourceData(resp *unifi.FirewallRule, d *schema.Res
|
||||
d.Set("src_port", resp.SrcPort)
|
||||
|
||||
d.Set("dst_network_type", resp.DstNetworkType)
|
||||
d.Set("dst_firewall_group_ids", stringSliceToSet(resp.DstFirewallGroupIDs))
|
||||
d.Set("dst_firewall_group_ids", utils.StringSliceToSet(resp.DstFirewallGroupIDs))
|
||||
d.Set("dst_address", resp.DstAddress)
|
||||
d.Set("dst_address_ipv6", resp.DstAddressIPV6)
|
||||
d.Set("dst_network_id", resp.DstNetworkID)
|
||||
@@ -318,16 +320,16 @@ func resourceFirewallRuleSetResourceData(resp *unifi.FirewallRule, d *schema.Res
|
||||
}
|
||||
|
||||
func resourceFirewallRuleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetFirewallRule(ctx, site, id)
|
||||
resp, err := c.GetFirewallRule(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -340,7 +342,7 @@ func resourceFirewallRuleRead(ctx context.Context, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourceFirewallRuleUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceFirewallRuleGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -351,11 +353,11 @@ func resourceFirewallRuleUpdate(ctx context.Context, d *schema.ResourceData, met
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateFirewallRule(ctx, site, req)
|
||||
resp, err := c.UpdateFirewallRule(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -364,15 +366,15 @@ func resourceFirewallRuleUpdate(ctx context.Context, d *schema.ResourceData, met
|
||||
}
|
||||
|
||||
func resourceFirewallRuleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
err := c.c.DeleteFirewallRule(ctx, site, id)
|
||||
err := c.DeleteFirewallRule(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,9 +1,11 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -90,7 +92,7 @@ func resourceNetwork() *schema.Resource {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DiffSuppressFunc: cidrDiffSuppress,
|
||||
ValidateFunc: cidrValidate,
|
||||
ValidateFunc: utils.CidrValidate,
|
||||
},
|
||||
"network_group": {
|
||||
Description: "The group of the network.",
|
||||
@@ -382,7 +384,7 @@ func resourceNetwork() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceNetworkCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceNetworkGetResourceData(d, meta)
|
||||
if err != nil {
|
||||
@@ -391,10 +393,10 @@ func resourceNetworkCreate(ctx context.Context, d *schema.ResourceData, meta int
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateNetwork(ctx, site, req)
|
||||
resp, err := c.CreateNetwork(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -405,18 +407,18 @@ func resourceNetworkCreate(ctx context.Context, d *schema.ResourceData, meta int
|
||||
}
|
||||
|
||||
func resourceNetworkGetResourceData(d *schema.ResourceData, meta interface{}) (*unifi.Network, error) {
|
||||
// c := meta.(*client)
|
||||
// c := meta.(*provider.Client)
|
||||
|
||||
vlan := d.Get("vlan_id").(int)
|
||||
dhcpDNS, err := listToStringSlice(d.Get("dhcp_dns").([]interface{}))
|
||||
dhcpDNS, err := utils.ListToStringSlice(d.Get("dhcp_dns").([]interface{}))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to convert dhcp_dns to string slice: %w", err)
|
||||
}
|
||||
dhcpV6DNS, err := listToStringSlice(d.Get("dhcp_v6_dns").([]interface{}))
|
||||
dhcpV6DNS, err := utils.ListToStringSlice(d.Get("dhcp_v6_dns").([]interface{}))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to convert dhcp_v6_dns to string slice: %w", err)
|
||||
}
|
||||
wanDNS, err := listToStringSlice(d.Get("wan_dns").([]interface{}))
|
||||
wanDNS, err := utils.ListToStringSlice(d.Get("wan_dns").([]interface{}))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to convert wan_dns to string slice: %w", err)
|
||||
}
|
||||
@@ -425,7 +427,7 @@ func resourceNetworkGetResourceData(d *schema.ResourceData, meta interface{}) (*
|
||||
Name: d.Get("name").(string),
|
||||
Purpose: d.Get("purpose").(string),
|
||||
VLAN: vlan,
|
||||
IPSubnet: cidrOneBased(d.Get("subnet").(string)),
|
||||
IPSubnet: utils.CidrOneBased(d.Get("subnet").(string)),
|
||||
NetworkGroup: d.Get("network_group").(string),
|
||||
DHCPDStart: d.Get("dhcp_start").(string),
|
||||
DHCPDStop: d.Get("dhcp_stop").(string),
|
||||
@@ -571,7 +573,7 @@ func resourceNetworkSetResourceData(resp *unifi.Network, d *schema.ResourceData,
|
||||
d.Set("name", resp.Name)
|
||||
d.Set("purpose", resp.Purpose)
|
||||
d.Set("vlan_id", vlan)
|
||||
d.Set("subnet", cidrZeroBased(resp.IPSubnet))
|
||||
d.Set("subnet", utils.CidrZeroBased(resp.IPSubnet))
|
||||
d.Set("network_group", resp.NetworkGroup)
|
||||
|
||||
d.Set("dhcp_dns", dhcpDNS)
|
||||
@@ -624,16 +626,16 @@ func resourceNetworkSetResourceData(resp *unifi.Network, d *schema.ResourceData,
|
||||
}
|
||||
|
||||
func resourceNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetNetwork(ctx, site, id)
|
||||
resp, err := c.GetNetwork(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -646,7 +648,7 @@ func resourceNetworkRead(ctx context.Context, d *schema.ResourceData, meta inter
|
||||
}
|
||||
|
||||
func resourceNetworkUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceNetworkGetResourceData(d, meta)
|
||||
if err != nil {
|
||||
@@ -656,11 +658,11 @@ func resourceNetworkUpdate(ctx context.Context, d *schema.ResourceData, meta int
|
||||
req.ID = d.Id()
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateNetwork(ctx, site, req)
|
||||
resp, err := c.UpdateNetwork(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -669,15 +671,15 @@ func resourceNetworkUpdate(ctx context.Context, d *schema.ResourceData, meta int
|
||||
}
|
||||
|
||||
func resourceNetworkDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
id := d.Id()
|
||||
|
||||
err := c.c.DeleteNetwork(ctx, site, id)
|
||||
err := c.DeleteNetwork(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil
|
||||
}
|
||||
@@ -685,11 +687,11 @@ func resourceNetworkDelete(ctx context.Context, d *schema.ResourceData, meta int
|
||||
}
|
||||
|
||||
func importNetwork(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
id := d.Id()
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
if strings.Contains(id, ":") {
|
||||
@@ -701,7 +703,7 @@ func importNetwork(ctx context.Context, d *schema.ResourceData, meta interface{}
|
||||
if strings.HasPrefix(id, "name=") {
|
||||
targetName := strings.TrimPrefix(id, "name=")
|
||||
var err error
|
||||
if id, err = getNetworkIDByName(ctx, c.c, targetName, site); err != nil {
|
||||
if id, err = getNetworkIDByName(ctx, c.Client, targetName, site); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"net"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -412,7 +413,7 @@ func TestAccNetwork_mdns(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
preCheck(t)
|
||||
preCheckMinVersion(t, controllerV7)
|
||||
preCheckMinVersion(t, provider.ControllerV7)
|
||||
},
|
||||
ProviderFactories: providerFactories,
|
||||
// TODO: CheckDestroy: ,
|
||||
@@ -1,8 +1,10 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -94,7 +96,7 @@ func resourcePortForward() *schema.Resource {
|
||||
ValidateFunc: validation.Any(
|
||||
validation.StringInSlice([]string{"any"}, false),
|
||||
validation.IsIPv4Address,
|
||||
cidrValidate,
|
||||
utils.CidrValidate,
|
||||
),
|
||||
},
|
||||
},
|
||||
@@ -102,7 +104,7 @@ func resourcePortForward() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourcePortForwardCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourcePortForwardGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -111,9 +113,9 @@ func resourcePortForwardCreate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
resp, err := c.c.CreatePortForward(ctx, site, req)
|
||||
resp, err := c.CreatePortForward(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -153,15 +155,15 @@ func resourcePortForwardSetResourceData(resp *unifi.PortForward, d *schema.Resou
|
||||
}
|
||||
|
||||
func resourcePortForwardRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
resp, err := c.c.GetPortForward(ctx, site, id)
|
||||
resp, err := c.GetPortForward(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -174,7 +176,7 @@ func resourcePortForwardRead(ctx context.Context, d *schema.ResourceData, meta i
|
||||
}
|
||||
|
||||
func resourcePortForwardUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourcePortForwardGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -185,11 +187,11 @@ func resourcePortForwardUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdatePortForward(ctx, site, req)
|
||||
resp, err := c.UpdatePortForward(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -198,15 +200,15 @@ func resourcePortForwardUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourcePortForwardDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
err := c.c.DeletePortForward(ctx, site, id)
|
||||
err := c.DeletePortForward(ctx, site, id)
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,8 +1,10 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -256,7 +258,7 @@ func resourcePortProfile() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourcePortProfileCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourcePortProfileGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -265,9 +267,9 @@ func resourcePortProfileCreate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
resp, err := c.c.CreatePortProfile(ctx, site, req)
|
||||
resp, err := c.CreatePortProfile(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -278,12 +280,12 @@ func resourcePortProfileCreate(ctx context.Context, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourcePortProfileGetResourceData(d *schema.ResourceData) (*unifi.PortProfile, error) {
|
||||
portSecurityMacAddress, err := setToStringSlice(d.Get("port_security_mac_address").(*schema.Set))
|
||||
portSecurityMacAddress, err := utils.SetToStringSlice(d.Get("port_security_mac_address").(*schema.Set))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
excludedNetworkIDs, err := setToStringSlice(d.Get("excluded_network_ids").(*schema.Set))
|
||||
excludedNetworkIDs, err := utils.SetToStringSlice(d.Get("excluded_network_ids").(*schema.Set))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -334,7 +336,7 @@ func resourcePortProfileSetResourceData(resp *unifi.PortProfile, d *schema.Resou
|
||||
d.Set("dot1x_idle_timeout", resp.Dot1XIDleTimeout)
|
||||
d.Set("egress_rate_limit_kbps", resp.EgressRateLimitKbps)
|
||||
d.Set("egress_rate_limit_kbps_enabled", resp.EgressRateLimitKbpsEnabled)
|
||||
d.Set("excluded_network_ids", stringSliceToSet(resp.ExcludedNetworkIDs))
|
||||
d.Set("excluded_network_ids", utils.StringSliceToSet(resp.ExcludedNetworkIDs))
|
||||
d.Set("forward", resp.Forward)
|
||||
d.Set("full_duplex", resp.FullDuplex)
|
||||
d.Set("isolation", resp.Isolation)
|
||||
@@ -345,7 +347,7 @@ func resourcePortProfileSetResourceData(resp *unifi.PortProfile, d *schema.Resou
|
||||
d.Set("op_mode", resp.OpMode)
|
||||
d.Set("poe_mode", resp.PoeMode)
|
||||
d.Set("port_security_enabled", resp.PortSecurityEnabled)
|
||||
d.Set("port_security_mac_address", stringSliceToSet(resp.PortSecurityMACAddress))
|
||||
d.Set("port_security_mac_address", utils.StringSliceToSet(resp.PortSecurityMACAddress))
|
||||
d.Set("priority_queue1_level", resp.PriorityQueue1Level)
|
||||
d.Set("priority_queue2_level", resp.PriorityQueue2Level)
|
||||
d.Set("priority_queue3_level", resp.PriorityQueue3Level)
|
||||
@@ -369,15 +371,15 @@ func resourcePortProfileSetResourceData(resp *unifi.PortProfile, d *schema.Resou
|
||||
}
|
||||
|
||||
func resourcePortProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
resp, err := c.c.GetPortProfile(ctx, site, id)
|
||||
resp, err := c.GetPortProfile(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -390,7 +392,7 @@ func resourcePortProfileRead(ctx context.Context, d *schema.ResourceData, meta i
|
||||
}
|
||||
|
||||
func resourcePortProfileUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourcePortProfileGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -401,11 +403,11 @@ func resourcePortProfileUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdatePortProfile(ctx, site, req)
|
||||
resp, err := c.UpdatePortProfile(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -414,15 +416,15 @@ func resourcePortProfileUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourcePortProfileDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
err := c.c.DeletePortProfile(ctx, site, id)
|
||||
err := c.DeletePortProfile(ctx, site, id)
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,9 +1,10 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"strings"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
@@ -234,7 +235,7 @@ func fromAcctServer(sshKey unifi.RADIUSProfileAcctServers) (map[string]interface
|
||||
}
|
||||
|
||||
func resourceRadiusProfileCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
req, err := resourceRadiusProfileGetResourceData(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
@@ -242,9 +243,9 @@ func resourceRadiusProfileCreate(ctx context.Context, d *schema.ResourceData, me
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
resp, err := c.c.CreateRADIUSProfile(ctx, site, req)
|
||||
resp, err := c.CreateRADIUSProfile(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -302,15 +303,15 @@ func resourceRadiusProfileSetResourceData(resp *unifi.RADIUSProfile, d *schema.R
|
||||
}
|
||||
|
||||
func resourceRadiusProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
resp, err := c.c.GetRADIUSProfile(ctx, site, id)
|
||||
resp, err := c.GetRADIUSProfile(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -323,7 +324,7 @@ func resourceRadiusProfileRead(ctx context.Context, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourceRadiusProfileUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceRadiusProfileGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -334,11 +335,11 @@ func resourceRadiusProfileUpdate(ctx context.Context, d *schema.ResourceData, me
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateRADIUSProfile(ctx, site, req)
|
||||
resp, err := c.UpdateRADIUSProfile(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -347,25 +348,25 @@ func resourceRadiusProfileUpdate(ctx context.Context, d *schema.ResourceData, me
|
||||
}
|
||||
|
||||
func resourceRadiusProfileDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
err := c.c.DeleteRADIUSProfile(ctx, site, id)
|
||||
err := c.DeleteRADIUSProfile(ctx, site, id)
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
func importRadiusProfile(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
id := d.Id()
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
if strings.Contains(id, ":") {
|
||||
@@ -377,7 +378,7 @@ func importRadiusProfile(ctx context.Context, d *schema.ResourceData, meta inter
|
||||
if strings.HasPrefix(id, "name=") {
|
||||
targetName := strings.TrimPrefix(id, "name=")
|
||||
var err error
|
||||
if id, err = getRadiusProfileIDByName(ctx, c.c, targetName, site); err != nil {
|
||||
if id, err = getRadiusProfileIDByName(ctx, c.Client, targetName, site); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,9 +1,10 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -141,7 +142,7 @@ func resourceSettingMgmtGetResourceData(d *schema.ResourceData, meta interface{}
|
||||
}
|
||||
|
||||
func resourceSettingMgmtCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceSettingMgmtGetResourceData(d, meta)
|
||||
if err != nil {
|
||||
@@ -150,10 +151,10 @@ func resourceSettingMgmtCreate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.UpdateSettingMgmt(ctx, site, req)
|
||||
resp, err := c.UpdateSettingMgmt(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -177,14 +178,14 @@ func resourceSettingMgmtSetResourceData(resp *unifi.SettingMgmt, d *schema.Resou
|
||||
}
|
||||
|
||||
func resourceSettingMgmtRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetSettingMgmt(ctx, site)
|
||||
resp, err := c.GetSettingMgmt(ctx, site)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -197,7 +198,7 @@ func resourceSettingMgmtRead(ctx context.Context, d *schema.ResourceData, meta i
|
||||
}
|
||||
|
||||
func resourceSettingMgmtUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceSettingMgmtGetResourceData(d, meta)
|
||||
if err != nil {
|
||||
@@ -207,10 +208,10 @@ func resourceSettingMgmtUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
req.ID = d.Id()
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.UpdateSettingMgmt(ctx, site, req)
|
||||
resp, err := c.UpdateSettingMgmt(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"sync"
|
||||
@@ -1,8 +1,9 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -98,7 +99,7 @@ func resourceSettingRadiusGetResourceData(d *schema.ResourceData, meta interface
|
||||
}
|
||||
|
||||
func resourceSettingRadiusCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceSettingRadiusGetResourceData(d, meta)
|
||||
if err != nil {
|
||||
@@ -107,10 +108,10 @@ func resourceSettingRadiusCreate(ctx context.Context, d *schema.ResourceData, me
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.UpdateSettingRadius(ctx, site, req)
|
||||
resp, err := c.UpdateSettingRadius(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -133,14 +134,14 @@ func resourceSettingRadiusSetResourceData(resp *unifi.SettingRadius, d *schema.R
|
||||
}
|
||||
|
||||
func resourceSettingRadiusRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetSettingRadius(ctx, site)
|
||||
resp, err := c.GetSettingRadius(ctx, site)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -153,7 +154,7 @@ func resourceSettingRadiusRead(ctx context.Context, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourceSettingRadiusUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceSettingRadiusGetResourceData(d, meta)
|
||||
if err != nil {
|
||||
@@ -163,10 +164,10 @@ func resourceSettingRadiusUpdate(ctx context.Context, d *schema.ResourceData, me
|
||||
req.ID = d.Id()
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.UpdateSettingRadius(ctx, site, req)
|
||||
resp, err := c.UpdateSettingRadius(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"sync"
|
||||
@@ -1,9 +1,11 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
"sync"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
@@ -73,18 +75,18 @@ func resourceSettingUsg() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceSettingUsgUpdateResourceData(d *schema.ResourceData, meta interface{}, setting *unifi.SettingUsg) error {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
//nolint // GetOkExists is deprecated, but using here:
|
||||
if mdns, hasMdns := d.GetOkExists("multicast_dns_enabled"); hasMdns {
|
||||
if c.IsControllerV7() {
|
||||
return fmt.Errorf("multicast_dns_enabled is not supported on controller version %v", c.version)
|
||||
return fmt.Errorf("multicast_dns_enabled is not supported on controller version %v", c.Version)
|
||||
}
|
||||
|
||||
setting.MdnsEnabled = mdns.(bool)
|
||||
}
|
||||
|
||||
dhcpRelay, err := listToStringSlice(d.Get("dhcp_relay_servers").([]interface{}))
|
||||
dhcpRelay, err := utils.ListToStringSlice(d.Get("dhcp_relay_servers").([]interface{}))
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to convert dhcp_relay_servers to string slice: %w", err)
|
||||
}
|
||||
@@ -98,14 +100,14 @@ func resourceSettingUsgUpdateResourceData(d *schema.ResourceData, meta interface
|
||||
}
|
||||
|
||||
func resourceSettingUsgUpsert(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
req, err := c.c.GetSettingUsg(ctx, c.site)
|
||||
req, err := c.GetSettingUsg(ctx, c.Site)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -115,7 +117,7 @@ func resourceSettingUsgUpsert(ctx context.Context, d *schema.ResourceData, meta
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
resp, err := c.c.UpdateSettingUsg(ctx, site, req)
|
||||
resp, err := c.UpdateSettingUsg(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -147,14 +149,14 @@ func resourceSettingUsgSetResourceData(resp *unifi.SettingUsg, d *schema.Resourc
|
||||
}
|
||||
|
||||
func resourceSettingUsgRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetSettingUsg(ctx, site)
|
||||
resp, err := c.GetSettingUsg(ctx, site)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,9 +1,10 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -43,10 +44,10 @@ func resourceSite() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceSiteImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
_, err := c.c.GetSite(ctx, id)
|
||||
_, err := c.GetSite(ctx, id)
|
||||
if err != nil {
|
||||
if !errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil, err
|
||||
@@ -57,7 +58,7 @@ func resourceSiteImport(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
}
|
||||
|
||||
// lookup site by name
|
||||
sites, err := c.c.ListSites(ctx)
|
||||
sites, err := c.ListSites(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -73,11 +74,11 @@ func resourceSiteImport(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
}
|
||||
|
||||
func resourceSiteCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
description := d.Get("description").(string)
|
||||
|
||||
resp, err := c.c.CreateSite(ctx, description)
|
||||
resp, err := c.CreateSite(ctx, description)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -95,11 +96,11 @@ func resourceSiteSetResourceData(resp *unifi.Site, d *schema.ResourceData) diag.
|
||||
}
|
||||
|
||||
func resourceSiteRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site, err := c.c.GetSite(ctx, id)
|
||||
site, err := c.GetSite(ctx, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -112,7 +113,7 @@ func resourceSiteRead(ctx context.Context, d *schema.ResourceData, meta interfac
|
||||
}
|
||||
|
||||
func resourceSiteUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := &unifi.Site{
|
||||
ID: d.Id(),
|
||||
@@ -120,7 +121,7 @@ func resourceSiteUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
Description: d.Get("description").(string),
|
||||
}
|
||||
|
||||
resp, err := c.c.UpdateSite(ctx, site.Name, site.Description)
|
||||
resp, err := c.UpdateSite(ctx, site.Name, site.Description)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -129,8 +130,8 @@ func resourceSiteUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
}
|
||||
|
||||
func resourceSiteDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
id := d.Id()
|
||||
_, err := c.c.DeleteSite(ctx, id)
|
||||
_, err := c.DeleteSite(ctx, id)
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,9 +1,11 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -46,7 +48,7 @@ func resourceStaticRoute() *schema.Resource {
|
||||
Description: "The network subnet address.",
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: cidrValidate,
|
||||
ValidateFunc: utils.CidrValidate,
|
||||
DiffSuppressFunc: cidrDiffSuppress,
|
||||
},
|
||||
"type": {
|
||||
@@ -77,7 +79,7 @@ func resourceStaticRoute() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceStaticRouteGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -86,10 +88,10 @@ func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateRouting(ctx, site, req)
|
||||
resp, err := c.CreateRouting(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -107,7 +109,7 @@ func resourceStaticRouteGetResourceData(d *schema.ResourceData) (*unifi.Routing,
|
||||
Type: "static-route",
|
||||
|
||||
Name: d.Get("name").(string),
|
||||
StaticRouteNetwork: cidrZeroBased(d.Get("network").(string)),
|
||||
StaticRouteNetwork: utils.CidrZeroBased(d.Get("network").(string)),
|
||||
StaticRouteDistance: d.Get("distance").(int),
|
||||
StaticRouteType: t,
|
||||
}
|
||||
@@ -128,7 +130,7 @@ func resourceStaticRouteGetResourceData(d *schema.ResourceData) (*unifi.Routing,
|
||||
func resourceStaticRouteSetResourceData(resp *unifi.Routing, d *schema.ResourceData, site string) diag.Diagnostics {
|
||||
d.Set("site", site)
|
||||
d.Set("name", resp.Name)
|
||||
d.Set("network", cidrZeroBased(resp.StaticRouteNetwork))
|
||||
d.Set("network", utils.CidrZeroBased(resp.StaticRouteNetwork))
|
||||
d.Set("distance", resp.StaticRouteDistance)
|
||||
|
||||
t := resp.StaticRouteType
|
||||
@@ -152,16 +154,16 @@ func resourceStaticRouteSetResourceData(resp *unifi.Routing, d *schema.ResourceD
|
||||
}
|
||||
|
||||
func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetRouting(ctx, site, id)
|
||||
resp, err := c.GetRouting(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -174,7 +176,7 @@ func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, meta i
|
||||
}
|
||||
|
||||
func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceStaticRouteGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -185,11 +187,11 @@ func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateRouting(ctx, site, req)
|
||||
resp, err := c.UpdateRouting(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -198,15 +200,15 @@ func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
err := c.c.DeleteRouting(ctx, site, id)
|
||||
err := c.DeleteRouting(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,9 +1,10 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
@@ -118,7 +119,7 @@ func resourceUser() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceUserGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -129,18 +130,18 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateUser(ctx, site, req)
|
||||
resp, err := c.CreateUser(ctx, site, req)
|
||||
if err != nil {
|
||||
if !IsServerErrorContains(err, "api.err.MacUsed") || !allowExisting {
|
||||
if !provider.IsServerErrorContains(err, "api.err.MacUsed") || !allowExisting {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
// mac in use, just absorb it
|
||||
mac := d.Get("mac").(string)
|
||||
existing, err := c.c.GetUserByMAC(ctx, site, mac)
|
||||
existing, err := c.GetUserByMAC(ctx, site, mac)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -148,7 +149,7 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
req.ID = existing.ID
|
||||
req.SiteID = existing.SiteID
|
||||
|
||||
resp, err = c.c.UpdateUser(ctx, site, req)
|
||||
resp, err = c.UpdateUser(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -157,7 +158,7 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
d.SetId(resp.ID)
|
||||
|
||||
if d.Get("blocked").(bool) {
|
||||
err := c.c.BlockUserByMAC(ctx, site, d.Get("mac").(string))
|
||||
err := c.BlockUserByMAC(ctx, site, d.Get("mac").(string))
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -167,7 +168,7 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
mac := d.Get("mac").(string)
|
||||
device := d.Get("dev_id_override").(int)
|
||||
|
||||
err := c.c.OverrideUserFingerprint(context.TODO(), site, mac, device)
|
||||
err := c.OverrideUserFingerprint(context.TODO(), site, mac, device)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -226,16 +227,16 @@ func resourceUserSetResourceData(resp *unifi.User, d *schema.ResourceData, site
|
||||
}
|
||||
|
||||
func resourceUserRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetUser(ctx, site, id)
|
||||
resp, err := c.GetUser(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -245,7 +246,7 @@ func resourceUserRead(ctx context.Context, d *schema.ResourceData, meta interfac
|
||||
}
|
||||
|
||||
// for some reason the IP address is only on this endpoint, so issue another request
|
||||
macResp, err := c.c.GetUserByMAC(ctx, site, resp.MAC)
|
||||
macResp, err := c.GetUserByMAC(ctx, site, resp.MAC)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -262,22 +263,22 @@ func resourceUserRead(ctx context.Context, d *schema.ResourceData, meta interfac
|
||||
}
|
||||
|
||||
func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
if d.HasChange("blocked") {
|
||||
mac := d.Get("mac").(string)
|
||||
if d.Get("blocked").(bool) {
|
||||
err := c.c.BlockUserByMAC(ctx, site, mac)
|
||||
err := c.BlockUserByMAC(ctx, site, mac)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
} else {
|
||||
err := c.c.UnblockUserByMAC(ctx, site, mac)
|
||||
err := c.UnblockUserByMAC(ctx, site, mac)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -288,7 +289,7 @@ func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
mac := d.Get("mac").(string)
|
||||
device := d.Get("dev_id_override").(int)
|
||||
|
||||
err := c.c.OverrideUserFingerprint(context.TODO(), site, mac, device)
|
||||
err := c.OverrideUserFingerprint(context.TODO(), site, mac, device)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -306,7 +307,7 @@ func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
req.ID = d.Id()
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateUser(ctx, site, req)
|
||||
resp, err := c.UpdateUser(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -315,7 +316,7 @@ func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
}
|
||||
|
||||
func resourceUserDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
@@ -325,11 +326,11 @@ func resourceUserDelete(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
// lookup MAC instead of trusting state
|
||||
u, err := c.c.GetUser(ctx, site, id)
|
||||
u, err := c.GetUser(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil
|
||||
}
|
||||
@@ -337,6 +338,6 @@ func resourceUserDelete(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
err = c.c.DeleteUserByMAC(ctx, site, u.MAC)
|
||||
err = c.DeleteUserByMAC(ctx, site, u.MAC)
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -59,7 +60,7 @@ func resourceUserGroup() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceUserGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceUserGroupGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -68,10 +69,10 @@ func resourceUserGroupCreate(ctx context.Context, d *schema.ResourceData, meta i
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateUserGroup(context.TODO(), site, req)
|
||||
resp, err := c.CreateUserGroup(context.TODO(), site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -98,16 +99,16 @@ func resourceUserGroupSetResourceData(resp *unifi.UserGroup, d *schema.ResourceD
|
||||
}
|
||||
|
||||
func resourceUserGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetUserGroup(context.TODO(), site, id)
|
||||
resp, err := c.GetUserGroup(context.TODO(), site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -120,7 +121,7 @@ func resourceUserGroupRead(ctx context.Context, d *schema.ResourceData, meta int
|
||||
}
|
||||
|
||||
func resourceUserGroupUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceUserGroupGetResourceData(d)
|
||||
if err != nil {
|
||||
@@ -131,11 +132,11 @@ func resourceUserGroupUpdate(ctx context.Context, d *schema.ResourceData, meta i
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateUserGroup(context.TODO(), site, req)
|
||||
resp, err := c.UpdateUserGroup(context.TODO(), site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -144,15 +145,15 @@ func resourceUserGroupUpdate(ctx context.Context, d *schema.ResourceData, meta i
|
||||
}
|
||||
|
||||
func resourceUserGroupDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
err := c.c.DeleteUserGroup(context.TODO(), site, id)
|
||||
err := c.DeleteUserGroup(context.TODO(), site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,9 +1,11 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
|
||||
"github.com/filipowm/go-unifi/unifi"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
@@ -203,7 +205,7 @@ func resourceWLAN() *schema.Resource {
|
||||
"minimum_data_rate_2g_kbps": {
|
||||
Description: "Set minimum data rate control for 2G devices, in Kbps. " +
|
||||
"Use `0` to disable minimum data rates. " +
|
||||
"Valid values are: " + markdownValueListInt(wlanValidMinimumDataRate2g) + ".",
|
||||
"Valid values are: " + utils.MarkdownValueListInt(wlanValidMinimumDataRate2g) + ".",
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
// TODO: this validation is from the UI, if other values work, perhaps remove this is set it to a range instead?
|
||||
@@ -212,7 +214,7 @@ func resourceWLAN() *schema.Resource {
|
||||
"minimum_data_rate_5g_kbps": {
|
||||
Description: "Set minimum data rate control for 5G devices, in Kbps. " +
|
||||
"Use `0` to disable minimum data rates. " +
|
||||
"Valid values are: " + markdownValueListInt(wlanValidMinimumDataRate5g) + ".",
|
||||
"Valid values are: " + utils.MarkdownValueListInt(wlanValidMinimumDataRate5g) + ".",
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
// TODO: this validation is from the UI, if other values work, perhaps remove this is set it to a range instead?
|
||||
@@ -243,7 +245,7 @@ func resourceWLAN() *schema.Resource {
|
||||
}
|
||||
|
||||
func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*unifi.WLAN, error) {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
security := d.Get("security").(string)
|
||||
passphrase := d.Get("passphrase").(string)
|
||||
@@ -265,7 +267,7 @@ func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*uni
|
||||
}
|
||||
if !c.SupportsWPA3() {
|
||||
if wpa3 || wpa3Transition {
|
||||
return nil, fmt.Errorf("WPA 3 support is not available on controller version %q, you must be on %q or higher", c.version, controllerVersionWPA3)
|
||||
return nil, fmt.Errorf("WPA 3 support is not available on controller version %q, you must be on %q or higher", c.Version, provider.ControllerVersionWPA3)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +278,7 @@ func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*uni
|
||||
}
|
||||
|
||||
macFilterEnabled := d.Get("mac_filter_enabled").(bool)
|
||||
macFilterList, err := setToStringSlice(d.Get("mac_filter_list").(*schema.Set))
|
||||
macFilterList, err := utils.SetToStringSlice(d.Get("mac_filter_list").(*schema.Set))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -286,7 +288,7 @@ func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*uni
|
||||
|
||||
// version specific fields and validation
|
||||
networkID := d.Get("network_id").(string)
|
||||
apGroupIDs, err := setToStringSlice(d.Get("ap_group_ids").(*schema.Set))
|
||||
apGroupIDs, err := utils.SetToStringSlice(d.Get("ap_group_ids").(*schema.Set))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -353,7 +355,7 @@ func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*uni
|
||||
}
|
||||
|
||||
func resourceWLANCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceWLANGetResourceData(d, meta)
|
||||
if err != nil {
|
||||
@@ -362,10 +364,10 @@ func resourceWLANCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.CreateWLAN(ctx, site, req)
|
||||
resp, err := c.CreateWLAN(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -376,7 +378,7 @@ func resourceWLANCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
}
|
||||
|
||||
func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData, meta interface{}, site string) diag.Diagnostics {
|
||||
// c := meta.(*client)
|
||||
// c := meta.(*provider.Client)
|
||||
security := resp.Security
|
||||
passphrase := resp.XPassphrase
|
||||
wpa3 := false
|
||||
@@ -393,11 +395,11 @@ func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData, meta
|
||||
var macFilterList *schema.Set
|
||||
macFilterPolicy := "deny"
|
||||
if macFilterEnabled {
|
||||
macFilterList = stringSliceToSet(resp.MACFilterList)
|
||||
macFilterList = utils.StringSliceToSet(resp.MACFilterList)
|
||||
macFilterPolicy = resp.MACFilterPolicy
|
||||
}
|
||||
|
||||
apGroupIDs := stringSliceToSet(resp.ApGroupIDs)
|
||||
apGroupIDs := utils.StringSliceToSet(resp.ApGroupIDs)
|
||||
|
||||
schedule := listFromSchedules(resp.ScheduleWithDuration)
|
||||
|
||||
@@ -441,15 +443,15 @@ func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData, meta
|
||||
}
|
||||
|
||||
func resourceWLANRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
resp, err := c.c.GetWLAN(ctx, site, id)
|
||||
resp, err := c.GetWLAN(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
d.SetId("")
|
||||
return nil
|
||||
@@ -462,7 +464,7 @@ func resourceWLANRead(ctx context.Context, d *schema.ResourceData, meta interfac
|
||||
}
|
||||
|
||||
func resourceWLANUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
req, err := resourceWLANGetResourceData(d, meta)
|
||||
if err != nil {
|
||||
@@ -472,11 +474,11 @@ func resourceWLANUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
req.ID = d.Id()
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
req.SiteID = site
|
||||
|
||||
resp, err := c.c.UpdateWLAN(ctx, site, req)
|
||||
resp, err := c.UpdateWLAN(ctx, site, req)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
@@ -485,15 +487,15 @@ func resourceWLANUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
||||
}
|
||||
|
||||
func resourceWLANDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
c := meta.(*client)
|
||||
c := meta.(*provider.Client)
|
||||
|
||||
id := d.Id()
|
||||
site := d.Get("site").(string)
|
||||
if site == "" {
|
||||
site = c.site
|
||||
site = c.Site
|
||||
}
|
||||
|
||||
err := c.c.DeleteWLAN(ctx, site, id)
|
||||
err := c.DeleteWLAN(ctx, site, id)
|
||||
if errors.Is(err, unifi.ErrNotFound) {
|
||||
return nil
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package provider
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
@@ -331,7 +332,7 @@ func TestAccWLAN_wpa3(t *testing.T) {
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
preCheck(t)
|
||||
preCheckMinVersion(t, controllerVersionWPA3)
|
||||
preCheckMinVersion(t, provider.ControllerVersionWPA3)
|
||||
},
|
||||
ProviderFactories: providerFactories,
|
||||
CheckDestroy: func(*terraform.State) error {
|
||||
172
internal/provider/v2/provider.go
Normal file
172
internal/provider/v2/provider.go
Normal file
@@ -0,0 +1,172 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
up "github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider"
|
||||
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
)
|
||||
|
||||
func New(version string) func() provider.Provider {
|
||||
return func() provider.Provider {
|
||||
return &unifiProvider{
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type unifiProvider struct {
|
||||
version string
|
||||
}
|
||||
|
||||
type unifiProviderModel struct {
|
||||
Username types.String `tfsdk:"username"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
APIKey types.String `tfsdk:"api_key"`
|
||||
APIUrl types.String `tfsdk:"api_url"`
|
||||
Site types.String `tfsdk:"site"`
|
||||
Insecure types.Bool `tfsdk:"allow_insecure"`
|
||||
}
|
||||
|
||||
func (p *unifiProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
||||
resp.TypeName = "unifi"
|
||||
resp.Version = p.version
|
||||
}
|
||||
|
||||
func (p *unifiProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"username": schema.StringAttribute{
|
||||
MarkdownDescription: up.ProviderUsernameDescription,
|
||||
Optional: true,
|
||||
},
|
||||
"password": schema.StringAttribute{
|
||||
MarkdownDescription: up.ProviderPasswordDescription,
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
"api_key": schema.StringAttribute{
|
||||
MarkdownDescription: up.ProviderAPIKeyDescription,
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
"api_url": schema.StringAttribute{
|
||||
MarkdownDescription: up.ProviderAPIURLDescription,
|
||||
Validators: []validator.String{
|
||||
stringvalidator.LengthAtLeast(1), // workaround for `required: true`, because it fails on doc generation due to incorrectly detected difference between v1 and v2
|
||||
},
|
||||
Optional: true,
|
||||
},
|
||||
"site": schema.StringAttribute{
|
||||
MarkdownDescription: up.ProviderSiteDescription,
|
||||
Optional: true,
|
||||
},
|
||||
"allow_insecure": schema.BoolAttribute{
|
||||
MarkdownDescription: up.ProviderAllowInsecureDescription,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *unifiProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
||||
tflog.Info(ctx, "Configuring Unifi provider...")
|
||||
// Retrieve provider data from the configuration
|
||||
var cfg unifiProviderModel
|
||||
diags := req.Config.Get(ctx, &cfg)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// If practitioner provided a configuration value for any of the
|
||||
// attributes, it must be a known value.
|
||||
|
||||
if cfg.APIUrl.IsUnknown() {
|
||||
resp.Diagnostics.AddAttributeError(
|
||||
path.Root("api_url"),
|
||||
"Unknown UniFi Controller API URL",
|
||||
"The provider cannot create the UniFi Controller API client as there is an unknown configuration value "+
|
||||
"for the API endpoint. Either target apply the source of the value first, set the value statically in "+
|
||||
"the configuration, or use the UNIFI_API_URL environment variable.",
|
||||
)
|
||||
}
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
// Default values to environment variables, but override
|
||||
// with Terraform configuration value if set.
|
||||
|
||||
// Check environment variables
|
||||
username := utils.GetAnyStringEnv("UNIFI_USERNAME")
|
||||
password := utils.GetAnyStringEnv("UNIFI_PASSWORD")
|
||||
apiKey := utils.GetAnyStringEnv("UNIFI_API_KEY")
|
||||
apiUrl := utils.GetAnyStringEnv("UNIFI_API_URL")
|
||||
site := utils.GetAnyStringEnv("UNIFI_SITE")
|
||||
insecure := utils.GetAnyBoolEnv("UNIFI_INSECURE")
|
||||
|
||||
if !cfg.Username.IsNull() {
|
||||
username = cfg.Username.ValueString()
|
||||
}
|
||||
if !cfg.Password.IsNull() {
|
||||
password = cfg.Password.ValueString()
|
||||
}
|
||||
if !cfg.APIKey.IsNull() {
|
||||
apiKey = cfg.APIKey.ValueString()
|
||||
}
|
||||
if !cfg.APIUrl.IsNull() {
|
||||
apiUrl = cfg.APIUrl.ValueString()
|
||||
}
|
||||
if !cfg.Site.IsNull() {
|
||||
site = cfg.Site.ValueString()
|
||||
}
|
||||
if !cfg.Insecure.IsNull() {
|
||||
insecure = cfg.Insecure.ValueBool()
|
||||
}
|
||||
if apiKey != "" && (username != "" || password != "") {
|
||||
resp.Diagnostics.AddAttributeError(path.Root("api_key"), "Two authentication methods configured", "Only one of `username`/`password` or `api_key` can be set")
|
||||
} else if apiKey == "" && (username == "" || password == "") {
|
||||
resp.Diagnostics.AddAttributeError(path.Root("api_key"), "Missing UniFi API credentials", "Either `username`/`password` or `api_key` must be set")
|
||||
}
|
||||
if apiUrl == "" {
|
||||
resp.Diagnostics.AddAttributeError(path.Root("api_url"), "Missing UniFi API URL", "The `api_url` attribute must be set")
|
||||
}
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
if site == "" {
|
||||
site = "default" // set default site if not provided
|
||||
}
|
||||
c, err := up.NewClient(&up.ClientConfig{
|
||||
Username: username,
|
||||
Password: password,
|
||||
ApiKey: apiKey,
|
||||
Url: apiUrl,
|
||||
Site: site,
|
||||
Insecure: insecure,
|
||||
})
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Failed to create UniFi client", err.Error())
|
||||
return
|
||||
}
|
||||
resp.ResourceData = c
|
||||
resp.DataSourceData = c
|
||||
}
|
||||
|
||||
func (p *unifiProvider) Resources(_ context.Context) []func() resource.Resource {
|
||||
return []func() resource.Resource{}
|
||||
}
|
||||
|
||||
func (p *unifiProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||||
return []func() datasource.DataSource{}
|
||||
}
|
||||
40
internal/utils/cidr.go
Normal file
40
internal/utils/cidr.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
func CidrValidate(raw interface{}, key string) ([]string, []error) {
|
||||
v, ok := raw.(string)
|
||||
if !ok {
|
||||
return nil, []error{fmt.Errorf("expected string, got %T", raw)}
|
||||
}
|
||||
|
||||
_, _, err := net.ParseCIDR(v)
|
||||
if err != nil {
|
||||
return nil, []error{err}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func CidrZeroBased(cidr string) string {
|
||||
_, cidrNet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return cidrNet.String()
|
||||
}
|
||||
|
||||
func CidrOneBased(cidr string) string {
|
||||
_, cidrNet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
cidrNet.IP[3]++
|
||||
|
||||
return cidrNet.String()
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -18,7 +18,7 @@ func TestCIDRValidate(t *testing.T) {
|
||||
{"", "192.1.2.1/20"},
|
||||
} {
|
||||
t.Run(c.cidr, func(t *testing.T) {
|
||||
_, actualErrs := cidrValidate(c.cidr, "key")
|
||||
_, actualErrs := CidrValidate(c.cidr, "key")
|
||||
switch len(actualErrs) {
|
||||
case 0:
|
||||
if c.expectedError != "" {
|
||||
50
internal/utils/env.go
Normal file
50
internal/utils/env.go
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// GetAnyStringEnv returns the first non-empty string value from the environment variables.
|
||||
func GetAnyStringEnv(ks ...string) string {
|
||||
for _, k := range ks {
|
||||
if v := os.Getenv(k); v != "" {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetAnyBoolEnv returns the first non-empty boolean value from the environment variables.
|
||||
func GetAnyBoolEnv(ks ...string) bool {
|
||||
val := ""
|
||||
|
||||
for _, k := range ks {
|
||||
if v := os.Getenv(k); v != "" {
|
||||
val = v
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return val == "true" || val == "1"
|
||||
}
|
||||
|
||||
// GetAnyIntEnv returns the first non-empty integer value from the environment variables.
|
||||
func GetAnyIntEnv(ks ...string) int {
|
||||
for _, k := range ks {
|
||||
if v := os.Getenv(k); v != "" {
|
||||
if i, err := strconv.Atoi(v); err == nil {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package provider
|
||||
package utils
|
||||
|
||||
import "strconv"
|
||||
|
||||
func markdownValueListInt(values []int) string {
|
||||
func MarkdownValueListInt(values []int) string {
|
||||
switch {
|
||||
case len(values) == 0:
|
||||
return ""
|
||||
@@ -1,4 +1,4 @@
|
||||
package provider
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
func listToStringSlice(src []interface{}) ([]string, error) {
|
||||
func ListToStringSlice(src []interface{}) ([]string, error) {
|
||||
dst := make([]string, 0, len(src))
|
||||
for _, s := range src {
|
||||
d, ok := s.(string)
|
||||
@@ -18,11 +18,11 @@ func listToStringSlice(src []interface{}) ([]string, error) {
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func setToStringSlice(src *schema.Set) ([]string, error) {
|
||||
return listToStringSlice(src.List())
|
||||
func SetToStringSlice(src *schema.Set) ([]string, error) {
|
||||
return ListToStringSlice(src.List())
|
||||
}
|
||||
|
||||
func stringSliceToList(list []string) []interface{} {
|
||||
func StringSliceToList(list []string) []interface{} {
|
||||
vs := make([]interface{}, 0, len(list))
|
||||
for _, v := range list {
|
||||
vs = append(vs, v)
|
||||
@@ -30,6 +30,6 @@ func stringSliceToList(list []string) []interface{} {
|
||||
return vs
|
||||
}
|
||||
|
||||
func stringSliceToSet(src []string) *schema.Set {
|
||||
return schema.NewSet(schema.HashString, stringSliceToList(src))
|
||||
func StringSliceToSet(src []string) *schema.Set {
|
||||
return schema.NewSet(schema.HashString, StringSliceToList(src))
|
||||
}
|
||||
63
main.go
63
main.go
@@ -1,16 +1,20 @@
|
||||
package main // import "github.com/filipowm/terraform-provider-unifi"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
|
||||
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||
v1 "github.com/filipowm/terraform-provider-unifi/internal/provider/v1"
|
||||
v2 "github.com/filipowm/terraform-provider-unifi/internal/provider/v2"
|
||||
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
|
||||
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
|
||||
"github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server"
|
||||
"github.com/hashicorp/terraform-plugin-mux/tf5to6server"
|
||||
"github.com/hashicorp/terraform-plugin-mux/tf6muxserver"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Generate docs for website
|
||||
//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
|
||||
|
||||
var (
|
||||
// these will be set by the goreleaser configuration
|
||||
// to appropriate values for the compiled binary
|
||||
@@ -21,17 +25,50 @@ var (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
var debugMode bool
|
||||
|
||||
flag.BoolVar(&debugMode, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
||||
flag.Parse()
|
||||
|
||||
opts := &plugin.ServeOpts{ProviderFunc: provider.New(version)}
|
||||
|
||||
if debugMode {
|
||||
opts.Debug = true
|
||||
opts.ProviderAddr = "registry.terraform.io/filipowm/unifi"
|
||||
p := v1.New(version)
|
||||
upgradedSdkServer, err := tf5to6server.UpgradeServer(
|
||||
ctx,
|
||||
func() tfprotov5.ProviderServer {
|
||||
return schema.NewGRPCProviderServer(p())
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
plugin.Serve(opts)
|
||||
providers := []func() tfprotov6.ProviderServer{
|
||||
providerserver.NewProtocol6(v2.New(version)()),
|
||||
func() tfprotov6.ProviderServer {
|
||||
return upgradedSdkServer
|
||||
},
|
||||
}
|
||||
|
||||
muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var serveOpts []tf6server.ServeOpt
|
||||
if debugMode {
|
||||
serveOpts = append(serveOpts, tf6server.WithManagedDebug())
|
||||
}
|
||||
|
||||
// Remove any date and time prefix in log package function output to
|
||||
// prevent duplicate timestamp and incorrect log level setting
|
||||
log.SetFlags(log.Flags() &^ (log.Ldate | log.Ltime))
|
||||
|
||||
err = tf6server.Serve(
|
||||
"registry.terraform.io/filipowm/unifi",
|
||||
muxServer.ProviderServer,
|
||||
serveOpts...,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
layout: ""
|
||||
page_title: "Provider: Unifi"
|
||||
page_title: "Provider: UniFi"
|
||||
description: |-
|
||||
The Unifi provider provides resources to interact with a Unifi controller API.
|
||||
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.
|
||||
The Unifi provider provides resources to interact with a UniFi Controller API.
|
||||
|
||||
It is not recommended to use your own account for management of your controller. A user specific to
|
||||
Terraform is recommended. You can create a **Limited Admin** with **Local Access Only** and
|
||||
|
||||
@@ -7,3 +7,6 @@ import (
|
||||
_ "github.com/golangci/golangci-lint/cmd/golangci-lint"
|
||||
_ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs"
|
||||
)
|
||||
|
||||
// Generate documentation.
|
||||
//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs generate --provider-dir ../ --rendered-website-dir ./docs --provider-name "terraform-provider-unifi" --rendered-provider-name "terraform-provider-unifi" //nolint:lll
|
||||
|
||||
Reference in New Issue
Block a user