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)
|
||||||
|
|
||||||
`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.
|
- `password` (String, Sensitive) The password of the account.
|
||||||
- `tunnel_medium_type` (Number) See RFC2868 section 3.2
|
- `tunnel_medium_type` (Number) See RFC2868 section 3.2
|
||||||
- `tunnel_type` (Number) See RFC2868 section 3.1
|
- `tunnel_type` (Number) See RFC2868 section 3.1
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,5 +28,3 @@ data "unifi_ap_group" "default" {
|
|||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of this AP group.
|
- `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_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.
|
- `wan_username` (String) Specifies the IPV4 WAN username.
|
||||||
- `x_wan_password` (String) Specifies the IPV4 WAN password.
|
- `x_wan_password` (String) Specifies the IPV4 WAN password.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,5 +28,3 @@ data "unifi_port_profile" "all" {
|
|||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of this port profile.
|
- `id` (String) The ID of this port profile.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,5 +23,3 @@ description: |-
|
|||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of this AP group.
|
- `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.
|
- `network_id` (String) The network ID for this user.
|
||||||
- `note` (String) A note with additional information for the user.
|
- `note` (String) A note with additional information for the user.
|
||||||
- `user_group_id` (String) The user group ID 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.
|
- `id` (String) The ID of this AP group.
|
||||||
- `qos_rate_max_down` (Number)
|
- `qos_rate_max_down` (Number)
|
||||||
- `qos_rate_max_up` (Number)
|
- `qos_rate_max_up` (Number)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,15 +13,13 @@ 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
|
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.
|
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
|
## Example Usage
|
||||||
|
|
||||||
```terraform
|
```terraform
|
||||||
provider "unifi" {
|
provider "unifi" {
|
||||||
api_key = var.api_key # optionally use UNIFI_API_KEY env var
|
|
||||||
username = var.username # optionally use UNIFI_USERNAME env var
|
username = var.username # optionally use UNIFI_USERNAME env var
|
||||||
password = var.password # optionally use UNIFI_PASSWORD env var
|
password = var.password # optionally use UNIFI_PASSWORD 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
|
api_url = var.api_url # optionally use UNIFI_API env var
|
||||||
|
|
||||||
# you may need to allow insecure TLS communications unless you have configured
|
# you may need to allow insecure TLS communications unless you have configured
|
||||||
@@ -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 generated by tfplugindocs -->
|
||||||
## Schema
|
## Schema
|
||||||
|
|
||||||
### Optional
|
### 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.
|
- `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.
|
- `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`
|
- `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.
|
- `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
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of the account.
|
- `id` (String) The ID of the account.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,5 @@ Optional:
|
|||||||
- `aggregate_num_ports` (Number) Number of ports in the aggregate.
|
- `aggregate_num_ports` (Number) Number of ports in the aggregate.
|
||||||
- `name` (String) Human-readable name of the port.
|
- `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`.
|
- `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.
|
- `port_profile_id` (String) ID of the Port Profile used on this port.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,5 +43,3 @@ resource "unifi_dynamic_dns" "test" {
|
|||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of the dynamic DNS.
|
- `id` (String) The ID of the dynamic DNS.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,5 +41,3 @@ resource "unifi_firewall_group" "can_print" {
|
|||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of the firewall group.
|
- `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_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.
|
- `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.
|
- `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.
|
- `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`.
|
- `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_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_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.
|
- `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'.
|
- `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).
|
- `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_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.
|
- `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.
|
- `subnet` (String) The subnet of the network. Must be a valid CIDR address.
|
||||||
- `vlan_id` (Number) The VLAN ID of the network.
|
- `vlan_id` (Number) The VLAN ID of the network.
|
||||||
|
|||||||
@@ -31,5 +31,3 @@ description: |-
|
|||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of the port forwarding rule.
|
- `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`.
|
- `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` (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`.
|
- `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`.
|
- `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`.
|
- `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`.
|
- `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_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.
|
- `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.
|
- `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_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_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.
|
- `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_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.
|
- `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`.
|
- `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.
|
- `voice_networkconf_id` (String) The ID of network to use as the voice network on the port profile.
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of the port profile.
|
- `id` (String) The ID of the port profile.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -60,5 +60,3 @@ Required:
|
|||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
- `port` (Number) Port of authentication service. Defaults to `1812`.
|
- `port` (Number) Port of authentication service. Defaults to `1812`.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,5 +49,3 @@ Optional:
|
|||||||
|
|
||||||
- `comment` (String) Comment.
|
- `comment` (String) Comment.
|
||||||
- `key` (String) Public SSH key.
|
- `key` (String) Public SSH key.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,5 +29,3 @@ description: |-
|
|||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of the settings.
|
- `id` (String) The ID of the settings.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,14 +18,9 @@ description: |-
|
|||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
- `dhcp_relay_servers` (List of String) The DHCP relay servers.
|
- `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.
|
- `multicast_dns_enabled` (Boolean) Whether multicast DNS is enabled.
|
||||||
- `site` (String) The name of the site to associate the settings with.
|
- `site` (String) The name of the site to associate the settings with.
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of the settings.
|
- `id` (String) The ID of the settings.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -56,5 +56,3 @@ resource "unifi_static_route" "interface" {
|
|||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
- `id` (String) The ID of the static route.
|
- `id` (String) The ID of the static route.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,5 +52,3 @@ resource "unifi_user" "test" {
|
|||||||
- `hostname` (String) The hostname of the user.
|
- `hostname` (String) The hostname of the user.
|
||||||
- `id` (String) The ID of the user.
|
- `id` (String) The ID of the user.
|
||||||
- `ip` (String) The IP address of the user.
|
- `ip` (String) The IP address of the user.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ resource "unifi_wlan" "wifi" {
|
|||||||
|
|
||||||
### Required
|
### 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`.
|
- `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.
|
- `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/logutils v1.0.0 // indirect
|
||||||
github.com/hashicorp/terraform-exec v0.22.0 // indirect
|
github.com/hashicorp/terraform-exec v0.22.0 // indirect
|
||||||
github.com/hashicorp/terraform-json v0.24.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-go v0.26.0 // indirect
|
||||||
github.com/hashicorp/terraform-plugin-log v0.9.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-registry-address v0.2.4 // indirect
|
||||||
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
|
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
|
||||||
github.com/hashicorp/yamux v0.1.2 // 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-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 h1:Fq7E/HrU8kuZu3hNliZGwloFWSYfWEOWnylFhYQIoys=
|
||||||
github.com/hashicorp/terraform-plugin-docs v0.20.1/go.mod h1:Yz6HoK7/EgzSrHPB9J/lWFzwl9/xep2OPnc5jaJDV90=
|
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 h1:cuIzCv4qwigug3OS7iKhpGAbZTiypAfFQmw8aE65O2M=
|
||||||
github.com/hashicorp/terraform-plugin-go v0.26.0/go.mod h1:+CXjuLDiFgqR+GcrM5a2E2Kal5t5q2jb0E3D57tTdNY=
|
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 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
|
||||||
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
|
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 h1:WNMsTLkZf/3ydlgsuXePa3jvZFwAJhruxTxP/c1Viuw=
|
||||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.1/go.mod h1:P6o64QS97plG44iFzSM6rAn6VJIC/Sy9a9IkEtl79K4=
|
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=
|
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 (
|
var (
|
||||||
controllerV6 = asVersion("6.0.0")
|
ControllerV6 = asVersion("6.0.0")
|
||||||
controllerV7 = asVersion("7.0.0")
|
ControllerV7 = asVersion("7.0.0")
|
||||||
controllerVersionApiKeyAuth = asVersion("9.0.108")
|
ControllerVersionApiKeyAuth = asVersion("9.0.108")
|
||||||
|
|
||||||
// https://community.ui.com/releases/UniFi-Network-Controller-6-1-61/62f1ad38-1ac5-430c-94b0-becbb8f71d7d
|
// 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 {
|
func (c *Client) IsControllerV6() bool {
|
||||||
return c.version.GreaterThanOrEqual(controllerV6)
|
return c.Version.GreaterThanOrEqual(ControllerV6)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) IsControllerV7() bool {
|
func (c *Client) IsControllerV7() bool {
|
||||||
return c.version.GreaterThanOrEqual(controllerV7)
|
return c.Version.GreaterThanOrEqual(ControllerV7)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) SupportsApiKeyAuthentication() bool {
|
func (c *Client) SupportsApiKeyAuthentication() bool {
|
||||||
return c.version.GreaterThanOrEqual(controllerVersionApiKeyAuth)
|
return c.Version.GreaterThanOrEqual(ControllerVersionApiKeyAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) SupportsWPA3() bool {
|
func (c *Client) SupportsWPA3() bool {
|
||||||
return c.version.GreaterThanOrEqual(controllerVersionWPA3)
|
return c.Version.GreaterThanOrEqual(ControllerVersionWPA3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkMinimumControllerVersion(versionString string) error {
|
func CheckMinimumControllerVersion(versionString string) error {
|
||||||
v, err := version.NewVersion(versionString)
|
v, err := version.NewVersion(versionString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if v.LessThan(controllerV6) {
|
if v.LessThan(ControllerV6) {
|
||||||
return fmt.Errorf("Controller version %q or greater is required to use the provider, found %q.", controllerV6, v)
|
return fmt.Errorf("Controller version %q or greater is required to use the provider, found %q.", ControllerV6, v)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,216 +1,13 @@
|
|||||||
package provider
|
package provider
|
||||||
|
|
||||||
import (
|
const (
|
||||||
"context"
|
ProviderUsernameDescription = "Local user name for the Unifi controller API. Can be specified with the `UNIFI_USERNAME` environment variable."
|
||||||
"crypto/tls"
|
ProviderPasswordDescription = "Password for the user accessing the API. Can be specified with the `UNIFI_PASSWORD` environment variable."
|
||||||
"errors"
|
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."
|
||||||
"fmt"
|
ProviderAPIURLDescription = "URL of the controller API. Can be specified with the `UNIFI_API` environment variable. " +
|
||||||
"github.com/hashicorp/go-version"
|
"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."
|
||||||
"log"
|
ProviderSiteDescription = "The site in the Unifi controller this provider will manage. Can be specified with the `UNIFI_SITE` environment variable. Default: `default`"
|
||||||
"net"
|
ProviderAllowInsecureDescription = "Skip verification of TLS certificates of API requests. You may need to set this to `true` " +
|
||||||
"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"
|
|
||||||
)
|
|
||||||
|
|
||||||
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 " +
|
"if you are using your local API without setting up a signed certificate. Can be specified with the " +
|
||||||
"`UNIFI_INSECURE` environment variable.",
|
"`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 (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
@@ -9,7 +10,7 @@ import (
|
|||||||
|
|
||||||
func dataAccount() *schema.Resource {
|
func dataAccount() *schema.Resource {
|
||||||
return &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,
|
ReadContext: dataAccountRead,
|
||||||
|
|
||||||
@@ -57,15 +58,15 @@ func dataAccount() *schema.Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dataAccountRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func dataAccountRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
name := d.Get("name").(string)
|
name := d.Get("name").(string)
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
accounts, err := c.c.ListAccount(ctx, site)
|
accounts, err := c.ListAccount(ctx, site)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
@@ -35,15 +36,15 @@ func dataAPGroup() *schema.Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dataAPGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func dataAPGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
name := d.Get("name").(string)
|
name := d.Get("name").(string)
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
groups, err := c.c.ListAPGroup(ctx, site)
|
groups, err := c.ListAPGroup(ctx, site)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"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/diag"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"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 {
|
func dataNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
name := d.Get("name").(string)
|
name := d.Get("name").(string)
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
id := d.Get("id").(string)
|
id := d.Get("id").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
if (name == "" && id == "") || (name != "" && id != "") {
|
if (name == "" && id == "") || (name != "" && id != "") {
|
||||||
return diag.Errorf("One of 'name' OR 'id' is required")
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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("name", n.Name)
|
||||||
d.Set("purpose", n.Purpose)
|
d.Set("purpose", n.Purpose)
|
||||||
d.Set("vlan_id", n.VLAN)
|
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("network_group", n.NetworkGroup)
|
||||||
d.Set("dhcp_dns", dhcpDNS)
|
d.Set("dhcp_dns", dhcpDNS)
|
||||||
d.Set("dhcp_start", n.DHCPDStart)
|
d.Set("dhcp_start", n.DHCPDStart)
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/go-version"
|
"github.com/hashicorp/go-version"
|
||||||
@@ -14,7 +15,7 @@ func TestAccDataNetwork_byName(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error parsing version: %s", err)
|
t.Fatalf("error parsing version: %s", err)
|
||||||
}
|
}
|
||||||
if v.LessThan(controllerV7) {
|
if v.LessThan(provider.ControllerV7) {
|
||||||
defaultName = "LAN"
|
defaultName = "LAN"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ func TestAccDataNetwork_byID(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error parsing version: %s", err)
|
t.Fatalf("error parsing version: %s", err)
|
||||||
}
|
}
|
||||||
if v.LessThan(controllerV7) {
|
if v.LessThan(provider.ControllerV7) {
|
||||||
defaultName = "LAN"
|
defaultName = "LAN"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
@@ -36,15 +37,15 @@ func dataPortProfile() *schema.Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dataPortProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func dataPortProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
name := d.Get("name").(string)
|
name := d.Get("name").(string)
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
groups, err := c.c.ListPortProfile(ctx, site)
|
groups, err := c.ListPortProfile(ctx, site)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
@@ -36,15 +37,15 @@ func dataRADIUSProfile() *schema.Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dataRADIUSProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func dataRADIUSProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
name := d.Get("name").(string)
|
name := d.Get("name").(string)
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
profiles, err := c.c.ListRADIUSProfile(ctx, site)
|
profiles, err := c.ListRADIUSProfile(ctx, site)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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 {
|
func dataUserRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
mac := d.Get("mac").(string)
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.c.GetUser(ctx, site, macResp.ID)
|
resp, err := c.GetUser(ctx, site, macResp.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
@@ -45,15 +46,15 @@ func dataUserGroup() *schema.Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dataUserGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func dataUserGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
name := d.Get("name").(string)
|
name := d.Get("name").(string)
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
groups, err := c.c.ListUserGroup(ctx, site)
|
groups, err := c.ListUserGroup(ctx, site)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
mapset "github.com/deckarep/golang-set/v2"
|
mapset "github.com/deckarep/golang-set/v2"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -38,7 +38,7 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runAcceptanceTests(m *testing.M) int {
|
func runAcceptanceTests(m *testing.M) int {
|
||||||
dc, err := compose.NewDockerCompose("../../docker-compose.yaml")
|
dc, err := compose.NewDockerCompose("../../../docker-compose.yaml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"github.com/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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 {
|
func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceAccountGetResourceData(d)
|
req, err := resourceAccountGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -83,10 +84,10 @@ func resourceAccountCreate(ctx context.Context, d *schema.ResourceData, meta int
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := resourceAccountGetResourceData(d)
|
req, err := resourceAccountGetResourceData(d)
|
||||||
@@ -112,7 +113,7 @@ func resourceAccountUpdate(ctx context.Context, d *schema.ResourceData, meta int
|
|||||||
req.ID = d.Id()
|
req.ID = d.Id()
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateAccount(ctx, site, req)
|
resp, err := c.UpdateAccount(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceAccountDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
//name := d.Get("name").(string)
|
//name := d.Get("name").(string)
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
err := c.c.DeleteAccount(ctx, site, id)
|
err := c.DeleteAccount(ctx, site, id)
|
||||||
if errors.Is(err, unifi.ErrNotFound) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil
|
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 {
|
func resourceAccountRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
return nil
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -138,11 +139,11 @@ func resourceDevice() *schema.Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resourceDeviceImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
func resourceDeviceImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
if colons := strings.Count(id, ":"); colons == 1 || colons == 6 {
|
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) {
|
if macAddressRegexp.MatchString(id) {
|
||||||
// look up id by mac
|
// look up id by mac
|
||||||
mac := cleanMAC(id)
|
mac := cleanMAC(id)
|
||||||
device, err := c.c.GetDeviceByMAC(ctx, site, mac)
|
device, err := c.GetDeviceByMAC(ctx, site, mac)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
func resourceDeviceCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
mac := d.Get("mac").(string)
|
mac := d.Get("mac").(string)
|
||||||
@@ -187,7 +188,7 @@ func resourceDeviceCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
|||||||
}
|
}
|
||||||
|
|
||||||
mac = cleanMAC(mac)
|
mac = cleanMAC(mac)
|
||||||
device, err := c.c.GetDeviceByMAC(ctx, site, mac)
|
device, err := c.GetDeviceByMAC(ctx, site, mac)
|
||||||
|
|
||||||
if device == nil {
|
if device == nil {
|
||||||
return diag.Errorf("device not found using mac %q", mac)
|
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")
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := resourceDeviceGetResourceData(d)
|
req, err := resourceDeviceGetResourceData(d)
|
||||||
@@ -232,7 +233,7 @@ func resourceDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta inte
|
|||||||
req.ID = d.Id()
|
req.ID = d.Id()
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateDevice(ctx, site, req)
|
resp, err := c.UpdateDevice(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
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) {
|
if !d.Get("forget_on_destroy").(bool) {
|
||||||
return nil
|
return nil
|
||||||
@@ -256,10 +257,10 @@ func resourceDeviceDelete(ctx context.Context, d *schema.ResourceData, meta inte
|
|||||||
mac := d.Get("mac").(string)
|
mac := d.Get("mac").(string)
|
||||||
|
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
err := c.c.ForgetDevice(ctx, site, mac)
|
err := c.ForgetDevice(ctx, site, mac)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceDeviceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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) {
|
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)
|
site := d.Get("site").(string)
|
||||||
mac := d.Get("mac").(string)
|
mac := d.Get("mac").(string)
|
||||||
|
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always consider unknown to be a pending state.
|
// Always consider unknown to be a pending state.
|
||||||
@@ -409,7 +410,7 @@ func waitForDeviceState(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
Pending: pending,
|
Pending: pending,
|
||||||
Target: []string{targetState.String()},
|
Target: []string{targetState.String()},
|
||||||
Refresh: func() (interface{}, string, error) {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
err = nil
|
err = nil
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"github.com/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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 {
|
func resourceDynamicDNSCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceDynamicDNSGetResourceData(d)
|
req, err := resourceDynamicDNSGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -84,10 +85,10 @@ func resourceDynamicDNSCreate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceDynamicDNSRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceDynamicDNSUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceDynamicDNSGetResourceData(d)
|
req, err := resourceDynamicDNSGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -159,11 +160,11 @@ func resourceDynamicDNSUpdate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateDynamicDNS(ctx, site, req)
|
resp, err := c.UpdateDynamicDNS(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceDynamicDNSDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"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/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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 {
|
func resourceFirewallGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceFirewallGroupGetResourceData(d)
|
req, err := resourceFirewallGroupGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -66,12 +68,12 @@ func resourceFirewallGroupCreate(ctx context.Context, d *schema.ResourceData, me
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 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.Errorf("firewall groups must have unique names: %s", err)
|
||||||
}
|
}
|
||||||
return diag.FromErr(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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -99,22 +101,22 @@ func resourceFirewallGroupSetResourceData(resp *unifi.FirewallGroup, d *schema.R
|
|||||||
d.Set("site", site)
|
d.Set("site", site)
|
||||||
d.Set("name", resp.Name)
|
d.Set("name", resp.Name)
|
||||||
d.Set("type", resp.GroupType)
|
d.Set("type", resp.GroupType)
|
||||||
d.Set("members", stringSliceToSet(resp.GroupMembers))
|
d.Set("members", utils.StringSliceToSet(resp.GroupMembers))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceFirewallGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func resourceFirewallGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceFirewallGroupUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceFirewallGroupGetResourceData(d)
|
req, err := resourceFirewallGroupGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -138,11 +140,11 @@ func resourceFirewallGroupUpdate(ctx context.Context, d *schema.ResourceData, me
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateFirewallGroup(ctx, site, req)
|
resp, err := c.UpdateFirewallGroup(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceFirewallGroupDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"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 {
|
func resourceFirewallRuleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceFirewallRuleGetResourceData(d)
|
req, err := resourceFirewallRuleGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -219,12 +221,12 @@ func resourceFirewallRuleCreate(ctx context.Context, d *schema.ResourceData, met
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 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)
|
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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -300,7 +302,7 @@ func resourceFirewallRuleSetResourceData(resp *unifi.FirewallRule, d *schema.Res
|
|||||||
d.Set("state_related", resp.StateRelated)
|
d.Set("state_related", resp.StateRelated)
|
||||||
|
|
||||||
d.Set("src_network_type", resp.SrcNetworkType)
|
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_mac", resp.SrcMACAddress)
|
||||||
d.Set("src_address", resp.SrcAddress)
|
d.Set("src_address", resp.SrcAddress)
|
||||||
d.Set("src_address_ipv6", resp.SrcAddressIPV6)
|
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("src_port", resp.SrcPort)
|
||||||
|
|
||||||
d.Set("dst_network_type", resp.DstNetworkType)
|
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", resp.DstAddress)
|
||||||
d.Set("dst_address_ipv6", resp.DstAddressIPV6)
|
d.Set("dst_address_ipv6", resp.DstAddressIPV6)
|
||||||
d.Set("dst_network_id", resp.DstNetworkID)
|
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 {
|
func resourceFirewallRuleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceFirewallRuleUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceFirewallRuleGetResourceData(d)
|
req, err := resourceFirewallRuleGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -351,11 +353,11 @@ func resourceFirewallRuleUpdate(ctx context.Context, d *schema.ResourceData, met
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateFirewallRule(ctx, site, req)
|
resp, err := c.UpdateFirewallRule(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceFirewallRuleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -90,7 +92,7 @@ func resourceNetwork() *schema.Resource {
|
|||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
DiffSuppressFunc: cidrDiffSuppress,
|
DiffSuppressFunc: cidrDiffSuppress,
|
||||||
ValidateFunc: cidrValidate,
|
ValidateFunc: utils.CidrValidate,
|
||||||
},
|
},
|
||||||
"network_group": {
|
"network_group": {
|
||||||
Description: "The group of the network.",
|
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 {
|
func resourceNetworkCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceNetworkGetResourceData(d, meta)
|
req, err := resourceNetworkGetResourceData(d, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -391,10 +393,10 @@ func resourceNetworkCreate(ctx context.Context, d *schema.ResourceData, meta int
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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) {
|
func resourceNetworkGetResourceData(d *schema.ResourceData, meta interface{}) (*unifi.Network, error) {
|
||||||
// c := meta.(*client)
|
// c := meta.(*provider.Client)
|
||||||
|
|
||||||
vlan := d.Get("vlan_id").(int)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to convert dhcp_dns to string slice: %w", err)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to convert dhcp_v6_dns to string slice: %w", err)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to convert wan_dns to string slice: %w", err)
|
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),
|
Name: d.Get("name").(string),
|
||||||
Purpose: d.Get("purpose").(string),
|
Purpose: d.Get("purpose").(string),
|
||||||
VLAN: vlan,
|
VLAN: vlan,
|
||||||
IPSubnet: cidrOneBased(d.Get("subnet").(string)),
|
IPSubnet: utils.CidrOneBased(d.Get("subnet").(string)),
|
||||||
NetworkGroup: d.Get("network_group").(string),
|
NetworkGroup: d.Get("network_group").(string),
|
||||||
DHCPDStart: d.Get("dhcp_start").(string),
|
DHCPDStart: d.Get("dhcp_start").(string),
|
||||||
DHCPDStop: d.Get("dhcp_stop").(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("name", resp.Name)
|
||||||
d.Set("purpose", resp.Purpose)
|
d.Set("purpose", resp.Purpose)
|
||||||
d.Set("vlan_id", vlan)
|
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("network_group", resp.NetworkGroup)
|
||||||
|
|
||||||
d.Set("dhcp_dns", dhcpDNS)
|
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 {
|
func resourceNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceNetworkUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceNetworkGetResourceData(d, meta)
|
req, err := resourceNetworkGetResourceData(d, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -656,11 +658,11 @@ func resourceNetworkUpdate(ctx context.Context, d *schema.ResourceData, meta int
|
|||||||
req.ID = d.Id()
|
req.ID = d.Id()
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateNetwork(ctx, site, req)
|
resp, err := c.UpdateNetwork(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceNetworkDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
err := c.c.DeleteNetwork(ctx, site, id)
|
err := c.DeleteNetwork(ctx, site, id)
|
||||||
if errors.Is(err, unifi.ErrNotFound) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil
|
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) {
|
func importNetwork(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(id, ":") {
|
if strings.Contains(id, ":") {
|
||||||
@@ -701,7 +703,7 @@ func importNetwork(ctx context.Context, d *schema.ResourceData, meta interface{}
|
|||||||
if strings.HasPrefix(id, "name=") {
|
if strings.HasPrefix(id, "name=") {
|
||||||
targetName := strings.TrimPrefix(id, "name=")
|
targetName := strings.TrimPrefix(id, "name=")
|
||||||
var err error
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -412,7 +413,7 @@ func TestAccNetwork_mdns(t *testing.T) {
|
|||||||
resource.ParallelTest(t, resource.TestCase{
|
resource.ParallelTest(t, resource.TestCase{
|
||||||
PreCheck: func() {
|
PreCheck: func() {
|
||||||
preCheck(t)
|
preCheck(t)
|
||||||
preCheckMinVersion(t, controllerV7)
|
preCheckMinVersion(t, provider.ControllerV7)
|
||||||
},
|
},
|
||||||
ProviderFactories: providerFactories,
|
ProviderFactories: providerFactories,
|
||||||
// TODO: CheckDestroy: ,
|
// TODO: CheckDestroy: ,
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"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/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
@@ -94,7 +96,7 @@ func resourcePortForward() *schema.Resource {
|
|||||||
ValidateFunc: validation.Any(
|
ValidateFunc: validation.Any(
|
||||||
validation.StringInSlice([]string{"any"}, false),
|
validation.StringInSlice([]string{"any"}, false),
|
||||||
validation.IsIPv4Address,
|
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 {
|
func resourcePortForwardCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourcePortForwardGetResourceData(d)
|
req, err := resourcePortForwardGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -111,9 +113,9 @@ func resourcePortForwardCreate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourcePortForwardRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourcePortForwardUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourcePortForwardGetResourceData(d)
|
req, err := resourcePortForwardGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -185,11 +187,11 @@ func resourcePortForwardUpdate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdatePortForward(ctx, site, req)
|
resp, err := c.UpdatePortForward(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourcePortForwardDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"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/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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 {
|
func resourcePortProfileCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourcePortProfileGetResourceData(d)
|
req, err := resourcePortProfileGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -265,9 +267,9 @@ func resourcePortProfileCreate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -334,7 +336,7 @@ func resourcePortProfileSetResourceData(resp *unifi.PortProfile, d *schema.Resou
|
|||||||
d.Set("dot1x_idle_timeout", resp.Dot1XIDleTimeout)
|
d.Set("dot1x_idle_timeout", resp.Dot1XIDleTimeout)
|
||||||
d.Set("egress_rate_limit_kbps", resp.EgressRateLimitKbps)
|
d.Set("egress_rate_limit_kbps", resp.EgressRateLimitKbps)
|
||||||
d.Set("egress_rate_limit_kbps_enabled", resp.EgressRateLimitKbpsEnabled)
|
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("forward", resp.Forward)
|
||||||
d.Set("full_duplex", resp.FullDuplex)
|
d.Set("full_duplex", resp.FullDuplex)
|
||||||
d.Set("isolation", resp.Isolation)
|
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("op_mode", resp.OpMode)
|
||||||
d.Set("poe_mode", resp.PoeMode)
|
d.Set("poe_mode", resp.PoeMode)
|
||||||
d.Set("port_security_enabled", resp.PortSecurityEnabled)
|
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_queue1_level", resp.PriorityQueue1Level)
|
||||||
d.Set("priority_queue2_level", resp.PriorityQueue2Level)
|
d.Set("priority_queue2_level", resp.PriorityQueue2Level)
|
||||||
d.Set("priority_queue3_level", resp.PriorityQueue3Level)
|
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 {
|
func resourcePortProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourcePortProfileUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourcePortProfileGetResourceData(d)
|
req, err := resourcePortProfileGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -401,11 +403,11 @@ func resourcePortProfileUpdate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdatePortProfile(ctx, site, req)
|
resp, err := c.UpdatePortProfile(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourcePortProfileDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"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 {
|
func resourceRadiusProfileCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
req, err := resourceRadiusProfileGetResourceData(d)
|
req, err := resourceRadiusProfileGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
@@ -242,9 +243,9 @@ func resourceRadiusProfileCreate(ctx context.Context, d *schema.ResourceData, me
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceRadiusProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceRadiusProfileUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceRadiusProfileGetResourceData(d)
|
req, err := resourceRadiusProfileGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -334,11 +335,11 @@ func resourceRadiusProfileUpdate(ctx context.Context, d *schema.ResourceData, me
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateRADIUSProfile(ctx, site, req)
|
resp, err := c.UpdateRADIUSProfile(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceRadiusProfileDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func importRadiusProfile(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
func importRadiusProfile(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(id, ":") {
|
if strings.Contains(id, ":") {
|
||||||
@@ -377,7 +378,7 @@ func importRadiusProfile(ctx context.Context, d *schema.ResourceData, meta inter
|
|||||||
if strings.HasPrefix(id, "name=") {
|
if strings.HasPrefix(id, "name=") {
|
||||||
targetName := strings.TrimPrefix(id, "name=")
|
targetName := strings.TrimPrefix(id, "name=")
|
||||||
var err error
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"github.com/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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 {
|
func resourceSettingMgmtCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceSettingMgmtGetResourceData(d, meta)
|
req, err := resourceSettingMgmtGetResourceData(d, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -150,10 +151,10 @@ func resourceSettingMgmtCreate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceSettingMgmtRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceSettingMgmtUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceSettingMgmtGetResourceData(d, meta)
|
req, err := resourceSettingMgmtGetResourceData(d, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -207,10 +208,10 @@ func resourceSettingMgmtUpdate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
req.ID = d.Id()
|
req.ID = d.Id()
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"github.com/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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 {
|
func resourceSettingRadiusCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceSettingRadiusGetResourceData(d, meta)
|
req, err := resourceSettingRadiusGetResourceData(d, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -107,10 +108,10 @@ func resourceSettingRadiusCreate(ctx context.Context, d *schema.ResourceData, me
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceSettingRadiusRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceSettingRadiusUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceSettingRadiusGetResourceData(d, meta)
|
req, err := resourceSettingRadiusGetResourceData(d, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -163,10 +164,10 @@ func resourceSettingRadiusUpdate(ctx context.Context, d *schema.ResourceData, me
|
|||||||
req.ID = d.Id()
|
req.ID = d.Id()
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"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 {
|
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:
|
//nolint // GetOkExists is deprecated, but using here:
|
||||||
if mdns, hasMdns := d.GetOkExists("multicast_dns_enabled"); hasMdns {
|
if mdns, hasMdns := d.GetOkExists("multicast_dns_enabled"); hasMdns {
|
||||||
if c.IsControllerV7() {
|
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)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to convert dhcp_relay_servers to string slice: %w", err)
|
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 {
|
func resourceSettingUsgUpsert(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -115,7 +117,7 @@ func resourceSettingUsgUpsert(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.c.UpdateSettingUsg(ctx, site, req)
|
resp, err := c.UpdateSettingUsg(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceSettingUsgRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
return nil
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"github.com/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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) {
|
func resourceSiteImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
_, err := c.c.GetSite(ctx, id)
|
_, err := c.GetSite(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, unifi.ErrNotFound) {
|
if !errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -57,7 +58,7 @@ func resourceSiteImport(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lookup site by name
|
// lookup site by name
|
||||||
sites, err := c.c.ListSites(ctx)
|
sites, err := c.ListSites(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
func resourceSiteCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
description := d.Get("description").(string)
|
description := d.Get("description").(string)
|
||||||
|
|
||||||
resp, err := c.c.CreateSite(ctx, description)
|
resp, err := c.CreateSite(ctx, description)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceSiteRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site, err := c.c.GetSite(ctx, id)
|
site, err := c.GetSite(ctx, id)
|
||||||
if errors.Is(err, unifi.ErrNotFound) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceSiteUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := &unifi.Site{
|
site := &unifi.Site{
|
||||||
ID: d.Id(),
|
ID: d.Id(),
|
||||||
@@ -120,7 +121,7 @@ func resourceSiteUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
Description: d.Get("description").(string),
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceSiteDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
_, err := c.c.DeleteSite(ctx, id)
|
_, err := c.DeleteSite(ctx, id)
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"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/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
@@ -46,7 +48,7 @@ func resourceStaticRoute() *schema.Resource {
|
|||||||
Description: "The network subnet address.",
|
Description: "The network subnet address.",
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ValidateFunc: cidrValidate,
|
ValidateFunc: utils.CidrValidate,
|
||||||
DiffSuppressFunc: cidrDiffSuppress,
|
DiffSuppressFunc: cidrDiffSuppress,
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
@@ -77,7 +79,7 @@ func resourceStaticRoute() *schema.Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceStaticRouteGetResourceData(d)
|
req, err := resourceStaticRouteGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -86,10 +88,10 @@ func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -107,7 +109,7 @@ func resourceStaticRouteGetResourceData(d *schema.ResourceData) (*unifi.Routing,
|
|||||||
Type: "static-route",
|
Type: "static-route",
|
||||||
|
|
||||||
Name: d.Get("name").(string),
|
Name: d.Get("name").(string),
|
||||||
StaticRouteNetwork: cidrZeroBased(d.Get("network").(string)),
|
StaticRouteNetwork: utils.CidrZeroBased(d.Get("network").(string)),
|
||||||
StaticRouteDistance: d.Get("distance").(int),
|
StaticRouteDistance: d.Get("distance").(int),
|
||||||
StaticRouteType: t,
|
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 {
|
func resourceStaticRouteSetResourceData(resp *unifi.Routing, d *schema.ResourceData, site string) diag.Diagnostics {
|
||||||
d.Set("site", site)
|
d.Set("site", site)
|
||||||
d.Set("name", resp.Name)
|
d.Set("name", resp.Name)
|
||||||
d.Set("network", cidrZeroBased(resp.StaticRouteNetwork))
|
d.Set("network", utils.CidrZeroBased(resp.StaticRouteNetwork))
|
||||||
d.Set("distance", resp.StaticRouteDistance)
|
d.Set("distance", resp.StaticRouteDistance)
|
||||||
|
|
||||||
t := resp.StaticRouteType
|
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 {
|
func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceStaticRouteGetResourceData(d)
|
req, err := resourceStaticRouteGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -185,11 +187,11 @@ func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, meta
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateRouting(ctx, site, req)
|
resp, err := c.UpdateRouting(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"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/diag"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
"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 {
|
func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceUserGetResourceData(d)
|
req, err := resourceUserGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -129,18 +130,18 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 err != nil {
|
||||||
if !IsServerErrorContains(err, "api.err.MacUsed") || !allowExisting {
|
if !provider.IsServerErrorContains(err, "api.err.MacUsed") || !allowExisting {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mac in use, just absorb it
|
// mac in use, just absorb it
|
||||||
mac := d.Get("mac").(string)
|
mac := d.Get("mac").(string)
|
||||||
existing, err := c.c.GetUserByMAC(ctx, site, mac)
|
existing, err := c.GetUserByMAC(ctx, site, mac)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -148,7 +149,7 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
req.ID = existing.ID
|
req.ID = existing.ID
|
||||||
req.SiteID = existing.SiteID
|
req.SiteID = existing.SiteID
|
||||||
|
|
||||||
resp, err = c.c.UpdateUser(ctx, site, req)
|
resp, err = c.UpdateUser(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -157,7 +158,7 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
d.SetId(resp.ID)
|
d.SetId(resp.ID)
|
||||||
|
|
||||||
if d.Get("blocked").(bool) {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -167,7 +168,7 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
mac := d.Get("mac").(string)
|
mac := d.Get("mac").(string)
|
||||||
device := d.Get("dev_id_override").(int)
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceUserRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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
|
// 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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.HasChange("blocked") {
|
if d.HasChange("blocked") {
|
||||||
mac := d.Get("mac").(string)
|
mac := d.Get("mac").(string)
|
||||||
if d.Get("blocked").(bool) {
|
if d.Get("blocked").(bool) {
|
||||||
err := c.c.BlockUserByMAC(ctx, site, mac)
|
err := c.BlockUserByMAC(ctx, site, mac)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err := c.c.UnblockUserByMAC(ctx, site, mac)
|
err := c.UnblockUserByMAC(ctx, site, mac)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -288,7 +289,7 @@ func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
mac := d.Get("mac").(string)
|
mac := d.Get("mac").(string)
|
||||||
device := d.Get("dev_id_override").(int)
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -306,7 +307,7 @@ func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
req.ID = d.Id()
|
req.ID = d.Id()
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateUser(ctx, site, req)
|
resp, err := c.UpdateUser(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceUserDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
@@ -325,11 +326,11 @@ func resourceUserDelete(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookup MAC instead of trusting state
|
// 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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -337,6 +338,6 @@ func resourceUserDelete(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.c.DeleteUserByMAC(ctx, site, u.MAC)
|
err = c.DeleteUserByMAC(ctx, site, u.MAC)
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
|
|
||||||
"github.com/filipowm/go-unifi/unifi"
|
"github.com/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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 {
|
func resourceUserGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceUserGroupGetResourceData(d)
|
req, err := resourceUserGroupGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -68,10 +69,10 @@ func resourceUserGroupCreate(ctx context.Context, d *schema.ResourceData, meta i
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceUserGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceUserGroupUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceUserGroupGetResourceData(d)
|
req, err := resourceUserGroupGetResourceData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -131,11 +132,11 @@ func resourceUserGroupUpdate(ctx context.Context, d *schema.ResourceData, meta i
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateUserGroup(context.TODO(), site, req)
|
resp, err := c.UpdateUserGroup(context.TODO(), site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceUserGroupDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"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/filipowm/go-unifi/unifi"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
@@ -203,7 +205,7 @@ func resourceWLAN() *schema.Resource {
|
|||||||
"minimum_data_rate_2g_kbps": {
|
"minimum_data_rate_2g_kbps": {
|
||||||
Description: "Set minimum data rate control for 2G devices, in Kbps. " +
|
Description: "Set minimum data rate control for 2G devices, in Kbps. " +
|
||||||
"Use `0` to disable minimum data rates. " +
|
"Use `0` to disable minimum data rates. " +
|
||||||
"Valid values are: " + markdownValueListInt(wlanValidMinimumDataRate2g) + ".",
|
"Valid values are: " + utils.MarkdownValueListInt(wlanValidMinimumDataRate2g) + ".",
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
// TODO: this validation is from the UI, if other values work, perhaps remove this is set it to a range instead?
|
// 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": {
|
"minimum_data_rate_5g_kbps": {
|
||||||
Description: "Set minimum data rate control for 5G devices, in Kbps. " +
|
Description: "Set minimum data rate control for 5G devices, in Kbps. " +
|
||||||
"Use `0` to disable minimum data rates. " +
|
"Use `0` to disable minimum data rates. " +
|
||||||
"Valid values are: " + markdownValueListInt(wlanValidMinimumDataRate5g) + ".",
|
"Valid values are: " + utils.MarkdownValueListInt(wlanValidMinimumDataRate5g) + ".",
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
// TODO: this validation is from the UI, if other values work, perhaps remove this is set it to a range instead?
|
// 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) {
|
func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*unifi.WLAN, error) {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
security := d.Get("security").(string)
|
security := d.Get("security").(string)
|
||||||
passphrase := d.Get("passphrase").(string)
|
passphrase := d.Get("passphrase").(string)
|
||||||
@@ -265,7 +267,7 @@ func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*uni
|
|||||||
}
|
}
|
||||||
if !c.SupportsWPA3() {
|
if !c.SupportsWPA3() {
|
||||||
if wpa3 || wpa3Transition {
|
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)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -286,7 +288,7 @@ func resourceWLANGetResourceData(d *schema.ResourceData, meta interface{}) (*uni
|
|||||||
|
|
||||||
// version specific fields and validation
|
// version specific fields and validation
|
||||||
networkID := d.Get("network_id").(string)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
func resourceWLANCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceWLANGetResourceData(d, meta)
|
req, err := resourceWLANGetResourceData(d, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -362,10 +364,10 @@ func resourceWLANCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
|
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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 {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData, meta interface{}, site string) diag.Diagnostics {
|
||||||
// c := meta.(*client)
|
// c := meta.(*provider.Client)
|
||||||
security := resp.Security
|
security := resp.Security
|
||||||
passphrase := resp.XPassphrase
|
passphrase := resp.XPassphrase
|
||||||
wpa3 := false
|
wpa3 := false
|
||||||
@@ -393,11 +395,11 @@ func resourceWLANSetResourceData(resp *unifi.WLAN, d *schema.ResourceData, meta
|
|||||||
var macFilterList *schema.Set
|
var macFilterList *schema.Set
|
||||||
macFilterPolicy := "deny"
|
macFilterPolicy := "deny"
|
||||||
if macFilterEnabled {
|
if macFilterEnabled {
|
||||||
macFilterList = stringSliceToSet(resp.MACFilterList)
|
macFilterList = utils.StringSliceToSet(resp.MACFilterList)
|
||||||
macFilterPolicy = resp.MACFilterPolicy
|
macFilterPolicy = resp.MACFilterPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
apGroupIDs := stringSliceToSet(resp.ApGroupIDs)
|
apGroupIDs := utils.StringSliceToSet(resp.ApGroupIDs)
|
||||||
|
|
||||||
schedule := listFromSchedules(resp.ScheduleWithDuration)
|
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 {
|
func resourceWLANRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
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 {
|
func resourceWLANUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
req, err := resourceWLANGetResourceData(d, meta)
|
req, err := resourceWLANGetResourceData(d, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -472,11 +474,11 @@ func resourceWLANUpdate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
req.ID = d.Id()
|
req.ID = d.Id()
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
if site == "" {
|
||||||
site = c.site
|
site = c.Site
|
||||||
}
|
}
|
||||||
req.SiteID = site
|
req.SiteID = site
|
||||||
|
|
||||||
resp, err := c.c.UpdateWLAN(ctx, site, req)
|
resp, err := c.UpdateWLAN(ctx, site, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.FromErr(err)
|
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 {
|
func resourceWLANDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
c := meta.(*client)
|
c := meta.(*provider.Client)
|
||||||
|
|
||||||
id := d.Id()
|
id := d.Id()
|
||||||
site := d.Get("site").(string)
|
site := d.Get("site").(string)
|
||||||
if site == "" {
|
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) {
|
if errors.Is(err, unifi.ErrNotFound) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package provider
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -331,7 +332,7 @@ func TestAccWLAN_wpa3(t *testing.T) {
|
|||||||
resource.ParallelTest(t, resource.TestCase{
|
resource.ParallelTest(t, resource.TestCase{
|
||||||
PreCheck: func() {
|
PreCheck: func() {
|
||||||
preCheck(t)
|
preCheck(t)
|
||||||
preCheckMinVersion(t, controllerVersionWPA3)
|
preCheckMinVersion(t, provider.ControllerVersionWPA3)
|
||||||
},
|
},
|
||||||
ProviderFactories: providerFactories,
|
ProviderFactories: providerFactories,
|
||||||
CheckDestroy: func(*terraform.State) error {
|
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 (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@@ -18,7 +18,7 @@ func TestCIDRValidate(t *testing.T) {
|
|||||||
{"", "192.1.2.1/20"},
|
{"", "192.1.2.1/20"},
|
||||||
} {
|
} {
|
||||||
t.Run(c.cidr, func(t *testing.T) {
|
t.Run(c.cidr, func(t *testing.T) {
|
||||||
_, actualErrs := cidrValidate(c.cidr, "key")
|
_, actualErrs := CidrValidate(c.cidr, "key")
|
||||||
switch len(actualErrs) {
|
switch len(actualErrs) {
|
||||||
case 0:
|
case 0:
|
||||||
if c.expectedError != "" {
|
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"
|
import "strconv"
|
||||||
|
|
||||||
func markdownValueListInt(values []int) string {
|
func MarkdownValueListInt(values []int) string {
|
||||||
switch {
|
switch {
|
||||||
case len(values) == 0:
|
case len(values) == 0:
|
||||||
return ""
|
return ""
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package provider
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"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))
|
dst := make([]string, 0, len(src))
|
||||||
for _, s := range src {
|
for _, s := range src {
|
||||||
d, ok := s.(string)
|
d, ok := s.(string)
|
||||||
@@ -18,11 +18,11 @@ func listToStringSlice(src []interface{}) ([]string, error) {
|
|||||||
return dst, nil
|
return dst, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setToStringSlice(src *schema.Set) ([]string, error) {
|
func SetToStringSlice(src *schema.Set) ([]string, error) {
|
||||||
return listToStringSlice(src.List())
|
return ListToStringSlice(src.List())
|
||||||
}
|
}
|
||||||
|
|
||||||
func stringSliceToList(list []string) []interface{} {
|
func StringSliceToList(list []string) []interface{} {
|
||||||
vs := make([]interface{}, 0, len(list))
|
vs := make([]interface{}, 0, len(list))
|
||||||
for _, v := range list {
|
for _, v := range list {
|
||||||
vs = append(vs, v)
|
vs = append(vs, v)
|
||||||
@@ -30,6 +30,6 @@ func stringSliceToList(list []string) []interface{} {
|
|||||||
return vs
|
return vs
|
||||||
}
|
}
|
||||||
|
|
||||||
func stringSliceToSet(src []string) *schema.Set {
|
func StringSliceToSet(src []string) *schema.Set {
|
||||||
return schema.NewSet(schema.HashString, stringSliceToList(src))
|
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"
|
package main // import "github.com/filipowm/terraform-provider-unifi"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
|
v1 "github.com/filipowm/terraform-provider-unifi/internal/provider/v1"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
|
v2 "github.com/filipowm/terraform-provider-unifi/internal/provider/v2"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||||
"github.com/filipowm/terraform-provider-unifi/internal/provider"
|
"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 (
|
var (
|
||||||
// these will be set by the goreleaser configuration
|
// these will be set by the goreleaser configuration
|
||||||
// to appropriate values for the compiled binary
|
// to appropriate values for the compiled binary
|
||||||
@@ -21,17 +25,50 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
ctx := context.Background()
|
||||||
var debugMode bool
|
var debugMode bool
|
||||||
|
|
||||||
flag.BoolVar(&debugMode, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
flag.BoolVar(&debugMode, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
opts := &plugin.ServeOpts{ProviderFunc: provider.New(version)}
|
p := v1.New(version)
|
||||||
|
upgradedSdkServer, err := tf5to6server.UpgradeServer(
|
||||||
if debugMode {
|
ctx,
|
||||||
opts.Debug = true
|
func() tfprotov5.ProviderServer {
|
||||||
opts.ProviderAddr = "registry.terraform.io/filipowm/unifi"
|
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: ""
|
layout: ""
|
||||||
page_title: "Provider: Unifi"
|
page_title: "Provider: UniFi"
|
||||||
description: |-
|
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
|
# 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
|
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
|
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/golangci/golangci-lint/cmd/golangci-lint"
|
||||||
_ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs"
|
_ "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