diff --git a/docs/data-sources/multicast_rendezvous_point.md b/docs/data-sources/multicast_rendezvous_point.md
new file mode 100644
index 0000000..f4d2cbe
--- /dev/null
+++ b/docs/data-sources/multicast_rendezvous_point.md
@@ -0,0 +1,33 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "meraki_multicast_rendezvous_point Data Source - terraform-provider-meraki"
+subcategory: "Switches"
+description: |-
+ This data source can read the Multicast Rendezvous Point configuration.
+---
+
+# meraki_multicast_rendezvous_point (Data Source)
+
+This data source can read the `Multicast Rendezvous Point` configuration.
+
+## Example Usage
+
+```terraform
+data "meraki_multicast_rendezvous_point" "example" {
+ id = "12345678"
+ network_id = "L_12345"
+}
+```
+
+
+## Schema
+
+### Required
+
+- `id` (String) The id of the object
+- `network_id` (String) Network ID
+
+### Read-Only
+
+- `interface_ip` (String) The IP address of the interface where the RP needs to be created.
+- `multicast_group` (String) `Any`, or the IP address of a multicast group
diff --git a/docs/data-sources/wireless_ssid.md b/docs/data-sources/wireless_ssid.md
new file mode 100644
index 0000000..77b5899
--- /dev/null
+++ b/docs/data-sources/wireless_ssid.md
@@ -0,0 +1,175 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "meraki_wireless_ssid Data Source - terraform-provider-meraki"
+subcategory: "Wireless"
+description: |-
+ This data source can read the Wireless SSID configuration.
+---
+
+# meraki_wireless_ssid (Data Source)
+
+This data source can read the `Wireless SSID` configuration.
+
+## Example Usage
+
+```terraform
+data "meraki_wireless_ssid" "example" {
+ id = "0"
+ network_id = "L_123456"
+ number = "0"
+}
+```
+
+
+## Schema
+
+### Required
+
+- `network_id` (String) Network ID
+- `number` (String) Wireless SSID number
+
+### Optional
+
+- `id` (String) The id of the object
+- `name` (String) The name of the SSID
+- `named_vlans_radius_guest_vlan_name` (String) RADIUS guest VLAN name.
+
+### Read-Only
+
+- `active_directory_credentials_logon_name` (String) The logon name of the Active Directory account.
+- `active_directory_credentials_password` (String) The password to the Active Directory user account.
+- `active_directory_servers` (Attributes List) The Active Directory servers to be used for authentication. (see [below for nested schema](#nestedatt--active_directory_servers))
+- `adult_content_filtering_enabled` (Boolean) Boolean indicating whether or not adult content will be blocked
+- `ap_tags_and_vlan_ids` (Attributes List) The list of tags and VLAN IDs used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming` (see [below for nested schema](#nestedatt--ap_tags_and_vlan_ids))
+- `auth_mode` (String) The association control method for the SSID (`open`, `open-enhanced`, `psk`, `open-with-radius`, `open-with-nac`, `8021x-meraki`, `8021x-nac`, `8021x-radius`, `8021x-google`, `8021x-entra`, `8021x-localradius`, `ipsk-with-radius`, `ipsk-without-radius` or `ipsk-with-nac`)
+- `availability_tags` (List of String) Accepts a list of tags for this SSID. If availableOnAllAps is false, then the SSID will only be broadcast by APs with tags matching any of the tags in this list.
+- `available_on_all_aps` (Boolean) Boolean indicating whether all APs should broadcast the SSID or if it should be restricted to APs matching any availability tags. Can only be false if the SSID has availability tags.
+- `band_selection` (String) The client-serving radio frequencies of this SSID in the default indoor RF profile. (`Dual band operation`, `5 GHz band only` or `Dual band operation with Band Steering`)
+- `concentrator_network_id` (String) The concentrator to use when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`.
+- `default_vlan_id` (Number) The default VLAN ID used for `all other APs`. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`
+- `disassociate_clients_on_vpn_failover` (Boolean) Disassociate clients when `VPN` concentrator failover occurs in order to trigger clients to re-associate and generate new DHCP requests. This param is only valid if ipAssignmentMode is `VPN`.
+- `dns_rewrite_dns_custom_nameservers` (List of String) User specified DNS servers (up to two servers)
+- `dns_rewrite_enabled` (Boolean) Boolean indicating whether or not DNS server rewrite is enabled. If disabled, upstream DNS will be used
+- `dot11r_adaptive` (Boolean) (Optional) Whether 802.11r is adaptive or not.
+- `dot11r_enabled` (Boolean) Whether 802.11r is enabled or not.
+- `dot11w_enabled` (Boolean) Whether 802.11w is enabled or not.
+- `dot11w_required` (Boolean) (Optional) Whether 802.11w is required or not.
+- `enabled` (Boolean) Whether or not the SSID is enabled
+- `encryption_mode` (String) The psk encryption mode for the SSID (`wep` or `wpa`). This param is only valid if the authMode is `psk`
+- `enterprise_admin_access` (String) Whether or not an SSID is accessible by `enterprise` administrators (`access disabled` or `access enabled`)
+- `gre_concentrator_host` (String) The EoGRE concentrator`s IP or FQDN. This param is required when ipAssignmentMode is `Ethernet over GRE`.
+- `gre_key` (Number) Optional numerical identifier that will add the GRE key field to the GRE header. Used to identify an individual traffic flow within a tunnel.
+- `ip_assignment_mode` (String) The client IP assignment mode (`NAT mode`, `Bridge mode`, `Layer 3 roaming`, `Ethernet over GRE`, `Layer 3 roaming with a concentrator` or `VPN`)
+- `lan_isolation_enabled` (Boolean) Boolean indicating whether Layer 2 LAN isolation should be enabled or disabled. Only configurable when ipAssignmentMode is `Bridge mode`.
+- `ldap_base_distinguished_name` (String) The base distinguished name of users on the LDAP server.
+- `ldap_credentials_distinguished_name` (String) The distinguished name of the LDAP user account (example: cn=user,dc=meraki,dc=com).
+- `ldap_credentials_password` (String) The password of the LDAP user account.
+- `ldap_server_ca_certificate_contents` (String) The contents of the CA certificate. Must be in PEM or DER format.
+- `ldap_servers` (Attributes List) The LDAP servers to be used for authentication. (see [below for nested schema](#nestedatt--ldap_servers))
+- `local_radius_cache_timeout` (Number) The duration (in seconds) for which LDAP and OCSP lookups are cached.
+- `local_radius_certificate_authentication_client_root_ca_certificate_contents` (String) The contents of the Client CA Certificate. Must be in PEM or DER format.
+- `local_radius_certificate_authentication_enabled` (Boolean) Whether or not to use EAP-TLS certificate-based authentication to validate wireless clients.
+- `local_radius_certificate_authentication_ocsp_responder_url` (String) (Optional) The URL of the OCSP responder to verify client certificate status.
+- `local_radius_certificate_authentication_use_ldap` (Boolean) Whether or not to verify the certificate with LDAP.
+- `local_radius_certificate_authentication_use_ocsp` (Boolean) Whether or not to verify the certificate with OCSP.
+- `local_radius_password_authentication_enabled` (Boolean) Whether or not to use EAP-TTLS/PAP or PEAP-GTC password-based authentication via LDAP lookup.
+- `mandatory_dhcp_enabled` (Boolean) If true, Mandatory DHCP will enforce that clients connecting to this SSID must use the IP address assigned by the DHCP server. Clients who use a static IP address won`t be able to associate.
+- `min_bitrate` (Number) The minimum bitrate in Mbps of this SSID in the default indoor RF profile. (`1`, `2`, `5.5`, `6`, `9`, `11`, `12`, `18`, `24`, `36`, `48` or `54`)
+- `named_vlans_radius_guest_vlan_enabled` (Boolean) Whether or not RADIUS guest named VLAN is enabled.
+- `named_vlans_tagging_by_ap_tags` (Attributes List) The list of AP tags and VLAN names used for named VLAN tagging. If an AP has a tag matching one in the list, then traffic on this SSID will be directed to use the VLAN name associated to the tag. (see [below for nested schema](#nestedatt--named_vlans_tagging_by_ap_tags))
+- `named_vlans_tagging_default_vlan_name` (String) The default VLAN name used to tag traffic in the absence of a matching AP tag.
+- `named_vlans_tagging_enabled` (Boolean) Whether or not traffic should be directed to use specific VLAN names.
+- `oauth_allowed_domains` (List of String) (Optional) The list of domains allowed access to the network.
+- `per_client_bandwidth_limit_down` (Number) The download bandwidth limit in Kbps. (0 represents no limit.)
+- `per_client_bandwidth_limit_up` (Number) The upload bandwidth limit in Kbps. (0 represents no limit.)
+- `per_ssid_bandwidth_limit_down` (Number) The total download bandwidth limit in Kbps. (0 represents no limit.)
+- `per_ssid_bandwidth_limit_up` (Number) The total upload bandwidth limit in Kbps. (0 represents no limit.)
+- `psk` (String) The passkey for the SSID. This param is only valid if the authMode is `psk`
+- `radius_accounting_enabled` (Boolean) Whether or not RADIUS accounting is enabled. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius`
+- `radius_accounting_interim_interval` (Number) The interval (in seconds) in which accounting information is updated and sent to the RADIUS accounting server.
+- `radius_accounting_servers` (Attributes List) The RADIUS accounting 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius` and radiusAccountingEnabled is `true` (see [below for nested schema](#nestedatt--radius_accounting_servers))
+- `radius_attribute_for_group_policies` (String) Specify the RADIUS attribute used to look up group policies (`Filter-Id`, `Reply-Message`, `Airespace-ACL-Name` or `Aruba-User-Role`). Access points must receive this attribute in the RADIUS Access-Accept message
+- `radius_authentication_nas_id` (String) The template of the NAS identifier to be used for RADIUS authentication (ex. $NODE_MAC$:$VAP_NUM$).
+- `radius_called_station_id` (String) The template of the called station identifier to be used for RADIUS (ex. $NODE_MAC$:$VAP_NUM$).
+- `radius_coa_enabled` (Boolean) If true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server.
+- `radius_failover_policy` (String) This policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable (`Deny access` or `Allow access`)
+- `radius_fallback_enabled` (Boolean) Whether or not higher priority RADIUS servers should be retried after 60 seconds.
+- `radius_guest_vlan_enabled` (Boolean) Whether or not RADIUS Guest VLAN is enabled. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode
+- `radius_guest_vlan_id` (Number) VLAN ID of the RADIUS Guest VLAN. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode
+- `radius_load_balancing_policy` (String) This policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts (`Strict priority order` or `Round robin`)
+- `radius_override` (Boolean) If true, the RADIUS response can override VLAN tag. This is not valid when ipAssignmentMode is `NAT mode`.
+- `radius_proxy_enabled` (Boolean) If true, Meraki devices will proxy RADIUS messages through the Meraki cloud to the configured RADIUS auth and accounting servers.
+- `radius_server_attempts_limit` (Number) The maximum number of transmit attempts after which a RADIUS server is failed over (must be between 1-5).
+- `radius_server_timeout` (Number) The amount of time for which a RADIUS client waits for a reply from the RADIUS server (must be between 1-10 seconds).
+- `radius_servers` (Attributes List) The RADIUS 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius` (see [below for nested schema](#nestedatt--radius_servers))
+- `radius_testing_enabled` (Boolean) If true, Meraki devices will periodically send Access-Request messages to configured RADIUS servers using identity `meraki_8021x_test` to ensure that the RADIUS servers are reachable.
+- `secondary_concentrator_network_id` (String) The secondary concentrator to use when the ipAssignmentMode is `VPN`. If configured, the APs will switch to using this concentrator if the primary concentrator is unreachable. This param is optional. (`disabled` represents no secondary concentrator.)
+- `speed_burst_enabled` (Boolean) Boolean indicating whether or not to allow users to temporarily exceed the bandwidth limit for short periods while still keeping them under the bandwidth limit over time.
+- `splash_guest_sponsor_domains` (List of String) Array of valid sponsor email domains for sponsored guest splash type.
+- `splash_page` (String) The type of splash page for the SSID (`None`, `Click-through splash page`, `Billing`, `Password-protected with Meraki RADIUS`, `Password-protected with custom RADIUS`, `Password-protected with Active Directory`, `Password-protected with LDAP`, `SMS authentication`, `Systems Manager Sentry`, `Facebook Wi-Fi`, `Google OAuth`, `Microsoft Entra ID`, `Sponsored guest`, `Cisco ISE` or `Google Apps domain`). This attribute is not supported for template children.
+- `use_vlan_tagging` (Boolean) Whether or not traffic should be directed to use specific VLANs. This param is only valid if the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`
+- `visible` (Boolean) Boolean indicating whether APs should advertise or hide this SSID. APs will only broadcast this SSID if set to true
+- `vlan_id` (Number) The VLAN ID used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`
+- `walled_garden_enabled` (Boolean) Allow access to a configurable list of IP ranges, which users may access prior to sign-on.
+- `walled_garden_ranges` (List of String) Specify your walled garden by entering an array of addresses, ranges using CIDR notation, domain names, and domain wildcards (e.g. `192.168.1.1/24`, `192.168.37.10/32`, `www.yahoo.com`, `*.google.com`]). Meraki`s splash page is automatically included in your walled garden.
+- `wpa_encryption_mode` (String) The types of WPA encryption. (`WPA1 only`, `WPA1 and WPA2`, `WPA2 only`, `WPA3 Transition Mode`, `WPA3 only` or `WPA3 192-bit Security`)
+
+
+### Nested Schema for `active_directory_servers`
+
+Read-Only:
+
+- `host` (String) IP address (or FQDN) of your Active Directory server.
+- `port` (Number) (Optional) UDP port the Active Directory server listens on. By default, uses port 3268.
+
+
+
+### Nested Schema for `ap_tags_and_vlan_ids`
+
+Read-Only:
+
+- `tags` (List of String) Array of AP tags
+- `vlan_id` (Number) Numerical identifier that is assigned to the VLAN
+
+
+
+### Nested Schema for `ldap_servers`
+
+Read-Only:
+
+- `host` (String) IP address (or FQDN) of your LDAP server.
+- `port` (Number) UDP port the LDAP server listens on.
+
+
+
+### Nested Schema for `named_vlans_tagging_by_ap_tags`
+
+Read-Only:
+
+- `tags` (List of String) List of AP tags.
+- `vlan_name` (String) VLAN name that will be used to tag traffic.
+
+
+
+### Nested Schema for `radius_accounting_servers`
+
+Read-Only:
+
+- `ca_certificate` (String) Certificate used for authorization for the RADSEC Server
+- `host` (String) IP address (or FQDN) to which the APs will send RADIUS accounting messages
+- `port` (Number) Port on the RADIUS server that is listening for accounting messages
+- `radsec_enabled` (Boolean) Use RADSEC (TLS over TCP) to connect to this RADIUS accounting server. Requires radiusProxyEnabled.
+- `secret` (String) Shared key used to authenticate messages between the APs and RADIUS server
+
+
+
+### Nested Schema for `radius_servers`
+
+Read-Only:
+
+- `ca_certificate` (String) Certificate used for authorization for the RADSEC Server
+- `host` (String) IP address (or FQDN) of your RADIUS server
+- `open_roaming_certificate_id` (Number) The ID of the Openroaming Certificate attached to radius server.
+- `port` (Number) UDP port the RADIUS server listens on for Access-requests
+- `radsec_enabled` (Boolean) Use RADSEC (TLS over TCP) to connect to this RADIUS server. Requires radiusProxyEnabled.
+- `secret` (String) RADIUS client shared secret
diff --git a/docs/resources/multicast_rendezvous_point.md b/docs/resources/multicast_rendezvous_point.md
new file mode 100644
index 0000000..ffaa8e6
--- /dev/null
+++ b/docs/resources/multicast_rendezvous_point.md
@@ -0,0 +1,42 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "meraki_multicast_rendezvous_point Resource - terraform-provider-meraki"
+subcategory: "Switches"
+description: |-
+ This resource can manage the Multicast Rendezvous Point configuration.
+---
+
+# meraki_multicast_rendezvous_point (Resource)
+
+This resource can manage the `Multicast Rendezvous Point` configuration.
+
+## Example Usage
+
+```terraform
+resource "meraki_multicast_rendezvous_point" "example" {
+ network_id = "L_12345"
+ interface_ip = "192.168.1.2"
+ multicast_group = "Any"
+}
+```
+
+
+## Schema
+
+### Required
+
+- `interface_ip` (String) The IP address of the interface where the RP needs to be created.
+- `multicast_group` (String) `Any`, or the IP address of a multicast group
+- `network_id` (String) Network ID
+
+### Read-Only
+
+- `id` (String) The id of the object
+
+## Import
+
+Import is supported using the following syntax:
+
+```shell
+terraform import meraki_multicast_rendezvous_point.example ","
+```
diff --git a/docs/resources/wireless_ssid.md b/docs/resources/wireless_ssid.md
new file mode 100644
index 0000000..4573001
--- /dev/null
+++ b/docs/resources/wireless_ssid.md
@@ -0,0 +1,315 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "meraki_wireless_ssid Resource - terraform-provider-meraki"
+subcategory: "Wireless"
+description: |-
+ This resource can manage the Wireless SSID configuration.
+---
+
+# meraki_wireless_ssid (Resource)
+
+This resource can manage the `Wireless SSID` configuration.
+
+## Example Usage
+
+```terraform
+resource "meraki_wireless_ssid" "example" {
+ network_id = "L_123456"
+ number = "0"
+ adult_content_filtering_enabled = false
+ auth_mode = "8021x-radius"
+ available_on_all_aps = false
+ band_selection = "5 GHz band only"
+ concentrator_network_id = "N_24329156"
+ default_vlan_id = 1
+ disassociate_clients_on_vpn_failover = false
+ enabled = false
+ encryption_mode = "wpa"
+ enterprise_admin_access = "access enabled"
+ ip_assignment_mode = "Bridge mode"
+ lan_isolation_enabled = false
+ mandatory_dhcp_enabled = false
+ min_bitrate = 5.5
+ name = "My SSID"
+ per_client_bandwidth_limit_down = 0
+ per_client_bandwidth_limit_up = 0
+ per_ssid_bandwidth_limit_down = 0
+ per_ssid_bandwidth_limit_up = 0
+ psk = "deadbeef"
+ radius_accounting_enabled = false
+ radius_accounting_interim_interval = 5
+ radius_attribute_for_group_policies = "Filter-Id"
+ radius_authentication_nas_id = "00-11-22-33-44-55:AP1"
+ radius_called_station_id = "00-11-22-33-44-55:AP1"
+ radius_coa_enabled = false
+ radius_failover_policy = "Deny access"
+ radius_fallback_enabled = false
+ radius_guest_vlan_enabled = false
+ radius_guest_vlan_id = 1
+ radius_load_balancing_policy = "Round robin"
+ radius_override = false
+ radius_proxy_enabled = false
+ radius_server_attempts_limit = 5
+ radius_server_timeout = 5
+ radius_testing_enabled = false
+ secondary_concentrator_network_id = "disabled"
+ splash_page = "Click-through splash page"
+ use_vlan_tagging = false
+ visible = false
+ vlan_id = 10
+ walled_garden_enabled = false
+ wpa_encryption_mode = "WPA2 only"
+ active_directory_credentials_logon_name = "user"
+ active_directory_credentials_password = "password"
+ active_directory_servers = [
+ {
+ host = "127.0.0.1"
+ port = 3268
+ }
+ ]
+ dns_rewrite_enabled = false
+ dns_rewrite_dns_custom_nameservers = ["8.8.8.8"]
+ dot11r_adaptive = false
+ dot11r_enabled = false
+ dot11w_enabled = false
+ dot11w_required = false
+ gre_key = 5
+ gre_concentrator_host = "192.168.1.1"
+ ldap_base_distinguished_name = "dc=example,dc=com"
+ ldap_credentials_distinguished_name = "cn=user,dc=example,dc=com"
+ ldap_credentials_password = "password"
+ ldap_server_ca_certificate_contents = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
+ ldap_servers = [
+ {
+ host = "127.0.0.1"
+ port = 389
+ }
+ ]
+ local_radius_cache_timeout = 60
+ local_radius_certificate_authentication_enabled = false
+ local_radius_certificate_authentication_ocsp_responder_url = "http://ocsp-server.example.com"
+ local_radius_certificate_authentication_use_ldap = false
+ local_radius_certificate_authentication_use_ocsp = false
+ local_radius_certificate_authentication_client_root_ca_certificate_contents = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
+ local_radius_password_authentication_enabled = false
+ named_vlans_radius_guest_vlan_enabled = false
+ named_vlans_radius_guest_vlan_name = "Guest VLAN"
+ named_vlans_tagging_default_vlan_name = "My VLAN"
+ named_vlans_tagging_enabled = false
+ named_vlans_tagging_by_ap_tags = [
+ {
+ vlan_name = "My VLAN"
+ tags = ["tag1"]
+ }
+ ]
+ oauth_allowed_domains = ["example.com"]
+ speed_burst_enabled = false
+ ap_tags_and_vlan_ids = [
+ {
+ vlan_id = 100
+ tags = ["tag1"]
+ }
+ ]
+ availability_tags = ["tag1"]
+ radius_accounting_servers = [
+ {
+ ca_certificate = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
+ host = "0.0.0.0"
+ port = 3000
+ radsec_enabled = false
+ secret = "secret-string"
+ }
+ ]
+ radius_servers = [
+ {
+ ca_certificate = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
+ host = "0.0.0.0"
+ open_roaming_certificate_id = 2
+ port = 3000
+ radsec_enabled = false
+ secret = "secret-string"
+ }
+ ]
+ splash_guest_sponsor_domains = ["example.com"]
+ walled_garden_ranges = ["example.com"]
+}
+```
+
+
+## Schema
+
+### Required
+
+- `name` (String) The name of the SSID
+- `network_id` (String) Network ID
+- `number` (String) Wireless SSID number
+
+### Optional
+
+- `active_directory_credentials_logon_name` (String) The logon name of the Active Directory account.
+- `active_directory_credentials_password` (String) The password to the Active Directory user account.
+- `active_directory_servers` (Attributes List) The Active Directory servers to be used for authentication. (see [below for nested schema](#nestedatt--active_directory_servers))
+- `adult_content_filtering_enabled` (Boolean) Boolean indicating whether or not adult content will be blocked
+- `ap_tags_and_vlan_ids` (Attributes List) The list of tags and VLAN IDs used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming` (see [below for nested schema](#nestedatt--ap_tags_and_vlan_ids))
+- `auth_mode` (String) The association control method for the SSID (`open`, `open-enhanced`, `psk`, `open-with-radius`, `open-with-nac`, `8021x-meraki`, `8021x-nac`, `8021x-radius`, `8021x-google`, `8021x-entra`, `8021x-localradius`, `ipsk-with-radius`, `ipsk-without-radius` or `ipsk-with-nac`)
+ - Choices: `8021x-entra`, `8021x-google`, `8021x-localradius`, `8021x-meraki`, `8021x-nac`, `8021x-radius`, `ipsk-with-nac`, `ipsk-with-radius`, `ipsk-without-radius`, `open`, `open-enhanced`, `open-with-nac`, `open-with-radius`, `psk`
+- `availability_tags` (List of String) Accepts a list of tags for this SSID. If availableOnAllAps is false, then the SSID will only be broadcast by APs with tags matching any of the tags in this list.
+- `available_on_all_aps` (Boolean) Boolean indicating whether all APs should broadcast the SSID or if it should be restricted to APs matching any availability tags. Can only be false if the SSID has availability tags.
+- `band_selection` (String) The client-serving radio frequencies of this SSID in the default indoor RF profile. (`Dual band operation`, `5 GHz band only` or `Dual band operation with Band Steering`)
+- `concentrator_network_id` (String) The concentrator to use when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`.
+- `default_vlan_id` (Number) The default VLAN ID used for `all other APs`. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`
+- `disassociate_clients_on_vpn_failover` (Boolean) Disassociate clients when `VPN` concentrator failover occurs in order to trigger clients to re-associate and generate new DHCP requests. This param is only valid if ipAssignmentMode is `VPN`.
+- `dns_rewrite_dns_custom_nameservers` (List of String) User specified DNS servers (up to two servers)
+- `dns_rewrite_enabled` (Boolean) Boolean indicating whether or not DNS server rewrite is enabled. If disabled, upstream DNS will be used
+- `dot11r_adaptive` (Boolean) (Optional) Whether 802.11r is adaptive or not.
+- `dot11r_enabled` (Boolean) Whether 802.11r is enabled or not.
+- `dot11w_enabled` (Boolean) Whether 802.11w is enabled or not.
+- `dot11w_required` (Boolean) (Optional) Whether 802.11w is required or not.
+- `enabled` (Boolean) Whether or not the SSID is enabled
+- `encryption_mode` (String) The psk encryption mode for the SSID (`wep` or `wpa`). This param is only valid if the authMode is `psk`
+ - Choices: `open`, `wep`, `wpa`, `wpa-eap`
+- `enterprise_admin_access` (String) Whether or not an SSID is accessible by `enterprise` administrators (`access disabled` or `access enabled`)
+ - Choices: `access disabled`, `access enabled`
+- `gre_concentrator_host` (String) The EoGRE concentrator`s IP or FQDN. This param is required when ipAssignmentMode is `Ethernet over GRE`.
+- `gre_key` (Number) Optional numerical identifier that will add the GRE key field to the GRE header. Used to identify an individual traffic flow within a tunnel.
+- `ip_assignment_mode` (String) The client IP assignment mode (`NAT mode`, `Bridge mode`, `Layer 3 roaming`, `Ethernet over GRE`, `Layer 3 roaming with a concentrator` or `VPN`)
+- `lan_isolation_enabled` (Boolean) Boolean indicating whether Layer 2 LAN isolation should be enabled or disabled. Only configurable when ipAssignmentMode is `Bridge mode`.
+- `ldap_base_distinguished_name` (String) The base distinguished name of users on the LDAP server.
+- `ldap_credentials_distinguished_name` (String) The distinguished name of the LDAP user account (example: cn=user,dc=meraki,dc=com).
+- `ldap_credentials_password` (String) The password of the LDAP user account.
+- `ldap_server_ca_certificate_contents` (String) The contents of the CA certificate. Must be in PEM or DER format.
+- `ldap_servers` (Attributes List) The LDAP servers to be used for authentication. (see [below for nested schema](#nestedatt--ldap_servers))
+- `local_radius_cache_timeout` (Number) The duration (in seconds) for which LDAP and OCSP lookups are cached.
+- `local_radius_certificate_authentication_client_root_ca_certificate_contents` (String) The contents of the Client CA Certificate. Must be in PEM or DER format.
+- `local_radius_certificate_authentication_enabled` (Boolean) Whether or not to use EAP-TLS certificate-based authentication to validate wireless clients.
+- `local_radius_certificate_authentication_ocsp_responder_url` (String) (Optional) The URL of the OCSP responder to verify client certificate status.
+- `local_radius_certificate_authentication_use_ldap` (Boolean) Whether or not to verify the certificate with LDAP.
+- `local_radius_certificate_authentication_use_ocsp` (Boolean) Whether or not to verify the certificate with OCSP.
+- `local_radius_password_authentication_enabled` (Boolean) Whether or not to use EAP-TTLS/PAP or PEAP-GTC password-based authentication via LDAP lookup.
+- `mandatory_dhcp_enabled` (Boolean) If true, Mandatory DHCP will enforce that clients connecting to this SSID must use the IP address assigned by the DHCP server. Clients who use a static IP address won`t be able to associate.
+- `min_bitrate` (Number) The minimum bitrate in Mbps of this SSID in the default indoor RF profile. (`1`, `2`, `5.5`, `6`, `9`, `11`, `12`, `18`, `24`, `36`, `48` or `54`)
+- `named_vlans_radius_guest_vlan_enabled` (Boolean) Whether or not RADIUS guest named VLAN is enabled.
+- `named_vlans_radius_guest_vlan_name` (String) RADIUS guest VLAN name.
+- `named_vlans_tagging_by_ap_tags` (Attributes List) The list of AP tags and VLAN names used for named VLAN tagging. If an AP has a tag matching one in the list, then traffic on this SSID will be directed to use the VLAN name associated to the tag. (see [below for nested schema](#nestedatt--named_vlans_tagging_by_ap_tags))
+- `named_vlans_tagging_default_vlan_name` (String) The default VLAN name used to tag traffic in the absence of a matching AP tag.
+- `named_vlans_tagging_enabled` (Boolean) Whether or not traffic should be directed to use specific VLAN names.
+- `oauth_allowed_domains` (List of String) (Optional) The list of domains allowed access to the network.
+- `per_client_bandwidth_limit_down` (Number) The download bandwidth limit in Kbps. (0 represents no limit.)
+- `per_client_bandwidth_limit_up` (Number) The upload bandwidth limit in Kbps. (0 represents no limit.)
+- `per_ssid_bandwidth_limit_down` (Number) The total download bandwidth limit in Kbps. (0 represents no limit.)
+- `per_ssid_bandwidth_limit_up` (Number) The total upload bandwidth limit in Kbps. (0 represents no limit.)
+- `psk` (String) The passkey for the SSID. This param is only valid if the authMode is `psk`
+- `radius_accounting_enabled` (Boolean) Whether or not RADIUS accounting is enabled. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius`
+- `radius_accounting_interim_interval` (Number) The interval (in seconds) in which accounting information is updated and sent to the RADIUS accounting server.
+- `radius_accounting_servers` (Attributes List) The RADIUS accounting 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius` and radiusAccountingEnabled is `true` (see [below for nested schema](#nestedatt--radius_accounting_servers))
+- `radius_attribute_for_group_policies` (String) Specify the RADIUS attribute used to look up group policies (`Filter-Id`, `Reply-Message`, `Airespace-ACL-Name` or `Aruba-User-Role`). Access points must receive this attribute in the RADIUS Access-Accept message
+ - Choices: `Airespace-ACL-Name`, `Aruba-User-Role`, `Filter-Id`, `Reply-Message`
+- `radius_authentication_nas_id` (String) The template of the NAS identifier to be used for RADIUS authentication (ex. $NODE_MAC$:$VAP_NUM$).
+- `radius_called_station_id` (String) The template of the called station identifier to be used for RADIUS (ex. $NODE_MAC$:$VAP_NUM$).
+- `radius_coa_enabled` (Boolean) If true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server.
+- `radius_failover_policy` (String) This policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable (`Deny access` or `Allow access`)
+ - Choices: `Allow access`, `Deny access`
+- `radius_fallback_enabled` (Boolean) Whether or not higher priority RADIUS servers should be retried after 60 seconds.
+- `radius_guest_vlan_enabled` (Boolean) Whether or not RADIUS Guest VLAN is enabled. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode
+- `radius_guest_vlan_id` (Number) VLAN ID of the RADIUS Guest VLAN. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode
+- `radius_load_balancing_policy` (String) This policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts (`Strict priority order` or `Round robin`)
+ - Choices: `Round robin`, `Strict priority order`
+- `radius_override` (Boolean) If true, the RADIUS response can override VLAN tag. This is not valid when ipAssignmentMode is `NAT mode`.
+- `radius_proxy_enabled` (Boolean) If true, Meraki devices will proxy RADIUS messages through the Meraki cloud to the configured RADIUS auth and accounting servers.
+- `radius_server_attempts_limit` (Number) The maximum number of transmit attempts after which a RADIUS server is failed over (must be between 1-5).
+- `radius_server_timeout` (Number) The amount of time for which a RADIUS client waits for a reply from the RADIUS server (must be between 1-10 seconds).
+- `radius_servers` (Attributes List) The RADIUS 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius` (see [below for nested schema](#nestedatt--radius_servers))
+- `radius_testing_enabled` (Boolean) If true, Meraki devices will periodically send Access-Request messages to configured RADIUS servers using identity `meraki_8021x_test` to ensure that the RADIUS servers are reachable.
+- `secondary_concentrator_network_id` (String) The secondary concentrator to use when the ipAssignmentMode is `VPN`. If configured, the APs will switch to using this concentrator if the primary concentrator is unreachable. This param is optional. (`disabled` represents no secondary concentrator.)
+- `speed_burst_enabled` (Boolean) Boolean indicating whether or not to allow users to temporarily exceed the bandwidth limit for short periods while still keeping them under the bandwidth limit over time.
+- `splash_guest_sponsor_domains` (List of String) Array of valid sponsor email domains for sponsored guest splash type.
+- `splash_page` (String) The type of splash page for the SSID (`None`, `Click-through splash page`, `Billing`, `Password-protected with Meraki RADIUS`, `Password-protected with custom RADIUS`, `Password-protected with Active Directory`, `Password-protected with LDAP`, `SMS authentication`, `Systems Manager Sentry`, `Facebook Wi-Fi`, `Google OAuth`, `Microsoft Entra ID`, `Sponsored guest`, `Cisco ISE` or `Google Apps domain`). This attribute is not supported for template children.
+ - Choices: `Billing`, `Cisco ISE`, `Click-through splash page`, `Facebook Wi-Fi`, `Google Apps domain`, `Google OAuth`, `Microsoft Entra ID`, `None`, `Password-protected with Active Directory`, `Password-protected with LDAP`, `Password-protected with Meraki RADIUS`, `Password-protected with custom RADIUS`, `SMS authentication`, `Sponsored guest`, `Systems Manager Sentry`
+- `use_vlan_tagging` (Boolean) Whether or not traffic should be directed to use specific VLANs. This param is only valid if the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`
+- `visible` (Boolean) Boolean indicating whether APs should advertise or hide this SSID. APs will only broadcast this SSID if set to true
+- `vlan_id` (Number) The VLAN ID used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`
+- `walled_garden_enabled` (Boolean) Allow access to a configurable list of IP ranges, which users may access prior to sign-on.
+- `walled_garden_ranges` (List of String) Specify your walled garden by entering an array of addresses, ranges using CIDR notation, domain names, and domain wildcards (e.g. `192.168.1.1/24`, `192.168.37.10/32`, `www.yahoo.com`, `*.google.com`]). Meraki`s splash page is automatically included in your walled garden.
+- `wpa_encryption_mode` (String) The types of WPA encryption. (`WPA1 only`, `WPA1 and WPA2`, `WPA2 only`, `WPA3 Transition Mode`, `WPA3 only` or `WPA3 192-bit Security`)
+ - Choices: `WPA1 and WPA2`, `WPA1 only`, `WPA2 only`, `WPA3 192-bit Security`, `WPA3 Transition Mode`, `WPA3 only`
+
+### Read-Only
+
+- `id` (String) The id of the object
+
+
+### Nested Schema for `active_directory_servers`
+
+Required:
+
+- `host` (String) IP address (or FQDN) of your Active Directory server.
+
+Optional:
+
+- `port` (Number) (Optional) UDP port the Active Directory server listens on. By default, uses port 3268.
+
+
+
+### Nested Schema for `ap_tags_and_vlan_ids`
+
+Optional:
+
+- `tags` (List of String) Array of AP tags
+- `vlan_id` (Number) Numerical identifier that is assigned to the VLAN
+
+
+
+### Nested Schema for `ldap_servers`
+
+Required:
+
+- `host` (String) IP address (or FQDN) of your LDAP server.
+- `port` (Number) UDP port the LDAP server listens on.
+
+
+
+### Nested Schema for `named_vlans_tagging_by_ap_tags`
+
+Optional:
+
+- `tags` (List of String) List of AP tags.
+- `vlan_name` (String) VLAN name that will be used to tag traffic.
+
+
+
+### Nested Schema for `radius_accounting_servers`
+
+Required:
+
+- `host` (String) IP address (or FQDN) to which the APs will send RADIUS accounting messages
+
+Optional:
+
+- `ca_certificate` (String) Certificate used for authorization for the RADSEC Server
+- `port` (Number) Port on the RADIUS server that is listening for accounting messages
+- `radsec_enabled` (Boolean) Use RADSEC (TLS over TCP) to connect to this RADIUS accounting server. Requires radiusProxyEnabled.
+- `secret` (String) Shared key used to authenticate messages between the APs and RADIUS server
+
+
+
+### Nested Schema for `radius_servers`
+
+Required:
+
+- `host` (String) IP address (or FQDN) of your RADIUS server
+
+Optional:
+
+- `ca_certificate` (String) Certificate used for authorization for the RADSEC Server
+- `open_roaming_certificate_id` (Number) The ID of the Openroaming Certificate attached to radius server.
+- `port` (Number) UDP port the RADIUS server listens on for Access-requests
+- `radsec_enabled` (Boolean) Use RADSEC (TLS over TCP) to connect to this RADIUS server. Requires radiusProxyEnabled.
+- `secret` (String) RADIUS client shared secret
+
+## Import
+
+Import is supported using the following syntax:
+
+```shell
+terraform import meraki_wireless_ssid.example ""
+```
diff --git a/examples/data-sources/meraki_multicast_rendezvous_point/data-source.tf b/examples/data-sources/meraki_multicast_rendezvous_point/data-source.tf
new file mode 100644
index 0000000..ef6b6d2
--- /dev/null
+++ b/examples/data-sources/meraki_multicast_rendezvous_point/data-source.tf
@@ -0,0 +1,4 @@
+data "meraki_multicast_rendezvous_point" "example" {
+ id = "12345678"
+ network_id = "L_12345"
+}
diff --git a/examples/data-sources/meraki_wireless_ssid/data-source.tf b/examples/data-sources/meraki_wireless_ssid/data-source.tf
new file mode 100644
index 0000000..208ca17
--- /dev/null
+++ b/examples/data-sources/meraki_wireless_ssid/data-source.tf
@@ -0,0 +1,5 @@
+data "meraki_wireless_ssid" "example" {
+ id = "0"
+ network_id = "L_123456"
+ number = "0"
+}
diff --git a/examples/resources/meraki_multicast_rendezvous_point/import.sh b/examples/resources/meraki_multicast_rendezvous_point/import.sh
new file mode 100644
index 0000000..fd355cb
--- /dev/null
+++ b/examples/resources/meraki_multicast_rendezvous_point/import.sh
@@ -0,0 +1 @@
+terraform import meraki_multicast_rendezvous_point.example ","
diff --git a/examples/resources/meraki_multicast_rendezvous_point/resource.tf b/examples/resources/meraki_multicast_rendezvous_point/resource.tf
new file mode 100644
index 0000000..204f4f1
--- /dev/null
+++ b/examples/resources/meraki_multicast_rendezvous_point/resource.tf
@@ -0,0 +1,5 @@
+resource "meraki_multicast_rendezvous_point" "example" {
+ network_id = "L_12345"
+ interface_ip = "192.168.1.2"
+ multicast_group = "Any"
+}
diff --git a/examples/resources/meraki_wireless_ssid/import.sh b/examples/resources/meraki_wireless_ssid/import.sh
new file mode 100644
index 0000000..105f2d4
--- /dev/null
+++ b/examples/resources/meraki_wireless_ssid/import.sh
@@ -0,0 +1 @@
+terraform import meraki_wireless_ssid.example ""
diff --git a/examples/resources/meraki_wireless_ssid/resource.tf b/examples/resources/meraki_wireless_ssid/resource.tf
new file mode 100644
index 0000000..4bda57a
--- /dev/null
+++ b/examples/resources/meraki_wireless_ssid/resource.tf
@@ -0,0 +1,120 @@
+resource "meraki_wireless_ssid" "example" {
+ network_id = "L_123456"
+ number = "0"
+ adult_content_filtering_enabled = false
+ auth_mode = "8021x-radius"
+ available_on_all_aps = false
+ band_selection = "5 GHz band only"
+ concentrator_network_id = "N_24329156"
+ default_vlan_id = 1
+ disassociate_clients_on_vpn_failover = false
+ enabled = false
+ encryption_mode = "wpa"
+ enterprise_admin_access = "access enabled"
+ ip_assignment_mode = "Bridge mode"
+ lan_isolation_enabled = false
+ mandatory_dhcp_enabled = false
+ min_bitrate = 5.5
+ name = "My SSID"
+ per_client_bandwidth_limit_down = 0
+ per_client_bandwidth_limit_up = 0
+ per_ssid_bandwidth_limit_down = 0
+ per_ssid_bandwidth_limit_up = 0
+ psk = "deadbeef"
+ radius_accounting_enabled = false
+ radius_accounting_interim_interval = 5
+ radius_attribute_for_group_policies = "Filter-Id"
+ radius_authentication_nas_id = "00-11-22-33-44-55:AP1"
+ radius_called_station_id = "00-11-22-33-44-55:AP1"
+ radius_coa_enabled = false
+ radius_failover_policy = "Deny access"
+ radius_fallback_enabled = false
+ radius_guest_vlan_enabled = false
+ radius_guest_vlan_id = 1
+ radius_load_balancing_policy = "Round robin"
+ radius_override = false
+ radius_proxy_enabled = false
+ radius_server_attempts_limit = 5
+ radius_server_timeout = 5
+ radius_testing_enabled = false
+ secondary_concentrator_network_id = "disabled"
+ splash_page = "Click-through splash page"
+ use_vlan_tagging = false
+ visible = false
+ vlan_id = 10
+ walled_garden_enabled = false
+ wpa_encryption_mode = "WPA2 only"
+ active_directory_credentials_logon_name = "user"
+ active_directory_credentials_password = "password"
+ active_directory_servers = [
+ {
+ host = "127.0.0.1"
+ port = 3268
+ }
+ ]
+ dns_rewrite_enabled = false
+ dns_rewrite_dns_custom_nameservers = ["8.8.8.8"]
+ dot11r_adaptive = false
+ dot11r_enabled = false
+ dot11w_enabled = false
+ dot11w_required = false
+ gre_key = 5
+ gre_concentrator_host = "192.168.1.1"
+ ldap_base_distinguished_name = "dc=example,dc=com"
+ ldap_credentials_distinguished_name = "cn=user,dc=example,dc=com"
+ ldap_credentials_password = "password"
+ ldap_server_ca_certificate_contents = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
+ ldap_servers = [
+ {
+ host = "127.0.0.1"
+ port = 389
+ }
+ ]
+ local_radius_cache_timeout = 60
+ local_radius_certificate_authentication_enabled = false
+ local_radius_certificate_authentication_ocsp_responder_url = "http://ocsp-server.example.com"
+ local_radius_certificate_authentication_use_ldap = false
+ local_radius_certificate_authentication_use_ocsp = false
+ local_radius_certificate_authentication_client_root_ca_certificate_contents = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
+ local_radius_password_authentication_enabled = false
+ named_vlans_radius_guest_vlan_enabled = false
+ named_vlans_radius_guest_vlan_name = "Guest VLAN"
+ named_vlans_tagging_default_vlan_name = "My VLAN"
+ named_vlans_tagging_enabled = false
+ named_vlans_tagging_by_ap_tags = [
+ {
+ vlan_name = "My VLAN"
+ tags = ["tag1"]
+ }
+ ]
+ oauth_allowed_domains = ["example.com"]
+ speed_burst_enabled = false
+ ap_tags_and_vlan_ids = [
+ {
+ vlan_id = 100
+ tags = ["tag1"]
+ }
+ ]
+ availability_tags = ["tag1"]
+ radius_accounting_servers = [
+ {
+ ca_certificate = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
+ host = "0.0.0.0"
+ port = 3000
+ radsec_enabled = false
+ secret = "secret-string"
+ }
+ ]
+ radius_servers = [
+ {
+ ca_certificate = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"
+ host = "0.0.0.0"
+ open_roaming_certificate_id = 2
+ port = 3000
+ radsec_enabled = false
+ secret = "secret-string"
+ }
+ ]
+ splash_guest_sponsor_domains = ["example.com"]
+ walled_garden_ranges = ["example.com"]
+}
diff --git a/gen/definition.go b/gen/definition.go
index b18d820..0f31a34 100644
--- a/gen/definition.go
+++ b/gen/definition.go
@@ -179,7 +179,7 @@ func toStringSlice(i []interface{}) []string {
var jsonTypes = map[string]string{
"integer": "Int64",
- "number": "Float",
+ "number": "Float64",
"boolean": "Bool",
"string": "String",
}
@@ -237,7 +237,7 @@ func traverseProperties(m map[string]interface{}, path []string, gjsonPath strin
attr.ModelName = propName
childGjsonPath := (gjsonPath + "." + propName)[1:]
res := gjson.Get(exampleStr, childGjsonPath)
- attr.Example = res.String()
+ attr.Example = sanitizeExample(res.String())
if desc, ok := propMap["description"]; ok {
attr.Description = sanitizeDescription(desc.(string))
}
@@ -249,14 +249,14 @@ func traverseProperties(m map[string]interface{}, path []string, gjsonPath strin
if min, ok := propMap["minimum"]; ok {
if attr.Type == "Int64" {
attr.MinInt = min.(int64)
- } else if attr.Type == "Float" {
+ } else if attr.Type == "Float64" {
attr.MinFloat = min.(float64)
}
}
if max, ok := propMap["maximum"]; ok {
if attr.Type == "Int64" {
attr.MaxInt = max.(int64)
- } else if attr.Type == "Float" {
+ } else if attr.Type == "Float64" {
attr.MaxFloat = max.(float64)
}
}
@@ -297,7 +297,7 @@ func traverseProperties(m map[string]interface{}, path []string, gjsonPath strin
attr.ElementType = t
childGjsonPath := (gjsonPath + "." + propName + ".0")[1:]
res := gjson.Get(exampleStr, childGjsonPath)
- attr.Example = res.String()
+ attr.Example = sanitizeExample(res.String())
} else if items["type"].(string) == "object" {
childGjsonPath := gjsonPath + "." + propName + ".0"
childRequired := []string{}
@@ -322,3 +322,8 @@ func sanitizeDescription(desc string) string {
desc = strings.Join(strings.Fields(desc), " ") // Remove extra spaces
return desc
}
+
+func sanitizeExample(ex string) string {
+ ex = strings.ReplaceAll(ex, "\n", "\\n")
+ return ex
+}
diff --git a/gen/definitions/multicast_rendezvous_point.yaml b/gen/definitions/multicast_rendezvous_point.yaml
new file mode 100644
index 0000000..0b37674
--- /dev/null
+++ b/gen/definitions/multicast_rendezvous_point.yaml
@@ -0,0 +1,29 @@
+name: Multicast Rendezvous Point
+rest_endpoint: /networks/%v/switch/routing/multicast/rendezvousPoints
+doc_category: Switches
+attributes:
+ - tf_name: network_id
+ type: String
+ reference: true
+ description: Network ID
+ example: L_12345
+ test_value: meraki_network.test.id
+ - model_name: interfaceIp
+ type: String
+ mandatory: true
+ description: The IP address of the interface where the RP needs to be created.
+ example: 192.168.1.2
+ - model_name: multicastGroup
+ type: String
+ mandatory: true
+ description: '`Any`, or the IP address of a multicast group'
+ example: Any
+test_prerequisites: |
+ data "meraki_organization" "test" {
+ name = "Dev"
+ }
+ resource "meraki_network" "test" {
+ organization_id = data.meraki_organization.test.id
+ name = "Network1"
+ product_types = ["switch", "wireless"]
+ }
diff --git a/gen/definitions/wireless_ssid.yaml b/gen/definitions/wireless_ssid.yaml
new file mode 100644
index 0000000..e9c315b
--- /dev/null
+++ b/gen/definitions/wireless_ssid.yaml
@@ -0,0 +1,491 @@
+name: Wireless SSID
+rest_endpoint: /networks/%v/wireless/ssids/%v
+data_source_name_query: true
+doc_category: Wireless
+put_create: true
+no_delete: true
+attributes:
+ - tf_name: network_id
+ type: String
+ reference: true
+ description: Network ID
+ example: L_123456
+ test_value: meraki_network.test.id
+ - tf_name: number
+ type: String
+ reference: true
+ id: true
+ description: Wireless SSID number
+ example: "0"
+ - model_name: adultContentFilteringEnabled
+ type: Bool
+ description: Boolean indicating whether or not adult content will be blocked
+ example: "false"
+ - model_name: authMode
+ type: String
+ description: The association control method for the SSID (`open`, `open-enhanced`, `psk`, `open-with-radius`, `open-with-nac`, `8021x-meraki`, `8021x-nac`, `8021x-radius`, `8021x-google`, `8021x-entra`, `8021x-localradius`, `ipsk-with-radius`, `ipsk-without-radius` or `ipsk-with-nac`)
+ example: 8021x-radius
+ enum_values: [8021x-entra, 8021x-google, 8021x-localradius, 8021x-meraki, 8021x-nac, 8021x-radius, ipsk-with-nac, ipsk-with-radius, ipsk-without-radius, open, open-enhanced, open-with-nac, open-with-radius, psk]
+ - model_name: availableOnAllAps
+ type: Bool
+ description: Boolean indicating whether all APs should broadcast the SSID or if it should be restricted to APs matching any availability tags. Can only be false if the SSID has availability tags.
+ example: "false"
+ - model_name: bandSelection
+ type: String
+ description: The client-serving radio frequencies of this SSID in the default indoor RF profile. (`Dual band operation`, `5 GHz band only` or `Dual band operation with Band Steering`)
+ example: 5 GHz band only
+ - model_name: concentratorNetworkId
+ type: String
+ exclude_test: true
+ description: The concentrator to use when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`.
+ example: N_24329156
+ - model_name: defaultVlanId
+ type: Int64
+ description: The default VLAN ID used for `all other APs`. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`
+ example: "1"
+ - model_name: disassociateClientsOnVpnFailover
+ type: Bool
+ description: Disassociate clients when `VPN` concentrator failover occurs in order to trigger clients to re-associate and generate new DHCP requests. This param is only valid if ipAssignmentMode is `VPN`.
+ example: "false"
+ - model_name: enabled
+ type: Bool
+ description: Whether or not the SSID is enabled
+ example: "false"
+ - model_name: encryptionMode
+ type: String
+ description: The psk encryption mode for the SSID (`wep` or `wpa`). This param is only valid if the authMode is `psk`
+ example: wpa
+ enum_values: [open, wep, wpa, wpa-eap]
+ - model_name: enterpriseAdminAccess
+ type: String
+ description: Whether or not an SSID is accessible by `enterprise` administrators (`access disabled` or `access enabled`)
+ example: access enabled
+ exclude_test: true
+ enum_values: [access disabled, access enabled]
+ - model_name: ipAssignmentMode
+ type: String
+ description: The client IP assignment mode (`NAT mode`, `Bridge mode`, `Layer 3 roaming`, `Ethernet over GRE`, `Layer 3 roaming with a concentrator` or `VPN`)
+ example: Bridge mode
+ - model_name: lanIsolationEnabled
+ type: Bool
+ description: Boolean indicating whether Layer 2 LAN isolation should be enabled or disabled. Only configurable when ipAssignmentMode is `Bridge mode`.
+ example: "false"
+ - model_name: mandatoryDhcpEnabled
+ type: Bool
+ description: If true, Mandatory DHCP will enforce that clients connecting to this SSID must use the IP address assigned by the DHCP server. Clients who use a static IP address won`t be able to associate.
+ example: "false"
+ - model_name: minBitrate
+ type: Float64
+ description: The minimum bitrate in Mbps of this SSID in the default indoor RF profile. (`1`, `2`, `5.5`, `6`, `9`, `11`, `12`, `18`, `24`, `36`, `48` or `54`)
+ example: "5.5"
+ - model_name: name
+ type: String
+ description: The name of the SSID
+ example: My SSID
+ mandatory: true
+ - model_name: perClientBandwidthLimitDown
+ type: Int64
+ description: The download bandwidth limit in Kbps. (0 represents no limit.)
+ example: "0"
+ - model_name: perClientBandwidthLimitUp
+ type: Int64
+ description: The upload bandwidth limit in Kbps. (0 represents no limit.)
+ example: "0"
+ - model_name: perSsidBandwidthLimitDown
+ type: Int64
+ description: The total download bandwidth limit in Kbps. (0 represents no limit.)
+ example: "0"
+ - model_name: perSsidBandwidthLimitUp
+ type: Int64
+ description: The total upload bandwidth limit in Kbps. (0 represents no limit.)
+ example: "0"
+ - model_name: psk
+ type: String
+ description: The passkey for the SSID. This param is only valid if the authMode is `psk`
+ example: deadbeef
+ - model_name: radiusAccountingEnabled
+ type: Bool
+ description: Whether or not RADIUS accounting is enabled. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius`
+ example: "false"
+ - model_name: radiusAccountingInterimInterval
+ type: Int64
+ description: The interval (in seconds) in which accounting information is updated and sent to the RADIUS accounting server.
+ example: "5"
+ - model_name: radiusAttributeForGroupPolicies
+ type: String
+ description: Specify the RADIUS attribute used to look up group policies (`Filter-Id`, `Reply-Message`, `Airespace-ACL-Name` or `Aruba-User-Role`). Access points must receive this attribute in the RADIUS Access-Accept message
+ example: Filter-Id
+ enum_values: [Airespace-ACL-Name, Aruba-User-Role, Filter-Id, Reply-Message]
+ - model_name: radiusAuthenticationNasId
+ type: String
+ description: The template of the NAS identifier to be used for RADIUS authentication (ex. $NODE_MAC$:$VAP_NUM$).
+ example: 00-11-22-33-44-55:AP1
+ - model_name: radiusCalledStationId
+ type: String
+ description: The template of the called station identifier to be used for RADIUS (ex. $NODE_MAC$:$VAP_NUM$).
+ example: 00-11-22-33-44-55:AP1
+ - model_name: radiusCoaEnabled
+ type: Bool
+ description: If true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server.
+ example: "false"
+ - model_name: radiusFailoverPolicy
+ type: String
+ description: This policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable (`Deny access` or `Allow access`)
+ example: Deny access
+ enum_values: [Allow access, Deny access]
+ - model_name: radiusFallbackEnabled
+ type: Bool
+ description: Whether or not higher priority RADIUS servers should be retried after 60 seconds.
+ example: "false"
+ - model_name: radiusGuestVlanEnabled
+ type: Bool
+ description: Whether or not RADIUS Guest VLAN is enabled. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode
+ example: "false"
+ - model_name: radiusGuestVlanId
+ type: Int64
+ description: VLAN ID of the RADIUS Guest VLAN. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode
+ example: "1"
+ - model_name: radiusLoadBalancingPolicy
+ type: String
+ description: This policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts (`Strict priority order` or `Round robin`)
+ example: Round robin
+ enum_values: [Round robin, Strict priority order]
+ - model_name: radiusOverride
+ type: Bool
+ description: If true, the RADIUS response can override VLAN tag. This is not valid when ipAssignmentMode is `NAT mode`.
+ example: "false"
+ - model_name: radiusProxyEnabled
+ type: Bool
+ description: If true, Meraki devices will proxy RADIUS messages through the Meraki cloud to the configured RADIUS auth and accounting servers.
+ example: "false"
+ - model_name: radiusServerAttemptsLimit
+ type: Int64
+ description: The maximum number of transmit attempts after which a RADIUS server is failed over (must be between 1-5).
+ example: "5"
+ - model_name: radiusServerTimeout
+ type: Int64
+ description: The amount of time for which a RADIUS client waits for a reply from the RADIUS server (must be between 1-10 seconds).
+ example: "5"
+ - model_name: radiusTestingEnabled
+ type: Bool
+ description: If true, Meraki devices will periodically send Access-Request messages to configured RADIUS servers using identity `meraki_8021x_test` to ensure that the RADIUS servers are reachable.
+ example: "false"
+ - model_name: secondaryConcentratorNetworkId
+ type: String
+ description: The secondary concentrator to use when the ipAssignmentMode is `VPN`. If configured, the APs will switch to using this concentrator if the primary concentrator is unreachable. This param is optional. (`disabled` represents no secondary concentrator.)
+ example: disabled
+ - model_name: splashPage
+ type: String
+ description: The type of splash page for the SSID (`None`, `Click-through splash page`, `Billing`, `Password-protected with Meraki RADIUS`, `Password-protected with custom RADIUS`, `Password-protected with Active Directory`, `Password-protected with LDAP`, `SMS authentication`, `Systems Manager Sentry`, `Facebook Wi-Fi`, `Google OAuth`, `Microsoft Entra ID`, `Sponsored guest`, `Cisco ISE` or `Google Apps domain`). This attribute is not supported for template children.
+ example: Click-through splash page
+ enum_values: [Billing, Cisco ISE, Click-through splash page, Facebook Wi-Fi, Google Apps domain, Google OAuth, Microsoft Entra ID, None, Password-protected with Active Directory, Password-protected with LDAP, Password-protected with Meraki RADIUS, Password-protected with custom RADIUS, SMS authentication, Sponsored guest, Systems Manager Sentry]
+ - model_name: useVlanTagging
+ type: Bool
+ description: Whether or not traffic should be directed to use specific VLANs. This param is only valid if the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`
+ example: "false"
+ - model_name: visible
+ type: Bool
+ description: Boolean indicating whether APs should advertise or hide this SSID. APs will only broadcast this SSID if set to true
+ example: "false"
+ - model_name: vlanId
+ type: Int64
+ description: The VLAN ID used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`
+ example: "10"
+ - model_name: walledGardenEnabled
+ type: Bool
+ description: Allow access to a configurable list of IP ranges, which users may access prior to sign-on.
+ example: "false"
+ - model_name: wpaEncryptionMode
+ type: String
+ description: The types of WPA encryption. (`WPA1 only`, `WPA1 and WPA2`, `WPA2 only`, `WPA3 Transition Mode`, `WPA3 only` or `WPA3 192-bit Security`)
+ example: WPA2 only
+ enum_values: [WPA1 and WPA2, WPA1 only, WPA2 only, WPA3 192-bit Security, WPA3 Transition Mode, WPA3 only]
+ - model_name: logonName
+ type: String
+ data_path: [activeDirectory, credentials]
+ description: The logon name of the Active Directory account.
+ exclude_test: true
+ example: user
+ - model_name: password
+ type: String
+ data_path: [activeDirectory, credentials]
+ description: The password to the Active Directory user account.
+ example: password
+ exclude_test: true
+ - model_name: servers
+ type: List
+ data_path: [activeDirectory]
+ exclude_test: true
+ description: The Active Directory servers to be used for authentication.
+ attributes:
+ - model_name: host
+ type: String
+ mandatory: true
+ description: IP address (or FQDN) of your Active Directory server.
+ example: 127.0.0.1
+ - model_name: port
+ type: Int64
+ description: (Optional) UDP port the Active Directory server listens on. By default, uses port 3268.
+ example: "3268"
+ - model_name: enabled
+ type: Bool
+ data_path: [dnsRewrite]
+ description: Boolean indicating whether or not DNS server rewrite is enabled. If disabled, upstream DNS will be used
+ example: "false"
+ exclude_test: true
+ - model_name: dnsCustomNameservers
+ type: List
+ element_type: String
+ data_path: [dnsRewrite]
+ exclude_test: true
+ description: User specified DNS servers (up to two servers)
+ example: 8.8.8.8
+ - model_name: adaptive
+ type: Bool
+ data_path: [dot11r]
+ description: (Optional) Whether 802.11r is adaptive or not.
+ example: "false"
+ - model_name: enabled
+ type: Bool
+ data_path: [dot11r]
+ description: Whether 802.11r is enabled or not.
+ example: "false"
+ - model_name: enabled
+ type: Bool
+ data_path: [dot11w]
+ description: Whether 802.11w is enabled or not.
+ example: "false"
+ - model_name: required
+ type: Bool
+ data_path: [dot11w]
+ description: (Optional) Whether 802.11w is required or not.
+ example: "false"
+ - model_name: key
+ type: Int64
+ data_path: [gre]
+ description: Optional numerical identifier that will add the GRE key field to the GRE header. Used to identify an individual traffic flow within a tunnel.
+ example: "5"
+ - model_name: host
+ type: String
+ data_path: [gre, concentrator]
+ description: The EoGRE concentrator`s IP or FQDN. This param is required when ipAssignmentMode is `Ethernet over GRE`.
+ example: 192.168.1.1
+ - model_name: baseDistinguishedName
+ type: String
+ data_path: [ldap]
+ exclude_test: true
+ description: The base distinguished name of users on the LDAP server.
+ example: dc=example,dc=com
+ - model_name: distinguishedName
+ type: String
+ data_path: [ldap, credentials]
+ exclude_test: true
+ description: 'The distinguished name of the LDAP user account (example: cn=user,dc=meraki,dc=com).'
+ example: cn=user,dc=example,dc=com
+ - model_name: password
+ type: String
+ data_path: [ldap, credentials]
+ exclude_test: true
+ description: The password of the LDAP user account.
+ example: password
+ - model_name: contents
+ type: String
+ data_path: [ldap, serverCaCertificate]
+ exclude_test: true
+ description: The contents of the CA certificate. Must be in PEM or DER format.
+ example: '-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----'
+ - model_name: servers
+ type: List
+ data_path: [ldap]
+ exclude_test: true
+ description: The LDAP servers to be used for authentication.
+ attributes:
+ - model_name: host
+ type: String
+ mandatory: true
+ description: IP address (or FQDN) of your LDAP server.
+ example: 127.0.0.1
+ - model_name: port
+ type: Int64
+ mandatory: true
+ description: UDP port the LDAP server listens on.
+ example: "389"
+ - model_name: cacheTimeout
+ type: Int64
+ data_path: [localRadius]
+ description: The duration (in seconds) for which LDAP and OCSP lookups are cached.
+ example: "60"
+ - model_name: enabled
+ type: Bool
+ data_path: [localRadius, certificateAuthentication]
+ description: Whether or not to use EAP-TLS certificate-based authentication to validate wireless clients.
+ example: "false"
+ - model_name: ocspResponderUrl
+ type: String
+ data_path: [localRadius, certificateAuthentication]
+ description: (Optional) The URL of the OCSP responder to verify client certificate status.
+ example: http://ocsp-server.example.com
+ - model_name: useLdap
+ type: Bool
+ data_path: [localRadius, certificateAuthentication]
+ description: Whether or not to verify the certificate with LDAP.
+ example: "false"
+ - model_name: useOcsp
+ type: Bool
+ data_path: [localRadius, certificateAuthentication]
+ description: Whether or not to verify the certificate with OCSP.
+ example: "false"
+ - model_name: contents
+ type: String
+ data_path: [localRadius, certificateAuthentication, clientRootCaCertificate]
+ description: The contents of the Client CA Certificate. Must be in PEM or DER format.
+ example: '-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----'
+ - model_name: enabled
+ type: Bool
+ data_path: [localRadius, passwordAuthentication]
+ description: Whether or not to use EAP-TTLS/PAP or PEAP-GTC password-based authentication via LDAP lookup.
+ example: "false"
+ - model_name: enabled
+ type: Bool
+ data_path: [namedVlans, radius, guestVlan]
+ description: Whether or not RADIUS guest named VLAN is enabled.
+ example: "false"
+ - model_name: name
+ type: String
+ data_path: [namedVlans, radius, guestVlan]
+ description: RADIUS guest VLAN name.
+ exclude_test: true
+ example: Guest VLAN
+ - model_name: defaultVlanName
+ type: String
+ data_path: [namedVlans, tagging]
+ description: The default VLAN name used to tag traffic in the absence of a matching AP tag.
+ example: My VLAN
+ exclude_test: true
+ - model_name: enabled
+ type: Bool
+ data_path: [namedVlans, tagging]
+ description: Whether or not traffic should be directed to use specific VLAN names.
+ example: "false"
+ - model_name: byApTags
+ type: List
+ data_path: [namedVlans, tagging]
+ exclude_test: true
+ description: The list of AP tags and VLAN names used for named VLAN tagging. If an AP has a tag matching one in the list, then traffic on this SSID will be directed to use the VLAN name associated to the tag.
+ attributes:
+ - model_name: vlanName
+ type: String
+ description: VLAN name that will be used to tag traffic.
+ example: My VLAN
+ - model_name: tags
+ type: List
+ element_type: String
+ description: List of AP tags.
+ example: tag1
+ - model_name: allowedDomains
+ type: List
+ element_type: String
+ data_path: [oauth]
+ description: (Optional) The list of domains allowed access to the network.
+ exclude_test: true
+ example: example.com
+ - model_name: enabled
+ type: Bool
+ data_path: [speedBurst]
+ description: Boolean indicating whether or not to allow users to temporarily exceed the bandwidth limit for short periods while still keeping them under the bandwidth limit over time.
+ example: "false"
+ - model_name: apTagsAndVlanIds
+ type: List
+ description: The list of tags and VLAN IDs used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`
+ attributes:
+ - model_name: vlanId
+ type: Int64
+ description: Numerical identifier that is assigned to the VLAN
+ example: "100"
+ - model_name: tags
+ type: List
+ element_type: String
+ description: Array of AP tags
+ example: tag1
+ - model_name: availabilityTags
+ type: List
+ element_type: String
+ description: Accepts a list of tags for this SSID. If availableOnAllAps is false, then the SSID will only be broadcast by APs with tags matching any of the tags in this list.
+ example: tag1
+ - model_name: radiusAccountingServers
+ type: List
+ exclude_test: true
+ description: The RADIUS accounting 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius` and radiusAccountingEnabled is `true`
+ attributes:
+ - model_name: caCertificate
+ type: String
+ description: Certificate used for authorization for the RADSEC Server
+ example: '-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----'
+ - model_name: host
+ type: String
+ mandatory: true
+ description: IP address (or FQDN) to which the APs will send RADIUS accounting messages
+ example: 0.0.0.0
+ - model_name: port
+ type: Int64
+ description: Port on the RADIUS server that is listening for accounting messages
+ example: "3000"
+ - model_name: radsecEnabled
+ type: Bool
+ description: Use RADSEC (TLS over TCP) to connect to this RADIUS accounting server. Requires radiusProxyEnabled.
+ example: "false"
+ - model_name: secret
+ type: String
+ description: Shared key used to authenticate messages between the APs and RADIUS server
+ example: secret-string
+ - model_name: radiusServers
+ type: List
+ description: The RADIUS 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius`
+ attributes:
+ - model_name: caCertificate
+ type: String
+ description: Certificate used for authorization for the RADSEC Server
+ example: '-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----'
+ - model_name: host
+ type: String
+ mandatory: true
+ description: IP address (or FQDN) of your RADIUS server
+ example: 0.0.0.0
+ - model_name: openRoamingCertificateId
+ type: Int64
+ description: The ID of the Openroaming Certificate attached to radius server.
+ exclude_test: true
+ example: "2"
+ - model_name: port
+ type: Int64
+ description: UDP port the RADIUS server listens on for Access-requests
+ example: "3000"
+ - model_name: radsecEnabled
+ type: Bool
+ description: Use RADSEC (TLS over TCP) to connect to this RADIUS server. Requires radiusProxyEnabled.
+ example: "false"
+ - model_name: secret
+ type: String
+ description: RADIUS client shared secret
+ example: secret-string
+ - model_name: splashGuestSponsorDomains
+ type: List
+ element_type: String
+ description: Array of valid sponsor email domains for sponsored guest splash type.
+ exclude_test: true
+ example: example.com
+ - model_name: walledGardenRanges
+ type: List
+ element_type: String
+ exclude_test: true
+ description: Specify your walled garden by entering an array of addresses, ranges using CIDR notation, domain names, and domain wildcards (e.g. `192.168.1.1/24`, `192.168.37.10/32`, `www.yahoo.com`, `*.google.com`]). Meraki`s splash page is automatically included in your walled garden.
+ example: example.com
+test_prerequisites: |
+ data "meraki_organization" "test" {
+ name = "Dev"
+ }
+ resource "meraki_network" "test" {
+ organization_id = data.meraki_organization.test.id
+ name = "Network1"
+ product_types = ["switch", "wireless"]
+ }
diff --git a/internal/provider/data_source_meraki_multicast_rendezvous_point.go b/internal/provider/data_source_meraki_multicast_rendezvous_point.go
new file mode 100644
index 0000000..52f26cc
--- /dev/null
+++ b/internal/provider/data_source_meraki_multicast_rendezvous_point.go
@@ -0,0 +1,124 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "context"
+ "fmt"
+ "net/url"
+
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/netascode/go-meraki"
+ "github.com/tidwall/gjson"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin model
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+ _ datasource.DataSource = &MulticastRendezvousPointDataSource{}
+ _ datasource.DataSourceWithConfigure = &MulticastRendezvousPointDataSource{}
+)
+
+func NewMulticastRendezvousPointDataSource() datasource.DataSource {
+ return &MulticastRendezvousPointDataSource{}
+}
+
+type MulticastRendezvousPointDataSource struct {
+ client *meraki.Client
+}
+
+func (d *MulticastRendezvousPointDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_multicast_rendezvous_point"
+}
+
+func (d *MulticastRendezvousPointDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ // This description is used by the documentation generator and the language server.
+ MarkdownDescription: "This data source can read the `Multicast Rendezvous Point` configuration.",
+
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The id of the object",
+ Required: true,
+ },
+ "network_id": schema.StringAttribute{
+ MarkdownDescription: "Network ID",
+ Required: true,
+ },
+ "interface_ip": schema.StringAttribute{
+ MarkdownDescription: "The IP address of the interface where the RP needs to be created.",
+ Computed: true,
+ },
+ "multicast_group": schema.StringAttribute{
+ MarkdownDescription: "`Any`, or the IP address of a multicast group",
+ Computed: true,
+ },
+ },
+ }
+}
+
+func (d *MulticastRendezvousPointDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ d.client = req.ProviderData.(*MerakiProviderData).Client
+}
+
+// End of section. //template:end model
+
+// Section below is generated&owned by "gen/generator.go". //template:begin read
+
+func (d *MulticastRendezvousPointDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+ var config MulticastRendezvousPoint
+
+ // Read config
+ diags := req.Config.Get(ctx, &config)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.Id.String()))
+
+ var res gjson.Result
+ var err error
+
+ if !res.Exists() {
+ res, err = d.client.Get(config.getPath() + "/" + url.QueryEscape(config.Id.ValueString()))
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err))
+ return
+ }
+ }
+
+ config.fromBody(ctx, res)
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &config)
+ resp.Diagnostics.Append(diags...)
+}
+
+// End of section. //template:end read
diff --git a/internal/provider/data_source_meraki_multicast_rendezvous_point_test.go b/internal/provider/data_source_meraki_multicast_rendezvous_point_test.go
new file mode 100644
index 0000000..1b87bc5
--- /dev/null
+++ b/internal/provider/data_source_meraki_multicast_rendezvous_point_test.go
@@ -0,0 +1,83 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSource
+
+func TestAccDataSourceMerakiMulticastRendezvousPoint(t *testing.T) {
+ var checks []resource.TestCheckFunc
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_multicast_rendezvous_point.test", "interface_ip", "192.168.1.2"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_multicast_rendezvous_point.test", "multicast_group", "Any"))
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccDataSourceMerakiMulticastRendezvousPointPrerequisitesConfig + testAccDataSourceMerakiMulticastRendezvousPointConfig(),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ },
+ },
+ })
+}
+
+// End of section. //template:end testAccDataSource
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites
+
+const testAccDataSourceMerakiMulticastRendezvousPointPrerequisitesConfig = `
+data "meraki_organization" "test" {
+ name = "Dev"
+}
+resource "meraki_network" "test" {
+ organization_id = data.meraki_organization.test.id
+ name = "Network1"
+ product_types = ["switch", "wireless"]
+}
+
+`
+
+// End of section. //template:end testPrerequisites
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSourceConfig
+
+func testAccDataSourceMerakiMulticastRendezvousPointConfig() string {
+ config := `resource "meraki_multicast_rendezvous_point" "test" {` + "\n"
+ config += ` network_id = meraki_network.test.id` + "\n"
+ config += ` interface_ip = "192.168.1.2"` + "\n"
+ config += ` multicast_group = "Any"` + "\n"
+ config += `}` + "\n"
+
+ config += `
+ data "meraki_multicast_rendezvous_point" "test" {
+ id = meraki_multicast_rendezvous_point.test.id
+ network_id = meraki_network.test.id
+ }
+ `
+ return config
+}
+
+// End of section. //template:end testAccDataSourceConfig
diff --git a/internal/provider/data_source_meraki_switch_link_aggregation_test.go b/internal/provider/data_source_meraki_switch_link_aggregation_test.go
index 638ab17..a06aa1a 100644
--- a/internal/provider/data_source_meraki_switch_link_aggregation_test.go
+++ b/internal/provider/data_source_meraki_switch_link_aggregation_test.go
@@ -65,19 +65,15 @@ resource "meraki_network_device_claim" "test" {
// End of section. //template:end testPrerequisites
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSourceConfig
+
func testAccDataSourceMerakiSwitchLinkAggregationConfig() string {
config := `resource "meraki_switch_link_aggregation" "test" {` + "\n"
- config += ` network_id = meraki_network.test.id` + "\n"
- config += ` switch_ports = [` + "\n"
- config += ` {` + "\n"
- config += ` port_id = "1"` + "\n"
- config += ` serial = tolist(meraki_network_device_claim.test.serials)[0]` + "\n"
- config += ` },` + "\n"
- config += ` {` + "\n"
- config += ` port_id = "2"` + "\n"
- config += ` serial = tolist(meraki_network_device_claim.test.serials)[0]` + "\n"
- config += ` }` + "\n"
- config += ` ]` + "\n"
+ config += ` network_id = meraki_network.test.id` + "\n"
+ config += ` switch_ports = [{` + "\n"
+ config += ` port_id = "1"` + "\n"
+ config += ` serial = tolist(meraki_network_device_claim.test.serials)[0]` + "\n"
+ config += ` }]` + "\n"
config += `}` + "\n"
config += `
@@ -88,3 +84,5 @@ func testAccDataSourceMerakiSwitchLinkAggregationConfig() string {
`
return config
}
+
+// End of section. //template:end testAccDataSourceConfig
diff --git a/internal/provider/data_source_meraki_wireless_ssid.go b/internal/provider/data_source_meraki_wireless_ssid.go
new file mode 100644
index 0000000..801e1a0
--- /dev/null
+++ b/internal/provider/data_source_meraki_wireless_ssid.go
@@ -0,0 +1,580 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "context"
+ "fmt"
+
+ "github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/netascode/go-meraki"
+ "github.com/tidwall/gjson"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin model
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+ _ datasource.DataSource = &WirelessSSIDDataSource{}
+ _ datasource.DataSourceWithConfigure = &WirelessSSIDDataSource{}
+)
+
+func NewWirelessSSIDDataSource() datasource.DataSource {
+ return &WirelessSSIDDataSource{}
+}
+
+type WirelessSSIDDataSource struct {
+ client *meraki.Client
+}
+
+func (d *WirelessSSIDDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_wireless_ssid"
+}
+
+func (d *WirelessSSIDDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ // This description is used by the documentation generator and the language server.
+ MarkdownDescription: "This data source can read the `Wireless SSID` configuration.",
+
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The id of the object",
+ Optional: true,
+ Computed: true,
+ },
+ "network_id": schema.StringAttribute{
+ MarkdownDescription: "Network ID",
+ Required: true,
+ },
+ "number": schema.StringAttribute{
+ MarkdownDescription: "Wireless SSID number",
+ Required: true,
+ },
+ "adult_content_filtering_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Boolean indicating whether or not adult content will be blocked",
+ Computed: true,
+ },
+ "auth_mode": schema.StringAttribute{
+ MarkdownDescription: "The association control method for the SSID (`open`, `open-enhanced`, `psk`, `open-with-radius`, `open-with-nac`, `8021x-meraki`, `8021x-nac`, `8021x-radius`, `8021x-google`, `8021x-entra`, `8021x-localradius`, `ipsk-with-radius`, `ipsk-without-radius` or `ipsk-with-nac`)",
+ Computed: true,
+ },
+ "available_on_all_aps": schema.BoolAttribute{
+ MarkdownDescription: "Boolean indicating whether all APs should broadcast the SSID or if it should be restricted to APs matching any availability tags. Can only be false if the SSID has availability tags.",
+ Computed: true,
+ },
+ "band_selection": schema.StringAttribute{
+ MarkdownDescription: "The client-serving radio frequencies of this SSID in the default indoor RF profile. (`Dual band operation`, `5 GHz band only` or `Dual band operation with Band Steering`)",
+ Computed: true,
+ },
+ "concentrator_network_id": schema.StringAttribute{
+ MarkdownDescription: "The concentrator to use when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`.",
+ Computed: true,
+ },
+ "default_vlan_id": schema.Int64Attribute{
+ MarkdownDescription: "The default VLAN ID used for `all other APs`. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`",
+ Computed: true,
+ },
+ "disassociate_clients_on_vpn_failover": schema.BoolAttribute{
+ MarkdownDescription: "Disassociate clients when `VPN` concentrator failover occurs in order to trigger clients to re-associate and generate new DHCP requests. This param is only valid if ipAssignmentMode is `VPN`.",
+ Computed: true,
+ },
+ "enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not the SSID is enabled",
+ Computed: true,
+ },
+ "encryption_mode": schema.StringAttribute{
+ MarkdownDescription: "The psk encryption mode for the SSID (`wep` or `wpa`). This param is only valid if the authMode is `psk`",
+ Computed: true,
+ },
+ "enterprise_admin_access": schema.StringAttribute{
+ MarkdownDescription: "Whether or not an SSID is accessible by `enterprise` administrators (`access disabled` or `access enabled`)",
+ Computed: true,
+ },
+ "ip_assignment_mode": schema.StringAttribute{
+ MarkdownDescription: "The client IP assignment mode (`NAT mode`, `Bridge mode`, `Layer 3 roaming`, `Ethernet over GRE`, `Layer 3 roaming with a concentrator` or `VPN`)",
+ Computed: true,
+ },
+ "lan_isolation_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Boolean indicating whether Layer 2 LAN isolation should be enabled or disabled. Only configurable when ipAssignmentMode is `Bridge mode`.",
+ Computed: true,
+ },
+ "mandatory_dhcp_enabled": schema.BoolAttribute{
+ MarkdownDescription: "If true, Mandatory DHCP will enforce that clients connecting to this SSID must use the IP address assigned by the DHCP server. Clients who use a static IP address won`t be able to associate.",
+ Computed: true,
+ },
+ "min_bitrate": schema.Float64Attribute{
+ MarkdownDescription: "The minimum bitrate in Mbps of this SSID in the default indoor RF profile. (`1`, `2`, `5.5`, `6`, `9`, `11`, `12`, `18`, `24`, `36`, `48` or `54`)",
+ Computed: true,
+ },
+ "name": schema.StringAttribute{
+ MarkdownDescription: "The name of the SSID",
+ Optional: true,
+ Computed: true,
+ },
+ "per_client_bandwidth_limit_down": schema.Int64Attribute{
+ MarkdownDescription: "The download bandwidth limit in Kbps. (0 represents no limit.)",
+ Computed: true,
+ },
+ "per_client_bandwidth_limit_up": schema.Int64Attribute{
+ MarkdownDescription: "The upload bandwidth limit in Kbps. (0 represents no limit.)",
+ Computed: true,
+ },
+ "per_ssid_bandwidth_limit_down": schema.Int64Attribute{
+ MarkdownDescription: "The total download bandwidth limit in Kbps. (0 represents no limit.)",
+ Computed: true,
+ },
+ "per_ssid_bandwidth_limit_up": schema.Int64Attribute{
+ MarkdownDescription: "The total upload bandwidth limit in Kbps. (0 represents no limit.)",
+ Computed: true,
+ },
+ "psk": schema.StringAttribute{
+ MarkdownDescription: "The passkey for the SSID. This param is only valid if the authMode is `psk`",
+ Computed: true,
+ },
+ "radius_accounting_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not RADIUS accounting is enabled. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius`",
+ Computed: true,
+ },
+ "radius_accounting_interim_interval": schema.Int64Attribute{
+ MarkdownDescription: "The interval (in seconds) in which accounting information is updated and sent to the RADIUS accounting server.",
+ Computed: true,
+ },
+ "radius_attribute_for_group_policies": schema.StringAttribute{
+ MarkdownDescription: "Specify the RADIUS attribute used to look up group policies (`Filter-Id`, `Reply-Message`, `Airespace-ACL-Name` or `Aruba-User-Role`). Access points must receive this attribute in the RADIUS Access-Accept message",
+ Computed: true,
+ },
+ "radius_authentication_nas_id": schema.StringAttribute{
+ MarkdownDescription: "The template of the NAS identifier to be used for RADIUS authentication (ex. $NODE_MAC$:$VAP_NUM$).",
+ Computed: true,
+ },
+ "radius_called_station_id": schema.StringAttribute{
+ MarkdownDescription: "The template of the called station identifier to be used for RADIUS (ex. $NODE_MAC$:$VAP_NUM$).",
+ Computed: true,
+ },
+ "radius_coa_enabled": schema.BoolAttribute{
+ MarkdownDescription: "If true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server.",
+ Computed: true,
+ },
+ "radius_failover_policy": schema.StringAttribute{
+ MarkdownDescription: "This policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable (`Deny access` or `Allow access`)",
+ Computed: true,
+ },
+ "radius_fallback_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not higher priority RADIUS servers should be retried after 60 seconds.",
+ Computed: true,
+ },
+ "radius_guest_vlan_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not RADIUS Guest VLAN is enabled. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode",
+ Computed: true,
+ },
+ "radius_guest_vlan_id": schema.Int64Attribute{
+ MarkdownDescription: "VLAN ID of the RADIUS Guest VLAN. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode",
+ Computed: true,
+ },
+ "radius_load_balancing_policy": schema.StringAttribute{
+ MarkdownDescription: "This policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts (`Strict priority order` or `Round robin`)",
+ Computed: true,
+ },
+ "radius_override": schema.BoolAttribute{
+ MarkdownDescription: "If true, the RADIUS response can override VLAN tag. This is not valid when ipAssignmentMode is `NAT mode`.",
+ Computed: true,
+ },
+ "radius_proxy_enabled": schema.BoolAttribute{
+ MarkdownDescription: "If true, Meraki devices will proxy RADIUS messages through the Meraki cloud to the configured RADIUS auth and accounting servers.",
+ Computed: true,
+ },
+ "radius_server_attempts_limit": schema.Int64Attribute{
+ MarkdownDescription: "The maximum number of transmit attempts after which a RADIUS server is failed over (must be between 1-5).",
+ Computed: true,
+ },
+ "radius_server_timeout": schema.Int64Attribute{
+ MarkdownDescription: "The amount of time for which a RADIUS client waits for a reply from the RADIUS server (must be between 1-10 seconds).",
+ Computed: true,
+ },
+ "radius_testing_enabled": schema.BoolAttribute{
+ MarkdownDescription: "If true, Meraki devices will periodically send Access-Request messages to configured RADIUS servers using identity `meraki_8021x_test` to ensure that the RADIUS servers are reachable.",
+ Computed: true,
+ },
+ "secondary_concentrator_network_id": schema.StringAttribute{
+ MarkdownDescription: "The secondary concentrator to use when the ipAssignmentMode is `VPN`. If configured, the APs will switch to using this concentrator if the primary concentrator is unreachable. This param is optional. (`disabled` represents no secondary concentrator.)",
+ Computed: true,
+ },
+ "splash_page": schema.StringAttribute{
+ MarkdownDescription: "The type of splash page for the SSID (`None`, `Click-through splash page`, `Billing`, `Password-protected with Meraki RADIUS`, `Password-protected with custom RADIUS`, `Password-protected with Active Directory`, `Password-protected with LDAP`, `SMS authentication`, `Systems Manager Sentry`, `Facebook Wi-Fi`, `Google OAuth`, `Microsoft Entra ID`, `Sponsored guest`, `Cisco ISE` or `Google Apps domain`). This attribute is not supported for template children.",
+ Computed: true,
+ },
+ "use_vlan_tagging": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not traffic should be directed to use specific VLANs. This param is only valid if the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`",
+ Computed: true,
+ },
+ "visible": schema.BoolAttribute{
+ MarkdownDescription: "Boolean indicating whether APs should advertise or hide this SSID. APs will only broadcast this SSID if set to true",
+ Computed: true,
+ },
+ "vlan_id": schema.Int64Attribute{
+ MarkdownDescription: "The VLAN ID used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`",
+ Computed: true,
+ },
+ "walled_garden_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Allow access to a configurable list of IP ranges, which users may access prior to sign-on.",
+ Computed: true,
+ },
+ "wpa_encryption_mode": schema.StringAttribute{
+ MarkdownDescription: "The types of WPA encryption. (`WPA1 only`, `WPA1 and WPA2`, `WPA2 only`, `WPA3 Transition Mode`, `WPA3 only` or `WPA3 192-bit Security`)",
+ Computed: true,
+ },
+ "active_directory_credentials_logon_name": schema.StringAttribute{
+ MarkdownDescription: "The logon name of the Active Directory account.",
+ Computed: true,
+ },
+ "active_directory_credentials_password": schema.StringAttribute{
+ MarkdownDescription: "The password to the Active Directory user account.",
+ Computed: true,
+ },
+ "active_directory_servers": schema.ListNestedAttribute{
+ MarkdownDescription: "The Active Directory servers to be used for authentication.",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "host": schema.StringAttribute{
+ MarkdownDescription: "IP address (or FQDN) of your Active Directory server.",
+ Computed: true,
+ },
+ "port": schema.Int64Attribute{
+ MarkdownDescription: "(Optional) UDP port the Active Directory server listens on. By default, uses port 3268.",
+ Computed: true,
+ },
+ },
+ },
+ },
+ "dns_rewrite_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Boolean indicating whether or not DNS server rewrite is enabled. If disabled, upstream DNS will be used",
+ Computed: true,
+ },
+ "dns_rewrite_dns_custom_nameservers": schema.ListAttribute{
+ MarkdownDescription: "User specified DNS servers (up to two servers)",
+ ElementType: types.StringType,
+ Computed: true,
+ },
+ "dot11r_adaptive": schema.BoolAttribute{
+ MarkdownDescription: "(Optional) Whether 802.11r is adaptive or not.",
+ Computed: true,
+ },
+ "dot11r_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether 802.11r is enabled or not.",
+ Computed: true,
+ },
+ "dot11w_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether 802.11w is enabled or not.",
+ Computed: true,
+ },
+ "dot11w_required": schema.BoolAttribute{
+ MarkdownDescription: "(Optional) Whether 802.11w is required or not.",
+ Computed: true,
+ },
+ "gre_key": schema.Int64Attribute{
+ MarkdownDescription: "Optional numerical identifier that will add the GRE key field to the GRE header. Used to identify an individual traffic flow within a tunnel.",
+ Computed: true,
+ },
+ "gre_concentrator_host": schema.StringAttribute{
+ MarkdownDescription: "The EoGRE concentrator`s IP or FQDN. This param is required when ipAssignmentMode is `Ethernet over GRE`.",
+ Computed: true,
+ },
+ "ldap_base_distinguished_name": schema.StringAttribute{
+ MarkdownDescription: "The base distinguished name of users on the LDAP server.",
+ Computed: true,
+ },
+ "ldap_credentials_distinguished_name": schema.StringAttribute{
+ MarkdownDescription: "The distinguished name of the LDAP user account (example: cn=user,dc=meraki,dc=com).",
+ Computed: true,
+ },
+ "ldap_credentials_password": schema.StringAttribute{
+ MarkdownDescription: "The password of the LDAP user account.",
+ Computed: true,
+ },
+ "ldap_server_ca_certificate_contents": schema.StringAttribute{
+ MarkdownDescription: "The contents of the CA certificate. Must be in PEM or DER format.",
+ Computed: true,
+ },
+ "ldap_servers": schema.ListNestedAttribute{
+ MarkdownDescription: "The LDAP servers to be used for authentication.",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "host": schema.StringAttribute{
+ MarkdownDescription: "IP address (or FQDN) of your LDAP server.",
+ Computed: true,
+ },
+ "port": schema.Int64Attribute{
+ MarkdownDescription: "UDP port the LDAP server listens on.",
+ Computed: true,
+ },
+ },
+ },
+ },
+ "local_radius_cache_timeout": schema.Int64Attribute{
+ MarkdownDescription: "The duration (in seconds) for which LDAP and OCSP lookups are cached.",
+ Computed: true,
+ },
+ "local_radius_certificate_authentication_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not to use EAP-TLS certificate-based authentication to validate wireless clients.",
+ Computed: true,
+ },
+ "local_radius_certificate_authentication_ocsp_responder_url": schema.StringAttribute{
+ MarkdownDescription: "(Optional) The URL of the OCSP responder to verify client certificate status.",
+ Computed: true,
+ },
+ "local_radius_certificate_authentication_use_ldap": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not to verify the certificate with LDAP.",
+ Computed: true,
+ },
+ "local_radius_certificate_authentication_use_ocsp": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not to verify the certificate with OCSP.",
+ Computed: true,
+ },
+ "local_radius_certificate_authentication_client_root_ca_certificate_contents": schema.StringAttribute{
+ MarkdownDescription: "The contents of the Client CA Certificate. Must be in PEM or DER format.",
+ Computed: true,
+ },
+ "local_radius_password_authentication_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not to use EAP-TTLS/PAP or PEAP-GTC password-based authentication via LDAP lookup.",
+ Computed: true,
+ },
+ "named_vlans_radius_guest_vlan_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not RADIUS guest named VLAN is enabled.",
+ Computed: true,
+ },
+ "named_vlans_radius_guest_vlan_name": schema.StringAttribute{
+ MarkdownDescription: "RADIUS guest VLAN name.",
+ Optional: true,
+ Computed: true,
+ },
+ "named_vlans_tagging_default_vlan_name": schema.StringAttribute{
+ MarkdownDescription: "The default VLAN name used to tag traffic in the absence of a matching AP tag.",
+ Computed: true,
+ },
+ "named_vlans_tagging_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Whether or not traffic should be directed to use specific VLAN names.",
+ Computed: true,
+ },
+ "named_vlans_tagging_by_ap_tags": schema.ListNestedAttribute{
+ MarkdownDescription: "The list of AP tags and VLAN names used for named VLAN tagging. If an AP has a tag matching one in the list, then traffic on this SSID will be directed to use the VLAN name associated to the tag.",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "vlan_name": schema.StringAttribute{
+ MarkdownDescription: "VLAN name that will be used to tag traffic.",
+ Computed: true,
+ },
+ "tags": schema.ListAttribute{
+ MarkdownDescription: "List of AP tags.",
+ ElementType: types.StringType,
+ Computed: true,
+ },
+ },
+ },
+ },
+ "oauth_allowed_domains": schema.ListAttribute{
+ MarkdownDescription: "(Optional) The list of domains allowed access to the network.",
+ ElementType: types.StringType,
+ Computed: true,
+ },
+ "speed_burst_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Boolean indicating whether or not to allow users to temporarily exceed the bandwidth limit for short periods while still keeping them under the bandwidth limit over time.",
+ Computed: true,
+ },
+ "ap_tags_and_vlan_ids": schema.ListNestedAttribute{
+ MarkdownDescription: "The list of tags and VLAN IDs used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "vlan_id": schema.Int64Attribute{
+ MarkdownDescription: "Numerical identifier that is assigned to the VLAN",
+ Computed: true,
+ },
+ "tags": schema.ListAttribute{
+ MarkdownDescription: "Array of AP tags",
+ ElementType: types.StringType,
+ Computed: true,
+ },
+ },
+ },
+ },
+ "availability_tags": schema.ListAttribute{
+ MarkdownDescription: "Accepts a list of tags for this SSID. If availableOnAllAps is false, then the SSID will only be broadcast by APs with tags matching any of the tags in this list.",
+ ElementType: types.StringType,
+ Computed: true,
+ },
+ "radius_accounting_servers": schema.ListNestedAttribute{
+ MarkdownDescription: "The RADIUS accounting 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius` and radiusAccountingEnabled is `true`",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "ca_certificate": schema.StringAttribute{
+ MarkdownDescription: "Certificate used for authorization for the RADSEC Server",
+ Computed: true,
+ },
+ "host": schema.StringAttribute{
+ MarkdownDescription: "IP address (or FQDN) to which the APs will send RADIUS accounting messages",
+ Computed: true,
+ },
+ "port": schema.Int64Attribute{
+ MarkdownDescription: "Port on the RADIUS server that is listening for accounting messages",
+ Computed: true,
+ },
+ "radsec_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Use RADSEC (TLS over TCP) to connect to this RADIUS accounting server. Requires radiusProxyEnabled.",
+ Computed: true,
+ },
+ "secret": schema.StringAttribute{
+ MarkdownDescription: "Shared key used to authenticate messages between the APs and RADIUS server",
+ Computed: true,
+ },
+ },
+ },
+ },
+ "radius_servers": schema.ListNestedAttribute{
+ MarkdownDescription: "The RADIUS 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius`",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "ca_certificate": schema.StringAttribute{
+ MarkdownDescription: "Certificate used for authorization for the RADSEC Server",
+ Computed: true,
+ },
+ "host": schema.StringAttribute{
+ MarkdownDescription: "IP address (or FQDN) of your RADIUS server",
+ Computed: true,
+ },
+ "open_roaming_certificate_id": schema.Int64Attribute{
+ MarkdownDescription: "The ID of the Openroaming Certificate attached to radius server.",
+ Computed: true,
+ },
+ "port": schema.Int64Attribute{
+ MarkdownDescription: "UDP port the RADIUS server listens on for Access-requests",
+ Computed: true,
+ },
+ "radsec_enabled": schema.BoolAttribute{
+ MarkdownDescription: "Use RADSEC (TLS over TCP) to connect to this RADIUS server. Requires radiusProxyEnabled.",
+ Computed: true,
+ },
+ "secret": schema.StringAttribute{
+ MarkdownDescription: "RADIUS client shared secret",
+ Computed: true,
+ },
+ },
+ },
+ },
+ "splash_guest_sponsor_domains": schema.ListAttribute{
+ MarkdownDescription: "Array of valid sponsor email domains for sponsored guest splash type.",
+ ElementType: types.StringType,
+ Computed: true,
+ },
+ "walled_garden_ranges": schema.ListAttribute{
+ MarkdownDescription: "Specify your walled garden by entering an array of addresses, ranges using CIDR notation, domain names, and domain wildcards (e.g. `192.168.1.1/24`, `192.168.37.10/32`, `www.yahoo.com`, `*.google.com`]). Meraki`s splash page is automatically included in your walled garden.",
+ ElementType: types.StringType,
+ Computed: true,
+ },
+ },
+ }
+}
+func (d *WirelessSSIDDataSource) ConfigValidators(ctx context.Context) []datasource.ConfigValidator {
+ return []datasource.ConfigValidator{
+ datasourcevalidator.ExactlyOneOf(
+ path.MatchRoot("id"),
+ path.MatchRoot("name"),
+ ),
+ }
+}
+
+func (d *WirelessSSIDDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ d.client = req.ProviderData.(*MerakiProviderData).Client
+}
+
+// End of section. //template:end model
+
+// Section below is generated&owned by "gen/generator.go". //template:begin read
+
+func (d *WirelessSSIDDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+ var config WirelessSSID
+
+ // Read config
+ diags := req.Config.Get(ctx, &config)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.Id.String()))
+
+ var res gjson.Result
+ var err error
+ if config.Id.IsNull() && !config.Name.IsNull() {
+ res, err = d.client.Get(config.getPath())
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve objects, got error: %s", err))
+ return
+ }
+ if len(res.Array()) > 0 {
+ res.ForEach(func(k, v gjson.Result) bool {
+ if config.Name.ValueString() == v.Get("name").String() {
+ config.Id = types.StringValue(v.Get("id").String())
+ tflog.Debug(ctx, fmt.Sprintf("%s: Found object with name '%v', id: %v", config.Id.String(), config.Name.ValueString(), config.Id.String()))
+ res = v
+ return false
+ }
+ return true
+ })
+ }
+
+ if config.Id.IsNull() {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to find object with name: %s", config.Name.ValueString()))
+ return
+ }
+ }
+
+ if !res.Exists() {
+ res, err = d.client.Get(config.getPath())
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object, got error: %s", err))
+ return
+ }
+ }
+
+ config.fromBody(ctx, res)
+ config.Id = config.Number
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &config)
+ resp.Diagnostics.Append(diags...)
+}
+
+// End of section. //template:end read
diff --git a/internal/provider/data_source_meraki_wireless_ssid_test.go b/internal/provider/data_source_meraki_wireless_ssid_test.go
new file mode 100644
index 0000000..37a8e43
--- /dev/null
+++ b/internal/provider/data_source_meraki_wireless_ssid_test.go
@@ -0,0 +1,305 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSource
+
+func TestAccDataSourceMerakiWirelessSSID(t *testing.T) {
+ var checks []resource.TestCheckFunc
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "number", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "adult_content_filtering_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "auth_mode", "8021x-radius"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "available_on_all_aps", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "band_selection", "5 GHz band only"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "default_vlan_id", "1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "disassociate_clients_on_vpn_failover", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "encryption_mode", "wpa"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "ip_assignment_mode", "Bridge mode"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "lan_isolation_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "mandatory_dhcp_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "min_bitrate", "5.5"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "name", "My SSID"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "per_client_bandwidth_limit_down", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "per_client_bandwidth_limit_up", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "per_ssid_bandwidth_limit_down", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "per_ssid_bandwidth_limit_up", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "psk", "deadbeef"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_accounting_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_accounting_interim_interval", "5"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_attribute_for_group_policies", "Filter-Id"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_authentication_nas_id", "00-11-22-33-44-55:AP1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_called_station_id", "00-11-22-33-44-55:AP1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_coa_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_failover_policy", "Deny access"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_fallback_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_guest_vlan_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_guest_vlan_id", "1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_load_balancing_policy", "Round robin"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_override", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_proxy_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_server_attempts_limit", "5"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_server_timeout", "5"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_testing_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "secondary_concentrator_network_id", "disabled"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "splash_page", "Click-through splash page"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "use_vlan_tagging", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "visible", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "vlan_id", "10"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "walled_garden_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "wpa_encryption_mode", "WPA2 only"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "dot11r_adaptive", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "dot11r_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "dot11w_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "dot11w_required", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "gre_key", "5"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "gre_concentrator_host", "192.168.1.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "local_radius_cache_timeout", "60"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "local_radius_certificate_authentication_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "local_radius_certificate_authentication_ocsp_responder_url", "http://ocsp-server.example.com"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "local_radius_certificate_authentication_use_ldap", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "local_radius_certificate_authentication_use_ocsp", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "local_radius_certificate_authentication_client_root_ca_certificate_contents", "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "local_radius_password_authentication_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "named_vlans_radius_guest_vlan_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "named_vlans_tagging_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "speed_burst_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "ap_tags_and_vlan_ids.0.vlan_id", "100"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "ap_tags_and_vlan_ids.0.tags.0", "tag1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "availability_tags.0", "tag1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_servers.0.ca_certificate", "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_servers.0.host", "0.0.0.0"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_servers.0.port", "3000"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_servers.0.radsec_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.meraki_wireless_ssid.test", "radius_servers.0.secret", "secret-string"))
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccDataSourceMerakiWirelessSSIDPrerequisitesConfig + testAccDataSourceMerakiWirelessSSIDConfig(),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ },
+ {
+ Config: testAccDataSourceMerakiWirelessSSIDPrerequisitesConfig + testAccNamedDataSourceMerakiWirelessSSIDConfig(),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ },
+ },
+ })
+}
+
+// End of section. //template:end testAccDataSource
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites
+
+const testAccDataSourceMerakiWirelessSSIDPrerequisitesConfig = `
+data "meraki_organization" "test" {
+ name = "Dev"
+}
+resource "meraki_network" "test" {
+ organization_id = data.meraki_organization.test.id
+ name = "Network1"
+ product_types = ["switch", "wireless"]
+}
+
+`
+
+// End of section. //template:end testPrerequisites
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccDataSourceConfig
+
+func testAccDataSourceMerakiWirelessSSIDConfig() string {
+ config := `resource "meraki_wireless_ssid" "test" {` + "\n"
+ config += ` network_id = meraki_network.test.id` + "\n"
+ config += ` number = "0"` + "\n"
+ config += ` adult_content_filtering_enabled = false` + "\n"
+ config += ` auth_mode = "8021x-radius"` + "\n"
+ config += ` available_on_all_aps = false` + "\n"
+ config += ` band_selection = "5 GHz band only"` + "\n"
+ config += ` default_vlan_id = 1` + "\n"
+ config += ` disassociate_clients_on_vpn_failover = false` + "\n"
+ config += ` enabled = false` + "\n"
+ config += ` encryption_mode = "wpa"` + "\n"
+ config += ` ip_assignment_mode = "Bridge mode"` + "\n"
+ config += ` lan_isolation_enabled = false` + "\n"
+ config += ` mandatory_dhcp_enabled = false` + "\n"
+ config += ` min_bitrate = 5.5` + "\n"
+ config += ` name = "My SSID"` + "\n"
+ config += ` per_client_bandwidth_limit_down = 0` + "\n"
+ config += ` per_client_bandwidth_limit_up = 0` + "\n"
+ config += ` per_ssid_bandwidth_limit_down = 0` + "\n"
+ config += ` per_ssid_bandwidth_limit_up = 0` + "\n"
+ config += ` psk = "deadbeef"` + "\n"
+ config += ` radius_accounting_enabled = false` + "\n"
+ config += ` radius_accounting_interim_interval = 5` + "\n"
+ config += ` radius_attribute_for_group_policies = "Filter-Id"` + "\n"
+ config += ` radius_authentication_nas_id = "00-11-22-33-44-55:AP1"` + "\n"
+ config += ` radius_called_station_id = "00-11-22-33-44-55:AP1"` + "\n"
+ config += ` radius_coa_enabled = false` + "\n"
+ config += ` radius_failover_policy = "Deny access"` + "\n"
+ config += ` radius_fallback_enabled = false` + "\n"
+ config += ` radius_guest_vlan_enabled = false` + "\n"
+ config += ` radius_guest_vlan_id = 1` + "\n"
+ config += ` radius_load_balancing_policy = "Round robin"` + "\n"
+ config += ` radius_override = false` + "\n"
+ config += ` radius_proxy_enabled = false` + "\n"
+ config += ` radius_server_attempts_limit = 5` + "\n"
+ config += ` radius_server_timeout = 5` + "\n"
+ config += ` radius_testing_enabled = false` + "\n"
+ config += ` secondary_concentrator_network_id = "disabled"` + "\n"
+ config += ` splash_page = "Click-through splash page"` + "\n"
+ config += ` use_vlan_tagging = false` + "\n"
+ config += ` visible = false` + "\n"
+ config += ` vlan_id = 10` + "\n"
+ config += ` walled_garden_enabled = false` + "\n"
+ config += ` wpa_encryption_mode = "WPA2 only"` + "\n"
+ config += ` dot11r_adaptive = false` + "\n"
+ config += ` dot11r_enabled = false` + "\n"
+ config += ` dot11w_enabled = false` + "\n"
+ config += ` dot11w_required = false` + "\n"
+ config += ` gre_key = 5` + "\n"
+ config += ` gre_concentrator_host = "192.168.1.1"` + "\n"
+ config += ` local_radius_cache_timeout = 60` + "\n"
+ config += ` local_radius_certificate_authentication_enabled = false` + "\n"
+ config += ` local_radius_certificate_authentication_ocsp_responder_url = "http://ocsp-server.example.com"` + "\n"
+ config += ` local_radius_certificate_authentication_use_ldap = false` + "\n"
+ config += ` local_radius_certificate_authentication_use_ocsp = false` + "\n"
+ config += ` local_radius_certificate_authentication_client_root_ca_certificate_contents = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"` + "\n"
+ config += ` local_radius_password_authentication_enabled = false` + "\n"
+ config += ` named_vlans_radius_guest_vlan_enabled = false` + "\n"
+ config += ` named_vlans_tagging_enabled = false` + "\n"
+ config += ` speed_burst_enabled = false` + "\n"
+ config += ` ap_tags_and_vlan_ids = [{` + "\n"
+ config += ` vlan_id = 100` + "\n"
+ config += ` tags = ["tag1"]` + "\n"
+ config += ` }]` + "\n"
+ config += ` availability_tags = ["tag1"]` + "\n"
+ config += ` radius_servers = [{` + "\n"
+ config += ` ca_certificate = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"` + "\n"
+ config += ` host = "0.0.0.0"` + "\n"
+ config += ` port = 3000` + "\n"
+ config += ` radsec_enabled = false` + "\n"
+ config += ` secret = "secret-string"` + "\n"
+ config += ` }]` + "\n"
+ config += `}` + "\n"
+
+ config += `
+ data "meraki_wireless_ssid" "test" {
+ network_id = meraki_network.test.id
+ number = "0"
+ depends_on = [meraki_wireless_ssid.test]
+ }
+ `
+ return config
+}
+
+func testAccNamedDataSourceMerakiWirelessSSIDConfig() string {
+ config := `resource "meraki_wireless_ssid" "test" {` + "\n"
+ config += ` network_id = meraki_network.test.id` + "\n"
+ config += ` number = "0"` + "\n"
+ config += ` adult_content_filtering_enabled = false` + "\n"
+ config += ` auth_mode = "8021x-radius"` + "\n"
+ config += ` available_on_all_aps = false` + "\n"
+ config += ` band_selection = "5 GHz band only"` + "\n"
+ config += ` default_vlan_id = 1` + "\n"
+ config += ` disassociate_clients_on_vpn_failover = false` + "\n"
+ config += ` enabled = false` + "\n"
+ config += ` encryption_mode = "wpa"` + "\n"
+ config += ` ip_assignment_mode = "Bridge mode"` + "\n"
+ config += ` lan_isolation_enabled = false` + "\n"
+ config += ` mandatory_dhcp_enabled = false` + "\n"
+ config += ` min_bitrate = 5.5` + "\n"
+ config += ` name = "My SSID"` + "\n"
+ config += ` per_client_bandwidth_limit_down = 0` + "\n"
+ config += ` per_client_bandwidth_limit_up = 0` + "\n"
+ config += ` per_ssid_bandwidth_limit_down = 0` + "\n"
+ config += ` per_ssid_bandwidth_limit_up = 0` + "\n"
+ config += ` psk = "deadbeef"` + "\n"
+ config += ` radius_accounting_enabled = false` + "\n"
+ config += ` radius_accounting_interim_interval = 5` + "\n"
+ config += ` radius_attribute_for_group_policies = "Filter-Id"` + "\n"
+ config += ` radius_authentication_nas_id = "00-11-22-33-44-55:AP1"` + "\n"
+ config += ` radius_called_station_id = "00-11-22-33-44-55:AP1"` + "\n"
+ config += ` radius_coa_enabled = false` + "\n"
+ config += ` radius_failover_policy = "Deny access"` + "\n"
+ config += ` radius_fallback_enabled = false` + "\n"
+ config += ` radius_guest_vlan_enabled = false` + "\n"
+ config += ` radius_guest_vlan_id = 1` + "\n"
+ config += ` radius_load_balancing_policy = "Round robin"` + "\n"
+ config += ` radius_override = false` + "\n"
+ config += ` radius_proxy_enabled = false` + "\n"
+ config += ` radius_server_attempts_limit = 5` + "\n"
+ config += ` radius_server_timeout = 5` + "\n"
+ config += ` radius_testing_enabled = false` + "\n"
+ config += ` secondary_concentrator_network_id = "disabled"` + "\n"
+ config += ` splash_page = "Click-through splash page"` + "\n"
+ config += ` use_vlan_tagging = false` + "\n"
+ config += ` visible = false` + "\n"
+ config += ` vlan_id = 10` + "\n"
+ config += ` walled_garden_enabled = false` + "\n"
+ config += ` wpa_encryption_mode = "WPA2 only"` + "\n"
+ config += ` dot11r_adaptive = false` + "\n"
+ config += ` dot11r_enabled = false` + "\n"
+ config += ` dot11w_enabled = false` + "\n"
+ config += ` dot11w_required = false` + "\n"
+ config += ` gre_key = 5` + "\n"
+ config += ` gre_concentrator_host = "192.168.1.1"` + "\n"
+ config += ` local_radius_cache_timeout = 60` + "\n"
+ config += ` local_radius_certificate_authentication_enabled = false` + "\n"
+ config += ` local_radius_certificate_authentication_ocsp_responder_url = "http://ocsp-server.example.com"` + "\n"
+ config += ` local_radius_certificate_authentication_use_ldap = false` + "\n"
+ config += ` local_radius_certificate_authentication_use_ocsp = false` + "\n"
+ config += ` local_radius_certificate_authentication_client_root_ca_certificate_contents = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"` + "\n"
+ config += ` local_radius_password_authentication_enabled = false` + "\n"
+ config += ` named_vlans_radius_guest_vlan_enabled = false` + "\n"
+ config += ` named_vlans_tagging_enabled = false` + "\n"
+ config += ` speed_burst_enabled = false` + "\n"
+ config += ` ap_tags_and_vlan_ids = [{` + "\n"
+ config += ` vlan_id = 100` + "\n"
+ config += ` tags = ["tag1"]` + "\n"
+ config += ` }]` + "\n"
+ config += ` availability_tags = ["tag1"]` + "\n"
+ config += ` radius_servers = [{` + "\n"
+ config += ` ca_certificate = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"` + "\n"
+ config += ` host = "0.0.0.0"` + "\n"
+ config += ` port = 3000` + "\n"
+ config += ` radsec_enabled = false` + "\n"
+ config += ` secret = "secret-string"` + "\n"
+ config += ` }]` + "\n"
+ config += `}` + "\n"
+
+ config += `
+ data "meraki_wireless_ssid" "test" {
+ name = meraki_wireless_ssid.test.name
+ network_id = meraki_network.test.id
+ number = "0"
+ }
+ `
+ return config
+}
+
+// End of section. //template:end testAccDataSourceConfig
diff --git a/internal/provider/model_meraki_multicast_rendezvous_point.go b/internal/provider/model_meraki_multicast_rendezvous_point.go
new file mode 100644
index 0000000..d75aaa0
--- /dev/null
+++ b/internal/provider/model_meraki_multicast_rendezvous_point.go
@@ -0,0 +1,103 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "context"
+ "fmt"
+ "net/url"
+
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/tidwall/gjson"
+ "github.com/tidwall/sjson"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin types
+
+type MulticastRendezvousPoint struct {
+ Id types.String `tfsdk:"id"`
+ NetworkId types.String `tfsdk:"network_id"`
+ InterfaceIp types.String `tfsdk:"interface_ip"`
+ MulticastGroup types.String `tfsdk:"multicast_group"`
+}
+
+// End of section. //template:end types
+
+// Section below is generated&owned by "gen/generator.go". //template:begin getPath
+
+func (data MulticastRendezvousPoint) getPath() string {
+ return fmt.Sprintf("/networks/%v/switch/routing/multicast/rendezvousPoints", url.QueryEscape(data.NetworkId.ValueString()))
+}
+
+// End of section. //template:end getPath
+
+// Section below is generated&owned by "gen/generator.go". //template:begin toBody
+
+func (data MulticastRendezvousPoint) toBody(ctx context.Context, state MulticastRendezvousPoint) string {
+ body := ""
+ if !data.InterfaceIp.IsNull() {
+ body, _ = sjson.Set(body, "interfaceIp", data.InterfaceIp.ValueString())
+ }
+ if !data.MulticastGroup.IsNull() {
+ body, _ = sjson.Set(body, "multicastGroup", data.MulticastGroup.ValueString())
+ }
+ return body
+}
+
+// End of section. //template:end toBody
+
+// Section below is generated&owned by "gen/generator.go". //template:begin fromBody
+
+func (data *MulticastRendezvousPoint) fromBody(ctx context.Context, res gjson.Result) {
+ if value := res.Get("interfaceIp"); value.Exists() {
+ data.InterfaceIp = types.StringValue(value.String())
+ } else {
+ data.InterfaceIp = types.StringNull()
+ }
+ if value := res.Get("multicastGroup"); value.Exists() {
+ data.MulticastGroup = types.StringValue(value.String())
+ } else {
+ data.MulticastGroup = types.StringNull()
+ }
+}
+
+// End of section. //template:end fromBody
+
+// Section below is generated&owned by "gen/generator.go". //template:begin fromBodyPartial
+
+// fromBodyPartial reads values from a gjson.Result into a tfstate model. It ignores null attributes in order to
+// uncouple the provider from the exact values that the backend API might summon to replace nulls. (Such behavior might
+// easily change across versions of the backend API.) For List/Set/Map attributes, the func only updates the
+// "managed" elements, instead of all elements.
+func (data *MulticastRendezvousPoint) fromBodyPartial(ctx context.Context, res gjson.Result) {
+ if value := res.Get("interfaceIp"); value.Exists() && !data.InterfaceIp.IsNull() {
+ data.InterfaceIp = types.StringValue(value.String())
+ } else {
+ data.InterfaceIp = types.StringNull()
+ }
+ if value := res.Get("multicastGroup"); value.Exists() && !data.MulticastGroup.IsNull() {
+ data.MulticastGroup = types.StringValue(value.String())
+ } else {
+ data.MulticastGroup = types.StringNull()
+ }
+}
+
+// End of section. //template:end fromBodyPartial
diff --git a/internal/provider/model_meraki_network_device_claim.go b/internal/provider/model_meraki_network_device_claim.go
index 6680690..2161aff 100644
--- a/internal/provider/model_meraki_network_device_claim.go
+++ b/internal/provider/model_meraki_network_device_claim.go
@@ -49,14 +49,6 @@ func (data NetworkDeviceClaim) getPath() string {
// End of section. //template:end getPath
-func (data NetworkDeviceClaim) getRemovePath() string {
- return fmt.Sprintf("/networks/%v/devices/remove", url.QueryEscape(data.NetworkId.ValueString()))
-}
-
-func (data NetworkDeviceClaim) getDevicesPath() string {
- return fmt.Sprintf("/networks/%v/devices", url.QueryEscape(data.NetworkId.ValueString()))
-}
-
// Section below is generated&owned by "gen/generator.go". //template:begin toBody
func (data NetworkDeviceClaim) toBody(ctx context.Context, state NetworkDeviceClaim) string {
diff --git a/internal/provider/model_meraki_organization_inventory_claim.go b/internal/provider/model_meraki_organization_inventory_claim.go
index 4ba3a2e..45317ba 100644
--- a/internal/provider/model_meraki_organization_inventory_claim.go
+++ b/internal/provider/model_meraki_organization_inventory_claim.go
@@ -49,14 +49,6 @@ func (data OrganizationInventoryClaim) getPath() string {
// End of section. //template:end getPath
-func (data OrganizationInventoryClaim) getReleasePath() string {
- return fmt.Sprintf("/organizations/%v/inventory/release", url.QueryEscape(data.OrganizationId.ValueString()))
-}
-
-func (data OrganizationInventoryClaim) getDevicesPath() string {
- return fmt.Sprintf("/organizations/%v/inventory/devices", url.QueryEscape(data.OrganizationId.ValueString()))
-}
-
// Section below is generated&owned by "gen/generator.go". //template:begin toBody
func (data OrganizationInventoryClaim) toBody(ctx context.Context, state OrganizationInventoryClaim) string {
diff --git a/internal/provider/model_meraki_wireless_ssid.go b/internal/provider/model_meraki_wireless_ssid.go
new file mode 100644
index 0000000..6598201
--- /dev/null
+++ b/internal/provider/model_meraki_wireless_ssid.go
@@ -0,0 +1,1730 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "context"
+ "fmt"
+ "net/url"
+ "slices"
+ "strconv"
+
+ "github.com/CiscoDevNet/terraform-provider-meraki/internal/provider/helpers"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/tidwall/gjson"
+ "github.com/tidwall/sjson"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin types
+
+type WirelessSSID struct {
+ Id types.String `tfsdk:"id"`
+ NetworkId types.String `tfsdk:"network_id"`
+ Number types.String `tfsdk:"number"`
+ AdultContentFilteringEnabled types.Bool `tfsdk:"adult_content_filtering_enabled"`
+ AuthMode types.String `tfsdk:"auth_mode"`
+ AvailableOnAllAps types.Bool `tfsdk:"available_on_all_aps"`
+ BandSelection types.String `tfsdk:"band_selection"`
+ ConcentratorNetworkId types.String `tfsdk:"concentrator_network_id"`
+ DefaultVlanId types.Int64 `tfsdk:"default_vlan_id"`
+ DisassociateClientsOnVpnFailover types.Bool `tfsdk:"disassociate_clients_on_vpn_failover"`
+ Enabled types.Bool `tfsdk:"enabled"`
+ EncryptionMode types.String `tfsdk:"encryption_mode"`
+ EnterpriseAdminAccess types.String `tfsdk:"enterprise_admin_access"`
+ IpAssignmentMode types.String `tfsdk:"ip_assignment_mode"`
+ LanIsolationEnabled types.Bool `tfsdk:"lan_isolation_enabled"`
+ MandatoryDhcpEnabled types.Bool `tfsdk:"mandatory_dhcp_enabled"`
+ MinBitrate types.Float64 `tfsdk:"min_bitrate"`
+ Name types.String `tfsdk:"name"`
+ PerClientBandwidthLimitDown types.Int64 `tfsdk:"per_client_bandwidth_limit_down"`
+ PerClientBandwidthLimitUp types.Int64 `tfsdk:"per_client_bandwidth_limit_up"`
+ PerSsidBandwidthLimitDown types.Int64 `tfsdk:"per_ssid_bandwidth_limit_down"`
+ PerSsidBandwidthLimitUp types.Int64 `tfsdk:"per_ssid_bandwidth_limit_up"`
+ Psk types.String `tfsdk:"psk"`
+ RadiusAccountingEnabled types.Bool `tfsdk:"radius_accounting_enabled"`
+ RadiusAccountingInterimInterval types.Int64 `tfsdk:"radius_accounting_interim_interval"`
+ RadiusAttributeForGroupPolicies types.String `tfsdk:"radius_attribute_for_group_policies"`
+ RadiusAuthenticationNasId types.String `tfsdk:"radius_authentication_nas_id"`
+ RadiusCalledStationId types.String `tfsdk:"radius_called_station_id"`
+ RadiusCoaEnabled types.Bool `tfsdk:"radius_coa_enabled"`
+ RadiusFailoverPolicy types.String `tfsdk:"radius_failover_policy"`
+ RadiusFallbackEnabled types.Bool `tfsdk:"radius_fallback_enabled"`
+ RadiusGuestVlanEnabled types.Bool `tfsdk:"radius_guest_vlan_enabled"`
+ RadiusGuestVlanId types.Int64 `tfsdk:"radius_guest_vlan_id"`
+ RadiusLoadBalancingPolicy types.String `tfsdk:"radius_load_balancing_policy"`
+ RadiusOverride types.Bool `tfsdk:"radius_override"`
+ RadiusProxyEnabled types.Bool `tfsdk:"radius_proxy_enabled"`
+ RadiusServerAttemptsLimit types.Int64 `tfsdk:"radius_server_attempts_limit"`
+ RadiusServerTimeout types.Int64 `tfsdk:"radius_server_timeout"`
+ RadiusTestingEnabled types.Bool `tfsdk:"radius_testing_enabled"`
+ SecondaryConcentratorNetworkId types.String `tfsdk:"secondary_concentrator_network_id"`
+ SplashPage types.String `tfsdk:"splash_page"`
+ UseVlanTagging types.Bool `tfsdk:"use_vlan_tagging"`
+ Visible types.Bool `tfsdk:"visible"`
+ VlanId types.Int64 `tfsdk:"vlan_id"`
+ WalledGardenEnabled types.Bool `tfsdk:"walled_garden_enabled"`
+ WpaEncryptionMode types.String `tfsdk:"wpa_encryption_mode"`
+ ActiveDirectoryCredentialsLogonName types.String `tfsdk:"active_directory_credentials_logon_name"`
+ ActiveDirectoryCredentialsPassword types.String `tfsdk:"active_directory_credentials_password"`
+ ActiveDirectoryServers []WirelessSSIDActiveDirectoryServers `tfsdk:"active_directory_servers"`
+ DnsRewriteEnabled types.Bool `tfsdk:"dns_rewrite_enabled"`
+ DnsRewriteDnsCustomNameservers types.List `tfsdk:"dns_rewrite_dns_custom_nameservers"`
+ Dot11rAdaptive types.Bool `tfsdk:"dot11r_adaptive"`
+ Dot11rEnabled types.Bool `tfsdk:"dot11r_enabled"`
+ Dot11wEnabled types.Bool `tfsdk:"dot11w_enabled"`
+ Dot11wRequired types.Bool `tfsdk:"dot11w_required"`
+ GreKey types.Int64 `tfsdk:"gre_key"`
+ GreConcentratorHost types.String `tfsdk:"gre_concentrator_host"`
+ LdapBaseDistinguishedName types.String `tfsdk:"ldap_base_distinguished_name"`
+ LdapCredentialsDistinguishedName types.String `tfsdk:"ldap_credentials_distinguished_name"`
+ LdapCredentialsPassword types.String `tfsdk:"ldap_credentials_password"`
+ LdapServerCaCertificateContents types.String `tfsdk:"ldap_server_ca_certificate_contents"`
+ LdapServers []WirelessSSIDLdapServers `tfsdk:"ldap_servers"`
+ LocalRadiusCacheTimeout types.Int64 `tfsdk:"local_radius_cache_timeout"`
+ LocalRadiusCertificateAuthenticationEnabled types.Bool `tfsdk:"local_radius_certificate_authentication_enabled"`
+ LocalRadiusCertificateAuthenticationOcspResponderUrl types.String `tfsdk:"local_radius_certificate_authentication_ocsp_responder_url"`
+ LocalRadiusCertificateAuthenticationUseLdap types.Bool `tfsdk:"local_radius_certificate_authentication_use_ldap"`
+ LocalRadiusCertificateAuthenticationUseOcsp types.Bool `tfsdk:"local_radius_certificate_authentication_use_ocsp"`
+ LocalRadiusCertificateAuthenticationClientRootCaCertificateContents types.String `tfsdk:"local_radius_certificate_authentication_client_root_ca_certificate_contents"`
+ LocalRadiusPasswordAuthenticationEnabled types.Bool `tfsdk:"local_radius_password_authentication_enabled"`
+ NamedVlansRadiusGuestVlanEnabled types.Bool `tfsdk:"named_vlans_radius_guest_vlan_enabled"`
+ NamedVlansRadiusGuestVlanName types.String `tfsdk:"named_vlans_radius_guest_vlan_name"`
+ NamedVlansTaggingDefaultVlanName types.String `tfsdk:"named_vlans_tagging_default_vlan_name"`
+ NamedVlansTaggingEnabled types.Bool `tfsdk:"named_vlans_tagging_enabled"`
+ NamedVlansTaggingByApTags []WirelessSSIDNamedVlansTaggingByApTags `tfsdk:"named_vlans_tagging_by_ap_tags"`
+ OauthAllowedDomains types.List `tfsdk:"oauth_allowed_domains"`
+ SpeedBurstEnabled types.Bool `tfsdk:"speed_burst_enabled"`
+ ApTagsAndVlanIds []WirelessSSIDApTagsAndVlanIds `tfsdk:"ap_tags_and_vlan_ids"`
+ AvailabilityTags types.List `tfsdk:"availability_tags"`
+ RadiusAccountingServers []WirelessSSIDRadiusAccountingServers `tfsdk:"radius_accounting_servers"`
+ RadiusServers []WirelessSSIDRadiusServers `tfsdk:"radius_servers"`
+ SplashGuestSponsorDomains types.List `tfsdk:"splash_guest_sponsor_domains"`
+ WalledGardenRanges types.List `tfsdk:"walled_garden_ranges"`
+}
+
+type WirelessSSIDActiveDirectoryServers struct {
+ Host types.String `tfsdk:"host"`
+ Port types.Int64 `tfsdk:"port"`
+}
+
+type WirelessSSIDLdapServers struct {
+ Host types.String `tfsdk:"host"`
+ Port types.Int64 `tfsdk:"port"`
+}
+
+type WirelessSSIDNamedVlansTaggingByApTags struct {
+ VlanName types.String `tfsdk:"vlan_name"`
+ Tags types.List `tfsdk:"tags"`
+}
+
+type WirelessSSIDApTagsAndVlanIds struct {
+ VlanId types.Int64 `tfsdk:"vlan_id"`
+ Tags types.List `tfsdk:"tags"`
+}
+
+type WirelessSSIDRadiusAccountingServers struct {
+ CaCertificate types.String `tfsdk:"ca_certificate"`
+ Host types.String `tfsdk:"host"`
+ Port types.Int64 `tfsdk:"port"`
+ RadsecEnabled types.Bool `tfsdk:"radsec_enabled"`
+ Secret types.String `tfsdk:"secret"`
+}
+
+type WirelessSSIDRadiusServers struct {
+ CaCertificate types.String `tfsdk:"ca_certificate"`
+ Host types.String `tfsdk:"host"`
+ OpenRoamingCertificateId types.Int64 `tfsdk:"open_roaming_certificate_id"`
+ Port types.Int64 `tfsdk:"port"`
+ RadsecEnabled types.Bool `tfsdk:"radsec_enabled"`
+ Secret types.String `tfsdk:"secret"`
+}
+
+// End of section. //template:end types
+
+// Section below is generated&owned by "gen/generator.go". //template:begin getPath
+
+func (data WirelessSSID) getPath() string {
+ return fmt.Sprintf("/networks/%v/wireless/ssids/%v", url.QueryEscape(data.NetworkId.ValueString()), url.QueryEscape(data.Number.ValueString()))
+}
+
+// End of section. //template:end getPath
+
+// Section below is generated&owned by "gen/generator.go". //template:begin toBody
+
+func (data WirelessSSID) toBody(ctx context.Context, state WirelessSSID) string {
+ body := ""
+ if !data.AdultContentFilteringEnabled.IsNull() {
+ body, _ = sjson.Set(body, "adultContentFilteringEnabled", data.AdultContentFilteringEnabled.ValueBool())
+ }
+ if !data.AuthMode.IsNull() {
+ body, _ = sjson.Set(body, "authMode", data.AuthMode.ValueString())
+ }
+ if !data.AvailableOnAllAps.IsNull() {
+ body, _ = sjson.Set(body, "availableOnAllAps", data.AvailableOnAllAps.ValueBool())
+ }
+ if !data.BandSelection.IsNull() {
+ body, _ = sjson.Set(body, "bandSelection", data.BandSelection.ValueString())
+ }
+ if !data.ConcentratorNetworkId.IsNull() {
+ body, _ = sjson.Set(body, "concentratorNetworkId", data.ConcentratorNetworkId.ValueString())
+ }
+ if !data.DefaultVlanId.IsNull() {
+ body, _ = sjson.Set(body, "defaultVlanId", data.DefaultVlanId.ValueInt64())
+ }
+ if !data.DisassociateClientsOnVpnFailover.IsNull() {
+ body, _ = sjson.Set(body, "disassociateClientsOnVpnFailover", data.DisassociateClientsOnVpnFailover.ValueBool())
+ }
+ if !data.Enabled.IsNull() {
+ body, _ = sjson.Set(body, "enabled", data.Enabled.ValueBool())
+ }
+ if !data.EncryptionMode.IsNull() {
+ body, _ = sjson.Set(body, "encryptionMode", data.EncryptionMode.ValueString())
+ }
+ if !data.EnterpriseAdminAccess.IsNull() {
+ body, _ = sjson.Set(body, "enterpriseAdminAccess", data.EnterpriseAdminAccess.ValueString())
+ }
+ if !data.IpAssignmentMode.IsNull() {
+ body, _ = sjson.Set(body, "ipAssignmentMode", data.IpAssignmentMode.ValueString())
+ }
+ if !data.LanIsolationEnabled.IsNull() {
+ body, _ = sjson.Set(body, "lanIsolationEnabled", data.LanIsolationEnabled.ValueBool())
+ }
+ if !data.MandatoryDhcpEnabled.IsNull() {
+ body, _ = sjson.Set(body, "mandatoryDhcpEnabled", data.MandatoryDhcpEnabled.ValueBool())
+ }
+ if !data.MinBitrate.IsNull() {
+ body, _ = sjson.Set(body, "minBitrate", data.MinBitrate.ValueFloat64())
+ }
+ if !data.Name.IsNull() {
+ body, _ = sjson.Set(body, "name", data.Name.ValueString())
+ }
+ if !data.PerClientBandwidthLimitDown.IsNull() {
+ body, _ = sjson.Set(body, "perClientBandwidthLimitDown", data.PerClientBandwidthLimitDown.ValueInt64())
+ }
+ if !data.PerClientBandwidthLimitUp.IsNull() {
+ body, _ = sjson.Set(body, "perClientBandwidthLimitUp", data.PerClientBandwidthLimitUp.ValueInt64())
+ }
+ if !data.PerSsidBandwidthLimitDown.IsNull() {
+ body, _ = sjson.Set(body, "perSsidBandwidthLimitDown", data.PerSsidBandwidthLimitDown.ValueInt64())
+ }
+ if !data.PerSsidBandwidthLimitUp.IsNull() {
+ body, _ = sjson.Set(body, "perSsidBandwidthLimitUp", data.PerSsidBandwidthLimitUp.ValueInt64())
+ }
+ if !data.Psk.IsNull() {
+ body, _ = sjson.Set(body, "psk", data.Psk.ValueString())
+ }
+ if !data.RadiusAccountingEnabled.IsNull() {
+ body, _ = sjson.Set(body, "radiusAccountingEnabled", data.RadiusAccountingEnabled.ValueBool())
+ }
+ if !data.RadiusAccountingInterimInterval.IsNull() {
+ body, _ = sjson.Set(body, "radiusAccountingInterimInterval", data.RadiusAccountingInterimInterval.ValueInt64())
+ }
+ if !data.RadiusAttributeForGroupPolicies.IsNull() {
+ body, _ = sjson.Set(body, "radiusAttributeForGroupPolicies", data.RadiusAttributeForGroupPolicies.ValueString())
+ }
+ if !data.RadiusAuthenticationNasId.IsNull() {
+ body, _ = sjson.Set(body, "radiusAuthenticationNasId", data.RadiusAuthenticationNasId.ValueString())
+ }
+ if !data.RadiusCalledStationId.IsNull() {
+ body, _ = sjson.Set(body, "radiusCalledStationId", data.RadiusCalledStationId.ValueString())
+ }
+ if !data.RadiusCoaEnabled.IsNull() {
+ body, _ = sjson.Set(body, "radiusCoaEnabled", data.RadiusCoaEnabled.ValueBool())
+ }
+ if !data.RadiusFailoverPolicy.IsNull() {
+ body, _ = sjson.Set(body, "radiusFailoverPolicy", data.RadiusFailoverPolicy.ValueString())
+ }
+ if !data.RadiusFallbackEnabled.IsNull() {
+ body, _ = sjson.Set(body, "radiusFallbackEnabled", data.RadiusFallbackEnabled.ValueBool())
+ }
+ if !data.RadiusGuestVlanEnabled.IsNull() {
+ body, _ = sjson.Set(body, "radiusGuestVlanEnabled", data.RadiusGuestVlanEnabled.ValueBool())
+ }
+ if !data.RadiusGuestVlanId.IsNull() {
+ body, _ = sjson.Set(body, "radiusGuestVlanId", data.RadiusGuestVlanId.ValueInt64())
+ }
+ if !data.RadiusLoadBalancingPolicy.IsNull() {
+ body, _ = sjson.Set(body, "radiusLoadBalancingPolicy", data.RadiusLoadBalancingPolicy.ValueString())
+ }
+ if !data.RadiusOverride.IsNull() {
+ body, _ = sjson.Set(body, "radiusOverride", data.RadiusOverride.ValueBool())
+ }
+ if !data.RadiusProxyEnabled.IsNull() {
+ body, _ = sjson.Set(body, "radiusProxyEnabled", data.RadiusProxyEnabled.ValueBool())
+ }
+ if !data.RadiusServerAttemptsLimit.IsNull() {
+ body, _ = sjson.Set(body, "radiusServerAttemptsLimit", data.RadiusServerAttemptsLimit.ValueInt64())
+ }
+ if !data.RadiusServerTimeout.IsNull() {
+ body, _ = sjson.Set(body, "radiusServerTimeout", data.RadiusServerTimeout.ValueInt64())
+ }
+ if !data.RadiusTestingEnabled.IsNull() {
+ body, _ = sjson.Set(body, "radiusTestingEnabled", data.RadiusTestingEnabled.ValueBool())
+ }
+ if !data.SecondaryConcentratorNetworkId.IsNull() {
+ body, _ = sjson.Set(body, "secondaryConcentratorNetworkId", data.SecondaryConcentratorNetworkId.ValueString())
+ }
+ if !data.SplashPage.IsNull() {
+ body, _ = sjson.Set(body, "splashPage", data.SplashPage.ValueString())
+ }
+ if !data.UseVlanTagging.IsNull() {
+ body, _ = sjson.Set(body, "useVlanTagging", data.UseVlanTagging.ValueBool())
+ }
+ if !data.Visible.IsNull() {
+ body, _ = sjson.Set(body, "visible", data.Visible.ValueBool())
+ }
+ if !data.VlanId.IsNull() {
+ body, _ = sjson.Set(body, "vlanId", data.VlanId.ValueInt64())
+ }
+ if !data.WalledGardenEnabled.IsNull() {
+ body, _ = sjson.Set(body, "walledGardenEnabled", data.WalledGardenEnabled.ValueBool())
+ }
+ if !data.WpaEncryptionMode.IsNull() {
+ body, _ = sjson.Set(body, "wpaEncryptionMode", data.WpaEncryptionMode.ValueString())
+ }
+ if !data.ActiveDirectoryCredentialsLogonName.IsNull() {
+ body, _ = sjson.Set(body, "activeDirectory.credentials.logonName", data.ActiveDirectoryCredentialsLogonName.ValueString())
+ }
+ if !data.ActiveDirectoryCredentialsPassword.IsNull() {
+ body, _ = sjson.Set(body, "activeDirectory.credentials.password", data.ActiveDirectoryCredentialsPassword.ValueString())
+ }
+ if len(data.ActiveDirectoryServers) > 0 {
+ body, _ = sjson.Set(body, "activeDirectory.servers", []interface{}{})
+ for _, item := range data.ActiveDirectoryServers {
+ itemBody := ""
+ if !item.Host.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "host", item.Host.ValueString())
+ }
+ if !item.Port.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "port", item.Port.ValueInt64())
+ }
+ body, _ = sjson.SetRaw(body, "activeDirectory.servers.-1", itemBody)
+ }
+ }
+ if !data.DnsRewriteEnabled.IsNull() {
+ body, _ = sjson.Set(body, "dnsRewrite.enabled", data.DnsRewriteEnabled.ValueBool())
+ }
+ if !data.DnsRewriteDnsCustomNameservers.IsNull() {
+ var values []string
+ data.DnsRewriteDnsCustomNameservers.ElementsAs(ctx, &values, false)
+ body, _ = sjson.Set(body, "dnsRewrite.dnsCustomNameservers", values)
+ }
+ if !data.Dot11rAdaptive.IsNull() {
+ body, _ = sjson.Set(body, "dot11r.adaptive", data.Dot11rAdaptive.ValueBool())
+ }
+ if !data.Dot11rEnabled.IsNull() {
+ body, _ = sjson.Set(body, "dot11r.enabled", data.Dot11rEnabled.ValueBool())
+ }
+ if !data.Dot11wEnabled.IsNull() {
+ body, _ = sjson.Set(body, "dot11w.enabled", data.Dot11wEnabled.ValueBool())
+ }
+ if !data.Dot11wRequired.IsNull() {
+ body, _ = sjson.Set(body, "dot11w.required", data.Dot11wRequired.ValueBool())
+ }
+ if !data.GreKey.IsNull() {
+ body, _ = sjson.Set(body, "gre.key", data.GreKey.ValueInt64())
+ }
+ if !data.GreConcentratorHost.IsNull() {
+ body, _ = sjson.Set(body, "gre.concentrator.host", data.GreConcentratorHost.ValueString())
+ }
+ if !data.LdapBaseDistinguishedName.IsNull() {
+ body, _ = sjson.Set(body, "ldap.baseDistinguishedName", data.LdapBaseDistinguishedName.ValueString())
+ }
+ if !data.LdapCredentialsDistinguishedName.IsNull() {
+ body, _ = sjson.Set(body, "ldap.credentials.distinguishedName", data.LdapCredentialsDistinguishedName.ValueString())
+ }
+ if !data.LdapCredentialsPassword.IsNull() {
+ body, _ = sjson.Set(body, "ldap.credentials.password", data.LdapCredentialsPassword.ValueString())
+ }
+ if !data.LdapServerCaCertificateContents.IsNull() {
+ body, _ = sjson.Set(body, "ldap.serverCaCertificate.contents", data.LdapServerCaCertificateContents.ValueString())
+ }
+ if len(data.LdapServers) > 0 {
+ body, _ = sjson.Set(body, "ldap.servers", []interface{}{})
+ for _, item := range data.LdapServers {
+ itemBody := ""
+ if !item.Host.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "host", item.Host.ValueString())
+ }
+ if !item.Port.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "port", item.Port.ValueInt64())
+ }
+ body, _ = sjson.SetRaw(body, "ldap.servers.-1", itemBody)
+ }
+ }
+ if !data.LocalRadiusCacheTimeout.IsNull() {
+ body, _ = sjson.Set(body, "localRadius.cacheTimeout", data.LocalRadiusCacheTimeout.ValueInt64())
+ }
+ if !data.LocalRadiusCertificateAuthenticationEnabled.IsNull() {
+ body, _ = sjson.Set(body, "localRadius.certificateAuthentication.enabled", data.LocalRadiusCertificateAuthenticationEnabled.ValueBool())
+ }
+ if !data.LocalRadiusCertificateAuthenticationOcspResponderUrl.IsNull() {
+ body, _ = sjson.Set(body, "localRadius.certificateAuthentication.ocspResponderUrl", data.LocalRadiusCertificateAuthenticationOcspResponderUrl.ValueString())
+ }
+ if !data.LocalRadiusCertificateAuthenticationUseLdap.IsNull() {
+ body, _ = sjson.Set(body, "localRadius.certificateAuthentication.useLdap", data.LocalRadiusCertificateAuthenticationUseLdap.ValueBool())
+ }
+ if !data.LocalRadiusCertificateAuthenticationUseOcsp.IsNull() {
+ body, _ = sjson.Set(body, "localRadius.certificateAuthentication.useOcsp", data.LocalRadiusCertificateAuthenticationUseOcsp.ValueBool())
+ }
+ if !data.LocalRadiusCertificateAuthenticationClientRootCaCertificateContents.IsNull() {
+ body, _ = sjson.Set(body, "localRadius.certificateAuthentication.clientRootCaCertificate.contents", data.LocalRadiusCertificateAuthenticationClientRootCaCertificateContents.ValueString())
+ }
+ if !data.LocalRadiusPasswordAuthenticationEnabled.IsNull() {
+ body, _ = sjson.Set(body, "localRadius.passwordAuthentication.enabled", data.LocalRadiusPasswordAuthenticationEnabled.ValueBool())
+ }
+ if !data.NamedVlansRadiusGuestVlanEnabled.IsNull() {
+ body, _ = sjson.Set(body, "namedVlans.radius.guestVlan.enabled", data.NamedVlansRadiusGuestVlanEnabled.ValueBool())
+ }
+ if !data.NamedVlansRadiusGuestVlanName.IsNull() {
+ body, _ = sjson.Set(body, "namedVlans.radius.guestVlan.name", data.NamedVlansRadiusGuestVlanName.ValueString())
+ }
+ if !data.NamedVlansTaggingDefaultVlanName.IsNull() {
+ body, _ = sjson.Set(body, "namedVlans.tagging.defaultVlanName", data.NamedVlansTaggingDefaultVlanName.ValueString())
+ }
+ if !data.NamedVlansTaggingEnabled.IsNull() {
+ body, _ = sjson.Set(body, "namedVlans.tagging.enabled", data.NamedVlansTaggingEnabled.ValueBool())
+ }
+ if len(data.NamedVlansTaggingByApTags) > 0 {
+ body, _ = sjson.Set(body, "namedVlans.tagging.byApTags", []interface{}{})
+ for _, item := range data.NamedVlansTaggingByApTags {
+ itemBody := ""
+ if !item.VlanName.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "vlanName", item.VlanName.ValueString())
+ }
+ if !item.Tags.IsNull() {
+ var values []string
+ item.Tags.ElementsAs(ctx, &values, false)
+ itemBody, _ = sjson.Set(itemBody, "tags", values)
+ }
+ body, _ = sjson.SetRaw(body, "namedVlans.tagging.byApTags.-1", itemBody)
+ }
+ }
+ if !data.OauthAllowedDomains.IsNull() {
+ var values []string
+ data.OauthAllowedDomains.ElementsAs(ctx, &values, false)
+ body, _ = sjson.Set(body, "oauth.allowedDomains", values)
+ }
+ if !data.SpeedBurstEnabled.IsNull() {
+ body, _ = sjson.Set(body, "speedBurst.enabled", data.SpeedBurstEnabled.ValueBool())
+ }
+ if len(data.ApTagsAndVlanIds) > 0 {
+ body, _ = sjson.Set(body, "apTagsAndVlanIds", []interface{}{})
+ for _, item := range data.ApTagsAndVlanIds {
+ itemBody := ""
+ if !item.VlanId.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "vlanId", item.VlanId.ValueInt64())
+ }
+ if !item.Tags.IsNull() {
+ var values []string
+ item.Tags.ElementsAs(ctx, &values, false)
+ itemBody, _ = sjson.Set(itemBody, "tags", values)
+ }
+ body, _ = sjson.SetRaw(body, "apTagsAndVlanIds.-1", itemBody)
+ }
+ }
+ if !data.AvailabilityTags.IsNull() {
+ var values []string
+ data.AvailabilityTags.ElementsAs(ctx, &values, false)
+ body, _ = sjson.Set(body, "availabilityTags", values)
+ }
+ if len(data.RadiusAccountingServers) > 0 {
+ body, _ = sjson.Set(body, "radiusAccountingServers", []interface{}{})
+ for _, item := range data.RadiusAccountingServers {
+ itemBody := ""
+ if !item.CaCertificate.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "caCertificate", item.CaCertificate.ValueString())
+ }
+ if !item.Host.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "host", item.Host.ValueString())
+ }
+ if !item.Port.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "port", item.Port.ValueInt64())
+ }
+ if !item.RadsecEnabled.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "radsecEnabled", item.RadsecEnabled.ValueBool())
+ }
+ if !item.Secret.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "secret", item.Secret.ValueString())
+ }
+ body, _ = sjson.SetRaw(body, "radiusAccountingServers.-1", itemBody)
+ }
+ }
+ if len(data.RadiusServers) > 0 {
+ body, _ = sjson.Set(body, "radiusServers", []interface{}{})
+ for _, item := range data.RadiusServers {
+ itemBody := ""
+ if !item.CaCertificate.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "caCertificate", item.CaCertificate.ValueString())
+ }
+ if !item.Host.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "host", item.Host.ValueString())
+ }
+ if !item.OpenRoamingCertificateId.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "openRoamingCertificateId", item.OpenRoamingCertificateId.ValueInt64())
+ }
+ if !item.Port.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "port", item.Port.ValueInt64())
+ }
+ if !item.RadsecEnabled.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "radsecEnabled", item.RadsecEnabled.ValueBool())
+ }
+ if !item.Secret.IsNull() {
+ itemBody, _ = sjson.Set(itemBody, "secret", item.Secret.ValueString())
+ }
+ body, _ = sjson.SetRaw(body, "radiusServers.-1", itemBody)
+ }
+ }
+ if !data.SplashGuestSponsorDomains.IsNull() {
+ var values []string
+ data.SplashGuestSponsorDomains.ElementsAs(ctx, &values, false)
+ body, _ = sjson.Set(body, "splashGuestSponsorDomains", values)
+ }
+ if !data.WalledGardenRanges.IsNull() {
+ var values []string
+ data.WalledGardenRanges.ElementsAs(ctx, &values, false)
+ body, _ = sjson.Set(body, "walledGardenRanges", values)
+ }
+ return body
+}
+
+// End of section. //template:end toBody
+
+// Section below is generated&owned by "gen/generator.go". //template:begin fromBody
+
+func (data *WirelessSSID) fromBody(ctx context.Context, res gjson.Result) {
+ if value := res.Get("adultContentFilteringEnabled"); value.Exists() {
+ data.AdultContentFilteringEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.AdultContentFilteringEnabled = types.BoolNull()
+ }
+ if value := res.Get("authMode"); value.Exists() {
+ data.AuthMode = types.StringValue(value.String())
+ } else {
+ data.AuthMode = types.StringNull()
+ }
+ if value := res.Get("availableOnAllAps"); value.Exists() {
+ data.AvailableOnAllAps = types.BoolValue(value.Bool())
+ } else {
+ data.AvailableOnAllAps = types.BoolNull()
+ }
+ if value := res.Get("bandSelection"); value.Exists() {
+ data.BandSelection = types.StringValue(value.String())
+ } else {
+ data.BandSelection = types.StringNull()
+ }
+ if value := res.Get("concentratorNetworkId"); value.Exists() {
+ data.ConcentratorNetworkId = types.StringValue(value.String())
+ } else {
+ data.ConcentratorNetworkId = types.StringNull()
+ }
+ if value := res.Get("defaultVlanId"); value.Exists() {
+ data.DefaultVlanId = types.Int64Value(value.Int())
+ } else {
+ data.DefaultVlanId = types.Int64Null()
+ }
+ if value := res.Get("disassociateClientsOnVpnFailover"); value.Exists() {
+ data.DisassociateClientsOnVpnFailover = types.BoolValue(value.Bool())
+ } else {
+ data.DisassociateClientsOnVpnFailover = types.BoolNull()
+ }
+ if value := res.Get("enabled"); value.Exists() {
+ data.Enabled = types.BoolValue(value.Bool())
+ } else {
+ data.Enabled = types.BoolNull()
+ }
+ if value := res.Get("encryptionMode"); value.Exists() {
+ data.EncryptionMode = types.StringValue(value.String())
+ } else {
+ data.EncryptionMode = types.StringNull()
+ }
+ if value := res.Get("enterpriseAdminAccess"); value.Exists() {
+ data.EnterpriseAdminAccess = types.StringValue(value.String())
+ } else {
+ data.EnterpriseAdminAccess = types.StringNull()
+ }
+ if value := res.Get("ipAssignmentMode"); value.Exists() {
+ data.IpAssignmentMode = types.StringValue(value.String())
+ } else {
+ data.IpAssignmentMode = types.StringNull()
+ }
+ if value := res.Get("lanIsolationEnabled"); value.Exists() {
+ data.LanIsolationEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.LanIsolationEnabled = types.BoolNull()
+ }
+ if value := res.Get("mandatoryDhcpEnabled"); value.Exists() {
+ data.MandatoryDhcpEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.MandatoryDhcpEnabled = types.BoolNull()
+ }
+ if value := res.Get("minBitrate"); value.Exists() {
+ data.MinBitrate = types.Float64Value(value.Float())
+ } else {
+ data.MinBitrate = types.Float64Null()
+ }
+ if value := res.Get("name"); value.Exists() {
+ data.Name = types.StringValue(value.String())
+ } else {
+ data.Name = types.StringNull()
+ }
+ if value := res.Get("perClientBandwidthLimitDown"); value.Exists() {
+ data.PerClientBandwidthLimitDown = types.Int64Value(value.Int())
+ } else {
+ data.PerClientBandwidthLimitDown = types.Int64Null()
+ }
+ if value := res.Get("perClientBandwidthLimitUp"); value.Exists() {
+ data.PerClientBandwidthLimitUp = types.Int64Value(value.Int())
+ } else {
+ data.PerClientBandwidthLimitUp = types.Int64Null()
+ }
+ if value := res.Get("perSsidBandwidthLimitDown"); value.Exists() {
+ data.PerSsidBandwidthLimitDown = types.Int64Value(value.Int())
+ } else {
+ data.PerSsidBandwidthLimitDown = types.Int64Null()
+ }
+ if value := res.Get("perSsidBandwidthLimitUp"); value.Exists() {
+ data.PerSsidBandwidthLimitUp = types.Int64Value(value.Int())
+ } else {
+ data.PerSsidBandwidthLimitUp = types.Int64Null()
+ }
+ if value := res.Get("psk"); value.Exists() {
+ data.Psk = types.StringValue(value.String())
+ } else {
+ data.Psk = types.StringNull()
+ }
+ if value := res.Get("radiusAccountingEnabled"); value.Exists() {
+ data.RadiusAccountingEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusAccountingEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusAccountingInterimInterval"); value.Exists() {
+ data.RadiusAccountingInterimInterval = types.Int64Value(value.Int())
+ } else {
+ data.RadiusAccountingInterimInterval = types.Int64Null()
+ }
+ if value := res.Get("radiusAttributeForGroupPolicies"); value.Exists() {
+ data.RadiusAttributeForGroupPolicies = types.StringValue(value.String())
+ } else {
+ data.RadiusAttributeForGroupPolicies = types.StringNull()
+ }
+ if value := res.Get("radiusAuthenticationNasId"); value.Exists() {
+ data.RadiusAuthenticationNasId = types.StringValue(value.String())
+ } else {
+ data.RadiusAuthenticationNasId = types.StringNull()
+ }
+ if value := res.Get("radiusCalledStationId"); value.Exists() {
+ data.RadiusCalledStationId = types.StringValue(value.String())
+ } else {
+ data.RadiusCalledStationId = types.StringNull()
+ }
+ if value := res.Get("radiusCoaEnabled"); value.Exists() {
+ data.RadiusCoaEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusCoaEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusFailoverPolicy"); value.Exists() {
+ data.RadiusFailoverPolicy = types.StringValue(value.String())
+ } else {
+ data.RadiusFailoverPolicy = types.StringNull()
+ }
+ if value := res.Get("radiusFallbackEnabled"); value.Exists() {
+ data.RadiusFallbackEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusFallbackEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusGuestVlanEnabled"); value.Exists() {
+ data.RadiusGuestVlanEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusGuestVlanEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusGuestVlanId"); value.Exists() {
+ data.RadiusGuestVlanId = types.Int64Value(value.Int())
+ } else {
+ data.RadiusGuestVlanId = types.Int64Null()
+ }
+ if value := res.Get("radiusLoadBalancingPolicy"); value.Exists() {
+ data.RadiusLoadBalancingPolicy = types.StringValue(value.String())
+ } else {
+ data.RadiusLoadBalancingPolicy = types.StringNull()
+ }
+ if value := res.Get("radiusOverride"); value.Exists() {
+ data.RadiusOverride = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusOverride = types.BoolNull()
+ }
+ if value := res.Get("radiusProxyEnabled"); value.Exists() {
+ data.RadiusProxyEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusProxyEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusServerAttemptsLimit"); value.Exists() {
+ data.RadiusServerAttemptsLimit = types.Int64Value(value.Int())
+ } else {
+ data.RadiusServerAttemptsLimit = types.Int64Null()
+ }
+ if value := res.Get("radiusServerTimeout"); value.Exists() {
+ data.RadiusServerTimeout = types.Int64Value(value.Int())
+ } else {
+ data.RadiusServerTimeout = types.Int64Null()
+ }
+ if value := res.Get("radiusTestingEnabled"); value.Exists() {
+ data.RadiusTestingEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusTestingEnabled = types.BoolNull()
+ }
+ if value := res.Get("secondaryConcentratorNetworkId"); value.Exists() {
+ data.SecondaryConcentratorNetworkId = types.StringValue(value.String())
+ } else {
+ data.SecondaryConcentratorNetworkId = types.StringNull()
+ }
+ if value := res.Get("splashPage"); value.Exists() {
+ data.SplashPage = types.StringValue(value.String())
+ } else {
+ data.SplashPage = types.StringNull()
+ }
+ if value := res.Get("useVlanTagging"); value.Exists() {
+ data.UseVlanTagging = types.BoolValue(value.Bool())
+ } else {
+ data.UseVlanTagging = types.BoolNull()
+ }
+ if value := res.Get("visible"); value.Exists() {
+ data.Visible = types.BoolValue(value.Bool())
+ } else {
+ data.Visible = types.BoolNull()
+ }
+ if value := res.Get("vlanId"); value.Exists() {
+ data.VlanId = types.Int64Value(value.Int())
+ } else {
+ data.VlanId = types.Int64Null()
+ }
+ if value := res.Get("walledGardenEnabled"); value.Exists() {
+ data.WalledGardenEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.WalledGardenEnabled = types.BoolNull()
+ }
+ if value := res.Get("wpaEncryptionMode"); value.Exists() {
+ data.WpaEncryptionMode = types.StringValue(value.String())
+ } else {
+ data.WpaEncryptionMode = types.StringNull()
+ }
+ if value := res.Get("activeDirectory.credentials.logonName"); value.Exists() {
+ data.ActiveDirectoryCredentialsLogonName = types.StringValue(value.String())
+ } else {
+ data.ActiveDirectoryCredentialsLogonName = types.StringNull()
+ }
+ if value := res.Get("activeDirectory.credentials.password"); value.Exists() {
+ data.ActiveDirectoryCredentialsPassword = types.StringValue(value.String())
+ } else {
+ data.ActiveDirectoryCredentialsPassword = types.StringNull()
+ }
+ if value := res.Get("activeDirectory.servers"); value.Exists() {
+ data.ActiveDirectoryServers = make([]WirelessSSIDActiveDirectoryServers, 0)
+ value.ForEach(func(k, res gjson.Result) bool {
+ parent := &data
+ data := WirelessSSIDActiveDirectoryServers{}
+ if value := res.Get("host"); value.Exists() {
+ data.Host = types.StringValue(value.String())
+ } else {
+ data.Host = types.StringNull()
+ }
+ if value := res.Get("port"); value.Exists() {
+ data.Port = types.Int64Value(value.Int())
+ } else {
+ data.Port = types.Int64Null()
+ }
+ (*parent).ActiveDirectoryServers = append((*parent).ActiveDirectoryServers, data)
+ return true
+ })
+ }
+ if value := res.Get("dnsRewrite.enabled"); value.Exists() {
+ data.DnsRewriteEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.DnsRewriteEnabled = types.BoolNull()
+ }
+ if value := res.Get("dnsRewrite.dnsCustomNameservers"); value.Exists() {
+ data.DnsRewriteDnsCustomNameservers = helpers.GetStringList(value.Array())
+ } else {
+ data.DnsRewriteDnsCustomNameservers = types.ListNull(types.StringType)
+ }
+ if value := res.Get("dot11r.adaptive"); value.Exists() {
+ data.Dot11rAdaptive = types.BoolValue(value.Bool())
+ } else {
+ data.Dot11rAdaptive = types.BoolNull()
+ }
+ if value := res.Get("dot11r.enabled"); value.Exists() {
+ data.Dot11rEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.Dot11rEnabled = types.BoolNull()
+ }
+ if value := res.Get("dot11w.enabled"); value.Exists() {
+ data.Dot11wEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.Dot11wEnabled = types.BoolNull()
+ }
+ if value := res.Get("dot11w.required"); value.Exists() {
+ data.Dot11wRequired = types.BoolValue(value.Bool())
+ } else {
+ data.Dot11wRequired = types.BoolNull()
+ }
+ if value := res.Get("gre.key"); value.Exists() {
+ data.GreKey = types.Int64Value(value.Int())
+ } else {
+ data.GreKey = types.Int64Null()
+ }
+ if value := res.Get("gre.concentrator.host"); value.Exists() {
+ data.GreConcentratorHost = types.StringValue(value.String())
+ } else {
+ data.GreConcentratorHost = types.StringNull()
+ }
+ if value := res.Get("ldap.baseDistinguishedName"); value.Exists() {
+ data.LdapBaseDistinguishedName = types.StringValue(value.String())
+ } else {
+ data.LdapBaseDistinguishedName = types.StringNull()
+ }
+ if value := res.Get("ldap.credentials.distinguishedName"); value.Exists() {
+ data.LdapCredentialsDistinguishedName = types.StringValue(value.String())
+ } else {
+ data.LdapCredentialsDistinguishedName = types.StringNull()
+ }
+ if value := res.Get("ldap.credentials.password"); value.Exists() {
+ data.LdapCredentialsPassword = types.StringValue(value.String())
+ } else {
+ data.LdapCredentialsPassword = types.StringNull()
+ }
+ if value := res.Get("ldap.serverCaCertificate.contents"); value.Exists() {
+ data.LdapServerCaCertificateContents = types.StringValue(value.String())
+ } else {
+ data.LdapServerCaCertificateContents = types.StringNull()
+ }
+ if value := res.Get("ldap.servers"); value.Exists() {
+ data.LdapServers = make([]WirelessSSIDLdapServers, 0)
+ value.ForEach(func(k, res gjson.Result) bool {
+ parent := &data
+ data := WirelessSSIDLdapServers{}
+ if value := res.Get("host"); value.Exists() {
+ data.Host = types.StringValue(value.String())
+ } else {
+ data.Host = types.StringNull()
+ }
+ if value := res.Get("port"); value.Exists() {
+ data.Port = types.Int64Value(value.Int())
+ } else {
+ data.Port = types.Int64Null()
+ }
+ (*parent).LdapServers = append((*parent).LdapServers, data)
+ return true
+ })
+ }
+ if value := res.Get("localRadius.cacheTimeout"); value.Exists() {
+ data.LocalRadiusCacheTimeout = types.Int64Value(value.Int())
+ } else {
+ data.LocalRadiusCacheTimeout = types.Int64Null()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.enabled"); value.Exists() {
+ data.LocalRadiusCertificateAuthenticationEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.LocalRadiusCertificateAuthenticationEnabled = types.BoolNull()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.ocspResponderUrl"); value.Exists() {
+ data.LocalRadiusCertificateAuthenticationOcspResponderUrl = types.StringValue(value.String())
+ } else {
+ data.LocalRadiusCertificateAuthenticationOcspResponderUrl = types.StringNull()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.useLdap"); value.Exists() {
+ data.LocalRadiusCertificateAuthenticationUseLdap = types.BoolValue(value.Bool())
+ } else {
+ data.LocalRadiusCertificateAuthenticationUseLdap = types.BoolNull()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.useOcsp"); value.Exists() {
+ data.LocalRadiusCertificateAuthenticationUseOcsp = types.BoolValue(value.Bool())
+ } else {
+ data.LocalRadiusCertificateAuthenticationUseOcsp = types.BoolNull()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.clientRootCaCertificate.contents"); value.Exists() {
+ data.LocalRadiusCertificateAuthenticationClientRootCaCertificateContents = types.StringValue(value.String())
+ } else {
+ data.LocalRadiusCertificateAuthenticationClientRootCaCertificateContents = types.StringNull()
+ }
+ if value := res.Get("localRadius.passwordAuthentication.enabled"); value.Exists() {
+ data.LocalRadiusPasswordAuthenticationEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.LocalRadiusPasswordAuthenticationEnabled = types.BoolNull()
+ }
+ if value := res.Get("namedVlans.radius.guestVlan.enabled"); value.Exists() {
+ data.NamedVlansRadiusGuestVlanEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.NamedVlansRadiusGuestVlanEnabled = types.BoolNull()
+ }
+ if value := res.Get("namedVlans.radius.guestVlan.name"); value.Exists() {
+ data.NamedVlansRadiusGuestVlanName = types.StringValue(value.String())
+ } else {
+ data.NamedVlansRadiusGuestVlanName = types.StringNull()
+ }
+ if value := res.Get("namedVlans.tagging.defaultVlanName"); value.Exists() {
+ data.NamedVlansTaggingDefaultVlanName = types.StringValue(value.String())
+ } else {
+ data.NamedVlansTaggingDefaultVlanName = types.StringNull()
+ }
+ if value := res.Get("namedVlans.tagging.enabled"); value.Exists() {
+ data.NamedVlansTaggingEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.NamedVlansTaggingEnabled = types.BoolNull()
+ }
+ if value := res.Get("namedVlans.tagging.byApTags"); value.Exists() {
+ data.NamedVlansTaggingByApTags = make([]WirelessSSIDNamedVlansTaggingByApTags, 0)
+ value.ForEach(func(k, res gjson.Result) bool {
+ parent := &data
+ data := WirelessSSIDNamedVlansTaggingByApTags{}
+ if value := res.Get("vlanName"); value.Exists() {
+ data.VlanName = types.StringValue(value.String())
+ } else {
+ data.VlanName = types.StringNull()
+ }
+ if value := res.Get("tags"); value.Exists() {
+ data.Tags = helpers.GetStringList(value.Array())
+ } else {
+ data.Tags = types.ListNull(types.StringType)
+ }
+ (*parent).NamedVlansTaggingByApTags = append((*parent).NamedVlansTaggingByApTags, data)
+ return true
+ })
+ }
+ if value := res.Get("oauth.allowedDomains"); value.Exists() {
+ data.OauthAllowedDomains = helpers.GetStringList(value.Array())
+ } else {
+ data.OauthAllowedDomains = types.ListNull(types.StringType)
+ }
+ if value := res.Get("speedBurst.enabled"); value.Exists() {
+ data.SpeedBurstEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.SpeedBurstEnabled = types.BoolNull()
+ }
+ if value := res.Get("apTagsAndVlanIds"); value.Exists() {
+ data.ApTagsAndVlanIds = make([]WirelessSSIDApTagsAndVlanIds, 0)
+ value.ForEach(func(k, res gjson.Result) bool {
+ parent := &data
+ data := WirelessSSIDApTagsAndVlanIds{}
+ if value := res.Get("vlanId"); value.Exists() {
+ data.VlanId = types.Int64Value(value.Int())
+ } else {
+ data.VlanId = types.Int64Null()
+ }
+ if value := res.Get("tags"); value.Exists() {
+ data.Tags = helpers.GetStringList(value.Array())
+ } else {
+ data.Tags = types.ListNull(types.StringType)
+ }
+ (*parent).ApTagsAndVlanIds = append((*parent).ApTagsAndVlanIds, data)
+ return true
+ })
+ }
+ if value := res.Get("availabilityTags"); value.Exists() {
+ data.AvailabilityTags = helpers.GetStringList(value.Array())
+ } else {
+ data.AvailabilityTags = types.ListNull(types.StringType)
+ }
+ if value := res.Get("radiusAccountingServers"); value.Exists() {
+ data.RadiusAccountingServers = make([]WirelessSSIDRadiusAccountingServers, 0)
+ value.ForEach(func(k, res gjson.Result) bool {
+ parent := &data
+ data := WirelessSSIDRadiusAccountingServers{}
+ if value := res.Get("caCertificate"); value.Exists() {
+ data.CaCertificate = types.StringValue(value.String())
+ } else {
+ data.CaCertificate = types.StringNull()
+ }
+ if value := res.Get("host"); value.Exists() {
+ data.Host = types.StringValue(value.String())
+ } else {
+ data.Host = types.StringNull()
+ }
+ if value := res.Get("port"); value.Exists() {
+ data.Port = types.Int64Value(value.Int())
+ } else {
+ data.Port = types.Int64Null()
+ }
+ if value := res.Get("radsecEnabled"); value.Exists() {
+ data.RadsecEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadsecEnabled = types.BoolNull()
+ }
+ if value := res.Get("secret"); value.Exists() {
+ data.Secret = types.StringValue(value.String())
+ } else {
+ data.Secret = types.StringNull()
+ }
+ (*parent).RadiusAccountingServers = append((*parent).RadiusAccountingServers, data)
+ return true
+ })
+ }
+ if value := res.Get("radiusServers"); value.Exists() {
+ data.RadiusServers = make([]WirelessSSIDRadiusServers, 0)
+ value.ForEach(func(k, res gjson.Result) bool {
+ parent := &data
+ data := WirelessSSIDRadiusServers{}
+ if value := res.Get("caCertificate"); value.Exists() {
+ data.CaCertificate = types.StringValue(value.String())
+ } else {
+ data.CaCertificate = types.StringNull()
+ }
+ if value := res.Get("host"); value.Exists() {
+ data.Host = types.StringValue(value.String())
+ } else {
+ data.Host = types.StringNull()
+ }
+ if value := res.Get("openRoamingCertificateId"); value.Exists() {
+ data.OpenRoamingCertificateId = types.Int64Value(value.Int())
+ } else {
+ data.OpenRoamingCertificateId = types.Int64Null()
+ }
+ if value := res.Get("port"); value.Exists() {
+ data.Port = types.Int64Value(value.Int())
+ } else {
+ data.Port = types.Int64Null()
+ }
+ if value := res.Get("radsecEnabled"); value.Exists() {
+ data.RadsecEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadsecEnabled = types.BoolNull()
+ }
+ if value := res.Get("secret"); value.Exists() {
+ data.Secret = types.StringValue(value.String())
+ } else {
+ data.Secret = types.StringNull()
+ }
+ (*parent).RadiusServers = append((*parent).RadiusServers, data)
+ return true
+ })
+ }
+ if value := res.Get("splashGuestSponsorDomains"); value.Exists() {
+ data.SplashGuestSponsorDomains = helpers.GetStringList(value.Array())
+ } else {
+ data.SplashGuestSponsorDomains = types.ListNull(types.StringType)
+ }
+ if value := res.Get("walledGardenRanges"); value.Exists() {
+ data.WalledGardenRanges = helpers.GetStringList(value.Array())
+ } else {
+ data.WalledGardenRanges = types.ListNull(types.StringType)
+ }
+}
+
+// End of section. //template:end fromBody
+
+// Section below is generated&owned by "gen/generator.go". //template:begin fromBodyPartial
+
+// fromBodyPartial reads values from a gjson.Result into a tfstate model. It ignores null attributes in order to
+// uncouple the provider from the exact values that the backend API might summon to replace nulls. (Such behavior might
+// easily change across versions of the backend API.) For List/Set/Map attributes, the func only updates the
+// "managed" elements, instead of all elements.
+func (data *WirelessSSID) fromBodyPartial(ctx context.Context, res gjson.Result) {
+ if value := res.Get("adultContentFilteringEnabled"); value.Exists() && !data.AdultContentFilteringEnabled.IsNull() {
+ data.AdultContentFilteringEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.AdultContentFilteringEnabled = types.BoolNull()
+ }
+ if value := res.Get("authMode"); value.Exists() && !data.AuthMode.IsNull() {
+ data.AuthMode = types.StringValue(value.String())
+ } else {
+ data.AuthMode = types.StringNull()
+ }
+ if value := res.Get("availableOnAllAps"); value.Exists() && !data.AvailableOnAllAps.IsNull() {
+ data.AvailableOnAllAps = types.BoolValue(value.Bool())
+ } else {
+ data.AvailableOnAllAps = types.BoolNull()
+ }
+ if value := res.Get("bandSelection"); value.Exists() && !data.BandSelection.IsNull() {
+ data.BandSelection = types.StringValue(value.String())
+ } else {
+ data.BandSelection = types.StringNull()
+ }
+ if value := res.Get("concentratorNetworkId"); value.Exists() && !data.ConcentratorNetworkId.IsNull() {
+ data.ConcentratorNetworkId = types.StringValue(value.String())
+ } else {
+ data.ConcentratorNetworkId = types.StringNull()
+ }
+ if value := res.Get("defaultVlanId"); value.Exists() && !data.DefaultVlanId.IsNull() {
+ data.DefaultVlanId = types.Int64Value(value.Int())
+ } else {
+ data.DefaultVlanId = types.Int64Null()
+ }
+ if value := res.Get("disassociateClientsOnVpnFailover"); value.Exists() && !data.DisassociateClientsOnVpnFailover.IsNull() {
+ data.DisassociateClientsOnVpnFailover = types.BoolValue(value.Bool())
+ } else {
+ data.DisassociateClientsOnVpnFailover = types.BoolNull()
+ }
+ if value := res.Get("enabled"); value.Exists() && !data.Enabled.IsNull() {
+ data.Enabled = types.BoolValue(value.Bool())
+ } else {
+ data.Enabled = types.BoolNull()
+ }
+ if value := res.Get("encryptionMode"); value.Exists() && !data.EncryptionMode.IsNull() {
+ data.EncryptionMode = types.StringValue(value.String())
+ } else {
+ data.EncryptionMode = types.StringNull()
+ }
+ if value := res.Get("enterpriseAdminAccess"); value.Exists() && !data.EnterpriseAdminAccess.IsNull() {
+ data.EnterpriseAdminAccess = types.StringValue(value.String())
+ } else {
+ data.EnterpriseAdminAccess = types.StringNull()
+ }
+ if value := res.Get("ipAssignmentMode"); value.Exists() && !data.IpAssignmentMode.IsNull() {
+ data.IpAssignmentMode = types.StringValue(value.String())
+ } else {
+ data.IpAssignmentMode = types.StringNull()
+ }
+ if value := res.Get("lanIsolationEnabled"); value.Exists() && !data.LanIsolationEnabled.IsNull() {
+ data.LanIsolationEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.LanIsolationEnabled = types.BoolNull()
+ }
+ if value := res.Get("mandatoryDhcpEnabled"); value.Exists() && !data.MandatoryDhcpEnabled.IsNull() {
+ data.MandatoryDhcpEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.MandatoryDhcpEnabled = types.BoolNull()
+ }
+ if value := res.Get("minBitrate"); value.Exists() && !data.MinBitrate.IsNull() {
+ data.MinBitrate = types.Float64Value(value.Float())
+ } else {
+ data.MinBitrate = types.Float64Null()
+ }
+ if value := res.Get("name"); value.Exists() && !data.Name.IsNull() {
+ data.Name = types.StringValue(value.String())
+ } else {
+ data.Name = types.StringNull()
+ }
+ if value := res.Get("perClientBandwidthLimitDown"); value.Exists() && !data.PerClientBandwidthLimitDown.IsNull() {
+ data.PerClientBandwidthLimitDown = types.Int64Value(value.Int())
+ } else {
+ data.PerClientBandwidthLimitDown = types.Int64Null()
+ }
+ if value := res.Get("perClientBandwidthLimitUp"); value.Exists() && !data.PerClientBandwidthLimitUp.IsNull() {
+ data.PerClientBandwidthLimitUp = types.Int64Value(value.Int())
+ } else {
+ data.PerClientBandwidthLimitUp = types.Int64Null()
+ }
+ if value := res.Get("perSsidBandwidthLimitDown"); value.Exists() && !data.PerSsidBandwidthLimitDown.IsNull() {
+ data.PerSsidBandwidthLimitDown = types.Int64Value(value.Int())
+ } else {
+ data.PerSsidBandwidthLimitDown = types.Int64Null()
+ }
+ if value := res.Get("perSsidBandwidthLimitUp"); value.Exists() && !data.PerSsidBandwidthLimitUp.IsNull() {
+ data.PerSsidBandwidthLimitUp = types.Int64Value(value.Int())
+ } else {
+ data.PerSsidBandwidthLimitUp = types.Int64Null()
+ }
+ if value := res.Get("psk"); value.Exists() && !data.Psk.IsNull() {
+ data.Psk = types.StringValue(value.String())
+ } else {
+ data.Psk = types.StringNull()
+ }
+ if value := res.Get("radiusAccountingEnabled"); value.Exists() && !data.RadiusAccountingEnabled.IsNull() {
+ data.RadiusAccountingEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusAccountingEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusAccountingInterimInterval"); value.Exists() && !data.RadiusAccountingInterimInterval.IsNull() {
+ data.RadiusAccountingInterimInterval = types.Int64Value(value.Int())
+ } else {
+ data.RadiusAccountingInterimInterval = types.Int64Null()
+ }
+ if value := res.Get("radiusAttributeForGroupPolicies"); value.Exists() && !data.RadiusAttributeForGroupPolicies.IsNull() {
+ data.RadiusAttributeForGroupPolicies = types.StringValue(value.String())
+ } else {
+ data.RadiusAttributeForGroupPolicies = types.StringNull()
+ }
+ if value := res.Get("radiusAuthenticationNasId"); value.Exists() && !data.RadiusAuthenticationNasId.IsNull() {
+ data.RadiusAuthenticationNasId = types.StringValue(value.String())
+ } else {
+ data.RadiusAuthenticationNasId = types.StringNull()
+ }
+ if value := res.Get("radiusCalledStationId"); value.Exists() && !data.RadiusCalledStationId.IsNull() {
+ data.RadiusCalledStationId = types.StringValue(value.String())
+ } else {
+ data.RadiusCalledStationId = types.StringNull()
+ }
+ if value := res.Get("radiusCoaEnabled"); value.Exists() && !data.RadiusCoaEnabled.IsNull() {
+ data.RadiusCoaEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusCoaEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusFailoverPolicy"); value.Exists() && !data.RadiusFailoverPolicy.IsNull() {
+ data.RadiusFailoverPolicy = types.StringValue(value.String())
+ } else {
+ data.RadiusFailoverPolicy = types.StringNull()
+ }
+ if value := res.Get("radiusFallbackEnabled"); value.Exists() && !data.RadiusFallbackEnabled.IsNull() {
+ data.RadiusFallbackEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusFallbackEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusGuestVlanEnabled"); value.Exists() && !data.RadiusGuestVlanEnabled.IsNull() {
+ data.RadiusGuestVlanEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusGuestVlanEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusGuestVlanId"); value.Exists() && !data.RadiusGuestVlanId.IsNull() {
+ data.RadiusGuestVlanId = types.Int64Value(value.Int())
+ } else {
+ data.RadiusGuestVlanId = types.Int64Null()
+ }
+ if value := res.Get("radiusLoadBalancingPolicy"); value.Exists() && !data.RadiusLoadBalancingPolicy.IsNull() {
+ data.RadiusLoadBalancingPolicy = types.StringValue(value.String())
+ } else {
+ data.RadiusLoadBalancingPolicy = types.StringNull()
+ }
+ if value := res.Get("radiusOverride"); value.Exists() && !data.RadiusOverride.IsNull() {
+ data.RadiusOverride = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusOverride = types.BoolNull()
+ }
+ if value := res.Get("radiusProxyEnabled"); value.Exists() && !data.RadiusProxyEnabled.IsNull() {
+ data.RadiusProxyEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusProxyEnabled = types.BoolNull()
+ }
+ if value := res.Get("radiusServerAttemptsLimit"); value.Exists() && !data.RadiusServerAttemptsLimit.IsNull() {
+ data.RadiusServerAttemptsLimit = types.Int64Value(value.Int())
+ } else {
+ data.RadiusServerAttemptsLimit = types.Int64Null()
+ }
+ if value := res.Get("radiusServerTimeout"); value.Exists() && !data.RadiusServerTimeout.IsNull() {
+ data.RadiusServerTimeout = types.Int64Value(value.Int())
+ } else {
+ data.RadiusServerTimeout = types.Int64Null()
+ }
+ if value := res.Get("radiusTestingEnabled"); value.Exists() && !data.RadiusTestingEnabled.IsNull() {
+ data.RadiusTestingEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadiusTestingEnabled = types.BoolNull()
+ }
+ if value := res.Get("secondaryConcentratorNetworkId"); value.Exists() && !data.SecondaryConcentratorNetworkId.IsNull() {
+ data.SecondaryConcentratorNetworkId = types.StringValue(value.String())
+ } else {
+ data.SecondaryConcentratorNetworkId = types.StringNull()
+ }
+ if value := res.Get("splashPage"); value.Exists() && !data.SplashPage.IsNull() {
+ data.SplashPage = types.StringValue(value.String())
+ } else {
+ data.SplashPage = types.StringNull()
+ }
+ if value := res.Get("useVlanTagging"); value.Exists() && !data.UseVlanTagging.IsNull() {
+ data.UseVlanTagging = types.BoolValue(value.Bool())
+ } else {
+ data.UseVlanTagging = types.BoolNull()
+ }
+ if value := res.Get("visible"); value.Exists() && !data.Visible.IsNull() {
+ data.Visible = types.BoolValue(value.Bool())
+ } else {
+ data.Visible = types.BoolNull()
+ }
+ if value := res.Get("vlanId"); value.Exists() && !data.VlanId.IsNull() {
+ data.VlanId = types.Int64Value(value.Int())
+ } else {
+ data.VlanId = types.Int64Null()
+ }
+ if value := res.Get("walledGardenEnabled"); value.Exists() && !data.WalledGardenEnabled.IsNull() {
+ data.WalledGardenEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.WalledGardenEnabled = types.BoolNull()
+ }
+ if value := res.Get("wpaEncryptionMode"); value.Exists() && !data.WpaEncryptionMode.IsNull() {
+ data.WpaEncryptionMode = types.StringValue(value.String())
+ } else {
+ data.WpaEncryptionMode = types.StringNull()
+ }
+ if value := res.Get("activeDirectory.credentials.logonName"); value.Exists() && !data.ActiveDirectoryCredentialsLogonName.IsNull() {
+ data.ActiveDirectoryCredentialsLogonName = types.StringValue(value.String())
+ } else {
+ data.ActiveDirectoryCredentialsLogonName = types.StringNull()
+ }
+ if value := res.Get("activeDirectory.credentials.password"); value.Exists() && !data.ActiveDirectoryCredentialsPassword.IsNull() {
+ data.ActiveDirectoryCredentialsPassword = types.StringValue(value.String())
+ } else {
+ data.ActiveDirectoryCredentialsPassword = types.StringNull()
+ }
+ for i := 0; i < len(data.ActiveDirectoryServers); i++ {
+ keys := [...]string{"host", "port"}
+ keyValues := [...]string{data.ActiveDirectoryServers[i].Host.ValueString(), strconv.FormatInt(data.ActiveDirectoryServers[i].Port.ValueInt64(), 10)}
+
+ parent := &data
+ data := (*parent).ActiveDirectoryServers[i]
+ parentRes := &res
+ var res gjson.Result
+
+ parentRes.Get("activeDirectory.servers").ForEach(
+ func(_, v gjson.Result) bool {
+ found := false
+ for ik := range keys {
+ if v.Get(keys[ik]).String() != keyValues[ik] {
+ found = false
+ break
+ }
+ found = true
+ }
+ if found {
+ res = v
+ return false
+ }
+ return true
+ },
+ )
+ if !res.Exists() {
+ tflog.Debug(ctx, fmt.Sprintf("removing ActiveDirectoryServers[%d] = %+v",
+ i,
+ (*parent).ActiveDirectoryServers[i],
+ ))
+ (*parent).ActiveDirectoryServers = slices.Delete((*parent).ActiveDirectoryServers, i, i+1)
+ i--
+
+ continue
+ }
+ if value := res.Get("host"); value.Exists() && !data.Host.IsNull() {
+ data.Host = types.StringValue(value.String())
+ } else {
+ data.Host = types.StringNull()
+ }
+ if value := res.Get("port"); value.Exists() && !data.Port.IsNull() {
+ data.Port = types.Int64Value(value.Int())
+ } else {
+ data.Port = types.Int64Null()
+ }
+ (*parent).ActiveDirectoryServers[i] = data
+ }
+ if value := res.Get("dnsRewrite.enabled"); value.Exists() && !data.DnsRewriteEnabled.IsNull() {
+ data.DnsRewriteEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.DnsRewriteEnabled = types.BoolNull()
+ }
+ if value := res.Get("dnsRewrite.dnsCustomNameservers"); value.Exists() && !data.DnsRewriteDnsCustomNameservers.IsNull() {
+ data.DnsRewriteDnsCustomNameservers = helpers.GetStringList(value.Array())
+ } else {
+ data.DnsRewriteDnsCustomNameservers = types.ListNull(types.StringType)
+ }
+ if value := res.Get("dot11r.adaptive"); value.Exists() && !data.Dot11rAdaptive.IsNull() {
+ data.Dot11rAdaptive = types.BoolValue(value.Bool())
+ } else {
+ data.Dot11rAdaptive = types.BoolNull()
+ }
+ if value := res.Get("dot11r.enabled"); value.Exists() && !data.Dot11rEnabled.IsNull() {
+ data.Dot11rEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.Dot11rEnabled = types.BoolNull()
+ }
+ if value := res.Get("dot11w.enabled"); value.Exists() && !data.Dot11wEnabled.IsNull() {
+ data.Dot11wEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.Dot11wEnabled = types.BoolNull()
+ }
+ if value := res.Get("dot11w.required"); value.Exists() && !data.Dot11wRequired.IsNull() {
+ data.Dot11wRequired = types.BoolValue(value.Bool())
+ } else {
+ data.Dot11wRequired = types.BoolNull()
+ }
+ if value := res.Get("gre.key"); value.Exists() && !data.GreKey.IsNull() {
+ data.GreKey = types.Int64Value(value.Int())
+ } else {
+ data.GreKey = types.Int64Null()
+ }
+ if value := res.Get("gre.concentrator.host"); value.Exists() && !data.GreConcentratorHost.IsNull() {
+ data.GreConcentratorHost = types.StringValue(value.String())
+ } else {
+ data.GreConcentratorHost = types.StringNull()
+ }
+ if value := res.Get("ldap.baseDistinguishedName"); value.Exists() && !data.LdapBaseDistinguishedName.IsNull() {
+ data.LdapBaseDistinguishedName = types.StringValue(value.String())
+ } else {
+ data.LdapBaseDistinguishedName = types.StringNull()
+ }
+ if value := res.Get("ldap.credentials.distinguishedName"); value.Exists() && !data.LdapCredentialsDistinguishedName.IsNull() {
+ data.LdapCredentialsDistinguishedName = types.StringValue(value.String())
+ } else {
+ data.LdapCredentialsDistinguishedName = types.StringNull()
+ }
+ if value := res.Get("ldap.credentials.password"); value.Exists() && !data.LdapCredentialsPassword.IsNull() {
+ data.LdapCredentialsPassword = types.StringValue(value.String())
+ } else {
+ data.LdapCredentialsPassword = types.StringNull()
+ }
+ if value := res.Get("ldap.serverCaCertificate.contents"); value.Exists() && !data.LdapServerCaCertificateContents.IsNull() {
+ data.LdapServerCaCertificateContents = types.StringValue(value.String())
+ } else {
+ data.LdapServerCaCertificateContents = types.StringNull()
+ }
+ for i := 0; i < len(data.LdapServers); i++ {
+ keys := [...]string{"host", "port"}
+ keyValues := [...]string{data.LdapServers[i].Host.ValueString(), strconv.FormatInt(data.LdapServers[i].Port.ValueInt64(), 10)}
+
+ parent := &data
+ data := (*parent).LdapServers[i]
+ parentRes := &res
+ var res gjson.Result
+
+ parentRes.Get("ldap.servers").ForEach(
+ func(_, v gjson.Result) bool {
+ found := false
+ for ik := range keys {
+ if v.Get(keys[ik]).String() != keyValues[ik] {
+ found = false
+ break
+ }
+ found = true
+ }
+ if found {
+ res = v
+ return false
+ }
+ return true
+ },
+ )
+ if !res.Exists() {
+ tflog.Debug(ctx, fmt.Sprintf("removing LdapServers[%d] = %+v",
+ i,
+ (*parent).LdapServers[i],
+ ))
+ (*parent).LdapServers = slices.Delete((*parent).LdapServers, i, i+1)
+ i--
+
+ continue
+ }
+ if value := res.Get("host"); value.Exists() && !data.Host.IsNull() {
+ data.Host = types.StringValue(value.String())
+ } else {
+ data.Host = types.StringNull()
+ }
+ if value := res.Get("port"); value.Exists() && !data.Port.IsNull() {
+ data.Port = types.Int64Value(value.Int())
+ } else {
+ data.Port = types.Int64Null()
+ }
+ (*parent).LdapServers[i] = data
+ }
+ if value := res.Get("localRadius.cacheTimeout"); value.Exists() && !data.LocalRadiusCacheTimeout.IsNull() {
+ data.LocalRadiusCacheTimeout = types.Int64Value(value.Int())
+ } else {
+ data.LocalRadiusCacheTimeout = types.Int64Null()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.enabled"); value.Exists() && !data.LocalRadiusCertificateAuthenticationEnabled.IsNull() {
+ data.LocalRadiusCertificateAuthenticationEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.LocalRadiusCertificateAuthenticationEnabled = types.BoolNull()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.ocspResponderUrl"); value.Exists() && !data.LocalRadiusCertificateAuthenticationOcspResponderUrl.IsNull() {
+ data.LocalRadiusCertificateAuthenticationOcspResponderUrl = types.StringValue(value.String())
+ } else {
+ data.LocalRadiusCertificateAuthenticationOcspResponderUrl = types.StringNull()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.useLdap"); value.Exists() && !data.LocalRadiusCertificateAuthenticationUseLdap.IsNull() {
+ data.LocalRadiusCertificateAuthenticationUseLdap = types.BoolValue(value.Bool())
+ } else {
+ data.LocalRadiusCertificateAuthenticationUseLdap = types.BoolNull()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.useOcsp"); value.Exists() && !data.LocalRadiusCertificateAuthenticationUseOcsp.IsNull() {
+ data.LocalRadiusCertificateAuthenticationUseOcsp = types.BoolValue(value.Bool())
+ } else {
+ data.LocalRadiusCertificateAuthenticationUseOcsp = types.BoolNull()
+ }
+ if value := res.Get("localRadius.certificateAuthentication.clientRootCaCertificate.contents"); value.Exists() && !data.LocalRadiusCertificateAuthenticationClientRootCaCertificateContents.IsNull() {
+ data.LocalRadiusCertificateAuthenticationClientRootCaCertificateContents = types.StringValue(value.String())
+ } else {
+ data.LocalRadiusCertificateAuthenticationClientRootCaCertificateContents = types.StringNull()
+ }
+ if value := res.Get("localRadius.passwordAuthentication.enabled"); value.Exists() && !data.LocalRadiusPasswordAuthenticationEnabled.IsNull() {
+ data.LocalRadiusPasswordAuthenticationEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.LocalRadiusPasswordAuthenticationEnabled = types.BoolNull()
+ }
+ if value := res.Get("namedVlans.radius.guestVlan.enabled"); value.Exists() && !data.NamedVlansRadiusGuestVlanEnabled.IsNull() {
+ data.NamedVlansRadiusGuestVlanEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.NamedVlansRadiusGuestVlanEnabled = types.BoolNull()
+ }
+ if value := res.Get("namedVlans.radius.guestVlan.name"); value.Exists() && !data.NamedVlansRadiusGuestVlanName.IsNull() {
+ data.NamedVlansRadiusGuestVlanName = types.StringValue(value.String())
+ } else {
+ data.NamedVlansRadiusGuestVlanName = types.StringNull()
+ }
+ if value := res.Get("namedVlans.tagging.defaultVlanName"); value.Exists() && !data.NamedVlansTaggingDefaultVlanName.IsNull() {
+ data.NamedVlansTaggingDefaultVlanName = types.StringValue(value.String())
+ } else {
+ data.NamedVlansTaggingDefaultVlanName = types.StringNull()
+ }
+ if value := res.Get("namedVlans.tagging.enabled"); value.Exists() && !data.NamedVlansTaggingEnabled.IsNull() {
+ data.NamedVlansTaggingEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.NamedVlansTaggingEnabled = types.BoolNull()
+ }
+ for i := 0; i < len(data.NamedVlansTaggingByApTags); i++ {
+ keys := [...]string{"vlanName"}
+ keyValues := [...]string{data.NamedVlansTaggingByApTags[i].VlanName.ValueString()}
+
+ parent := &data
+ data := (*parent).NamedVlansTaggingByApTags[i]
+ parentRes := &res
+ var res gjson.Result
+
+ parentRes.Get("namedVlans.tagging.byApTags").ForEach(
+ func(_, v gjson.Result) bool {
+ found := false
+ for ik := range keys {
+ if v.Get(keys[ik]).String() != keyValues[ik] {
+ found = false
+ break
+ }
+ found = true
+ }
+ if found {
+ res = v
+ return false
+ }
+ return true
+ },
+ )
+ if !res.Exists() {
+ tflog.Debug(ctx, fmt.Sprintf("removing NamedVlansTaggingByApTags[%d] = %+v",
+ i,
+ (*parent).NamedVlansTaggingByApTags[i],
+ ))
+ (*parent).NamedVlansTaggingByApTags = slices.Delete((*parent).NamedVlansTaggingByApTags, i, i+1)
+ i--
+
+ continue
+ }
+ if value := res.Get("vlanName"); value.Exists() && !data.VlanName.IsNull() {
+ data.VlanName = types.StringValue(value.String())
+ } else {
+ data.VlanName = types.StringNull()
+ }
+ if value := res.Get("tags"); value.Exists() && !data.Tags.IsNull() {
+ data.Tags = helpers.GetStringList(value.Array())
+ } else {
+ data.Tags = types.ListNull(types.StringType)
+ }
+ (*parent).NamedVlansTaggingByApTags[i] = data
+ }
+ if value := res.Get("oauth.allowedDomains"); value.Exists() && !data.OauthAllowedDomains.IsNull() {
+ data.OauthAllowedDomains = helpers.GetStringList(value.Array())
+ } else {
+ data.OauthAllowedDomains = types.ListNull(types.StringType)
+ }
+ if value := res.Get("speedBurst.enabled"); value.Exists() && !data.SpeedBurstEnabled.IsNull() {
+ data.SpeedBurstEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.SpeedBurstEnabled = types.BoolNull()
+ }
+ for i := 0; i < len(data.ApTagsAndVlanIds); i++ {
+ keys := [...]string{"vlanId"}
+ keyValues := [...]string{strconv.FormatInt(data.ApTagsAndVlanIds[i].VlanId.ValueInt64(), 10)}
+
+ parent := &data
+ data := (*parent).ApTagsAndVlanIds[i]
+ parentRes := &res
+ var res gjson.Result
+
+ parentRes.Get("apTagsAndVlanIds").ForEach(
+ func(_, v gjson.Result) bool {
+ found := false
+ for ik := range keys {
+ if v.Get(keys[ik]).String() != keyValues[ik] {
+ found = false
+ break
+ }
+ found = true
+ }
+ if found {
+ res = v
+ return false
+ }
+ return true
+ },
+ )
+ if !res.Exists() {
+ tflog.Debug(ctx, fmt.Sprintf("removing ApTagsAndVlanIds[%d] = %+v",
+ i,
+ (*parent).ApTagsAndVlanIds[i],
+ ))
+ (*parent).ApTagsAndVlanIds = slices.Delete((*parent).ApTagsAndVlanIds, i, i+1)
+ i--
+
+ continue
+ }
+ if value := res.Get("vlanId"); value.Exists() && !data.VlanId.IsNull() {
+ data.VlanId = types.Int64Value(value.Int())
+ } else {
+ data.VlanId = types.Int64Null()
+ }
+ if value := res.Get("tags"); value.Exists() && !data.Tags.IsNull() {
+ data.Tags = helpers.GetStringList(value.Array())
+ } else {
+ data.Tags = types.ListNull(types.StringType)
+ }
+ (*parent).ApTagsAndVlanIds[i] = data
+ }
+ if value := res.Get("availabilityTags"); value.Exists() && !data.AvailabilityTags.IsNull() {
+ data.AvailabilityTags = helpers.GetStringList(value.Array())
+ } else {
+ data.AvailabilityTags = types.ListNull(types.StringType)
+ }
+ for i := 0; i < len(data.RadiusAccountingServers); i++ {
+ keys := [...]string{"caCertificate", "host", "port", "radsecEnabled", "secret"}
+ keyValues := [...]string{data.RadiusAccountingServers[i].CaCertificate.ValueString(), data.RadiusAccountingServers[i].Host.ValueString(), strconv.FormatInt(data.RadiusAccountingServers[i].Port.ValueInt64(), 10), strconv.FormatBool(data.RadiusAccountingServers[i].RadsecEnabled.ValueBool()), data.RadiusAccountingServers[i].Secret.ValueString()}
+
+ parent := &data
+ data := (*parent).RadiusAccountingServers[i]
+ parentRes := &res
+ var res gjson.Result
+
+ parentRes.Get("radiusAccountingServers").ForEach(
+ func(_, v gjson.Result) bool {
+ found := false
+ for ik := range keys {
+ if v.Get(keys[ik]).String() != keyValues[ik] {
+ found = false
+ break
+ }
+ found = true
+ }
+ if found {
+ res = v
+ return false
+ }
+ return true
+ },
+ )
+ if !res.Exists() {
+ tflog.Debug(ctx, fmt.Sprintf("removing RadiusAccountingServers[%d] = %+v",
+ i,
+ (*parent).RadiusAccountingServers[i],
+ ))
+ (*parent).RadiusAccountingServers = slices.Delete((*parent).RadiusAccountingServers, i, i+1)
+ i--
+
+ continue
+ }
+ if value := res.Get("caCertificate"); value.Exists() && !data.CaCertificate.IsNull() {
+ data.CaCertificate = types.StringValue(value.String())
+ } else {
+ data.CaCertificate = types.StringNull()
+ }
+ if value := res.Get("host"); value.Exists() && !data.Host.IsNull() {
+ data.Host = types.StringValue(value.String())
+ } else {
+ data.Host = types.StringNull()
+ }
+ if value := res.Get("port"); value.Exists() && !data.Port.IsNull() {
+ data.Port = types.Int64Value(value.Int())
+ } else {
+ data.Port = types.Int64Null()
+ }
+ if value := res.Get("radsecEnabled"); value.Exists() && !data.RadsecEnabled.IsNull() {
+ data.RadsecEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadsecEnabled = types.BoolNull()
+ }
+ if value := res.Get("secret"); value.Exists() && !data.Secret.IsNull() {
+ data.Secret = types.StringValue(value.String())
+ } else {
+ data.Secret = types.StringNull()
+ }
+ (*parent).RadiusAccountingServers[i] = data
+ }
+ for i := 0; i < len(data.RadiusServers); i++ {
+ keys := [...]string{"caCertificate", "host", "openRoamingCertificateId", "port", "radsecEnabled", "secret"}
+ keyValues := [...]string{data.RadiusServers[i].CaCertificate.ValueString(), data.RadiusServers[i].Host.ValueString(), strconv.FormatInt(data.RadiusServers[i].OpenRoamingCertificateId.ValueInt64(), 10), strconv.FormatInt(data.RadiusServers[i].Port.ValueInt64(), 10), strconv.FormatBool(data.RadiusServers[i].RadsecEnabled.ValueBool()), data.RadiusServers[i].Secret.ValueString()}
+
+ parent := &data
+ data := (*parent).RadiusServers[i]
+ parentRes := &res
+ var res gjson.Result
+
+ parentRes.Get("radiusServers").ForEach(
+ func(_, v gjson.Result) bool {
+ found := false
+ for ik := range keys {
+ if v.Get(keys[ik]).String() != keyValues[ik] {
+ found = false
+ break
+ }
+ found = true
+ }
+ if found {
+ res = v
+ return false
+ }
+ return true
+ },
+ )
+ if !res.Exists() {
+ tflog.Debug(ctx, fmt.Sprintf("removing RadiusServers[%d] = %+v",
+ i,
+ (*parent).RadiusServers[i],
+ ))
+ (*parent).RadiusServers = slices.Delete((*parent).RadiusServers, i, i+1)
+ i--
+
+ continue
+ }
+ if value := res.Get("caCertificate"); value.Exists() && !data.CaCertificate.IsNull() {
+ data.CaCertificate = types.StringValue(value.String())
+ } else {
+ data.CaCertificate = types.StringNull()
+ }
+ if value := res.Get("host"); value.Exists() && !data.Host.IsNull() {
+ data.Host = types.StringValue(value.String())
+ } else {
+ data.Host = types.StringNull()
+ }
+ if value := res.Get("openRoamingCertificateId"); value.Exists() && !data.OpenRoamingCertificateId.IsNull() {
+ data.OpenRoamingCertificateId = types.Int64Value(value.Int())
+ } else {
+ data.OpenRoamingCertificateId = types.Int64Null()
+ }
+ if value := res.Get("port"); value.Exists() && !data.Port.IsNull() {
+ data.Port = types.Int64Value(value.Int())
+ } else {
+ data.Port = types.Int64Null()
+ }
+ if value := res.Get("radsecEnabled"); value.Exists() && !data.RadsecEnabled.IsNull() {
+ data.RadsecEnabled = types.BoolValue(value.Bool())
+ } else {
+ data.RadsecEnabled = types.BoolNull()
+ }
+ if value := res.Get("secret"); value.Exists() && !data.Secret.IsNull() {
+ data.Secret = types.StringValue(value.String())
+ } else {
+ data.Secret = types.StringNull()
+ }
+ (*parent).RadiusServers[i] = data
+ }
+ if value := res.Get("splashGuestSponsorDomains"); value.Exists() && !data.SplashGuestSponsorDomains.IsNull() {
+ data.SplashGuestSponsorDomains = helpers.GetStringList(value.Array())
+ } else {
+ data.SplashGuestSponsorDomains = types.ListNull(types.StringType)
+ }
+ if value := res.Get("walledGardenRanges"); value.Exists() && !data.WalledGardenRanges.IsNull() {
+ data.WalledGardenRanges = helpers.GetStringList(value.Array())
+ } else {
+ data.WalledGardenRanges = types.ListNull(types.StringType)
+ }
+}
+
+// End of section. //template:end fromBodyPartial
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index b2ad671..8bd41a9 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -217,6 +217,7 @@ func (p *MerakiProvider) Configure(ctx context.Context, req provider.ConfigureRe
func (p *MerakiProvider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{
+ NewMulticastRendezvousPointResource,
NewNetworkResource,
NewNetworkDeviceClaimResource,
NewNetworkGroupPolicyResource,
@@ -238,11 +239,13 @@ func (p *MerakiProvider) Resources(ctx context.Context) []func() resource.Resour
NewSwitchQoSRuleResource,
NewSwitchQoSRuleOrderResource,
NewSwitchRoutingMulticastResource,
+ NewWirelessSSIDResource,
}
}
func (p *MerakiProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
+ NewMulticastRendezvousPointDataSource,
NewNetworkDataSource,
NewNetworkGroupPolicyDataSource,
NewNetworkSettingsDataSource,
@@ -262,6 +265,7 @@ func (p *MerakiProvider) DataSources(ctx context.Context) []func() datasource.Da
NewSwitchQoSRuleDataSource,
NewSwitchQoSRuleOrderDataSource,
NewSwitchRoutingMulticastDataSource,
+ NewWirelessSSIDDataSource,
}
}
diff --git a/internal/provider/resource_meraki_multicast_rendezvous_point.go b/internal/provider/resource_meraki_multicast_rendezvous_point.go
new file mode 100644
index 0000000..568aa8f
--- /dev/null
+++ b/internal/provider/resource_meraki_multicast_rendezvous_point.go
@@ -0,0 +1,253 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "context"
+ "fmt"
+ "net/url"
+ "strings"
+
+ "github.com/CiscoDevNet/terraform-provider-meraki/internal/provider/helpers"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/netascode/go-meraki"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin model
+
+// Ensure provider defined types fully satisfy framework interfaces
+var (
+ _ resource.Resource = &MulticastRendezvousPointResource{}
+ _ resource.ResourceWithImportState = &MulticastRendezvousPointResource{}
+)
+
+func NewMulticastRendezvousPointResource() resource.Resource {
+ return &MulticastRendezvousPointResource{}
+}
+
+type MulticastRendezvousPointResource struct {
+ client *meraki.Client
+}
+
+func (r *MulticastRendezvousPointResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_multicast_rendezvous_point"
+}
+
+func (r *MulticastRendezvousPointResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ // This description is used by the documentation generator and the language server.
+ MarkdownDescription: helpers.NewAttributeDescription("This resource can manage the `Multicast Rendezvous Point` configuration.").String,
+
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The id of the object",
+ Computed: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "network_id": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Network ID").String,
+ Required: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.RequiresReplace(),
+ },
+ },
+ "interface_ip": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The IP address of the interface where the RP needs to be created.").String,
+ Required: true,
+ },
+ "multicast_group": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("`Any`, or the IP address of a multicast group").String,
+ Required: true,
+ },
+ },
+ }
+}
+
+func (r *MulticastRendezvousPointResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ r.client = req.ProviderData.(*MerakiProviderData).Client
+}
+
+// End of section. //template:end model
+
+// Section below is generated&owned by "gen/generator.go". //template:begin create
+
+func (r *MulticastRendezvousPointResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan MulticastRendezvousPoint
+
+ // Read plan
+ diags := req.Plan.Get(ctx, &plan)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Create", plan.Id.ValueString()))
+
+ // Create object
+ body := plan.toBody(ctx, MulticastRendezvousPoint{})
+ res, err := r.client.Post(plan.getPath(), body)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (POST/PUT), got error: %s, %s", err, res.String()))
+ return
+ }
+ plan.Id = types.StringValue(res.Get("id").String())
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+
+ helpers.SetFlagImporting(ctx, false, resp.Private, &resp.Diagnostics)
+}
+
+// End of section. //template:end create
+
+// Section below is generated&owned by "gen/generator.go". //template:begin read
+
+func (r *MulticastRendezvousPointResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state MulticastRendezvousPoint
+
+ // Read state
+ diags := req.State.Get(ctx, &state)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Id.String()))
+ res, err := r.client.Get(state.getPath() + "/" + url.QueryEscape(state.Id.ValueString()))
+ if err != nil && strings.Contains(err.Error(), "StatusCode 404") {
+ resp.State.RemoveResource(ctx)
+ return
+ } else if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object (GET), got error: %s, %s", err, res.String()))
+ return
+ }
+
+ imp, diags := helpers.IsFlagImporting(ctx, req)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ // After `terraform import` we switch to a full read.
+ if imp {
+ state.fromBody(ctx, res)
+ } else {
+ state.fromBodyPartial(ctx, res)
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+
+ helpers.SetFlagImporting(ctx, false, resp.Private, &resp.Diagnostics)
+}
+
+// End of section. //template:end read
+
+// Section below is generated&owned by "gen/generator.go". //template:begin update
+
+func (r *MulticastRendezvousPointResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan, state MulticastRendezvousPoint
+
+ // Read plan
+ diags := req.Plan.Get(ctx, &plan)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Read state
+ diags = req.State.Get(ctx, &state)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.Id.ValueString()))
+
+ body := plan.toBody(ctx, state)
+ res, err := r.client.Put(plan.getPath()+"/"+url.QueryEscape(plan.Id.ValueString()), body)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (PUT), got error: %s, %s", err, res.String()))
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+}
+
+// End of section. //template:end update
+
+// Section below is generated&owned by "gen/generator.go". //template:begin delete
+
+func (r *MulticastRendezvousPointResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state MulticastRendezvousPoint
+
+ // Read state
+ diags := req.State.Get(ctx, &state)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Id.ValueString()))
+ res, err := r.client.Delete(state.getPath() + "/" + url.QueryEscape(state.Id.ValueString()))
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (DELETE), got error: %s, %s", err, res.String()))
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Delete finished successfully", state.Id.ValueString()))
+
+ resp.State.RemoveResource(ctx)
+}
+
+// End of section. //template:end delete
+
+// Section below is generated&owned by "gen/generator.go". //template:begin import
+func (r *MulticastRendezvousPointResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ idParts := strings.Split(req.ID, ",")
+
+ if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
+ resp.Diagnostics.AddError(
+ "Unexpected Import Identifier",
+ fmt.Sprintf("Expected import identifier with format: ,. Got: %q", req.ID),
+ )
+ return
+ }
+ resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("network_id"), idParts[0])...)
+ resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), idParts[1])...)
+
+ helpers.SetFlagImporting(ctx, true, resp.Private, &resp.Diagnostics)
+}
+
+// End of section. //template:end import
diff --git a/internal/provider/resource_meraki_multicast_rendezvous_point_test.go b/internal/provider/resource_meraki_multicast_rendezvous_point_test.go
new file mode 100644
index 0000000..f32e597
--- /dev/null
+++ b/internal/provider/resource_meraki_multicast_rendezvous_point_test.go
@@ -0,0 +1,97 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "os"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAcc
+
+func TestAccMerakiMulticastRendezvousPoint(t *testing.T) {
+ var checks []resource.TestCheckFunc
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_multicast_rendezvous_point.test", "interface_ip", "192.168.1.2"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_multicast_rendezvous_point.test", "multicast_group", "Any"))
+
+ var steps []resource.TestStep
+ if os.Getenv("SKIP_MINIMUM_TEST") == "" {
+ steps = append(steps, resource.TestStep{
+ Config: testAccMerakiMulticastRendezvousPointPrerequisitesConfig + testAccMerakiMulticastRendezvousPointConfig_minimum(),
+ })
+ }
+ steps = append(steps, resource.TestStep{
+ Config: testAccMerakiMulticastRendezvousPointPrerequisitesConfig + testAccMerakiMulticastRendezvousPointConfig_all(),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ })
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: steps,
+ })
+}
+
+// End of section. //template:end testAcc
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites
+
+const testAccMerakiMulticastRendezvousPointPrerequisitesConfig = `
+data "meraki_organization" "test" {
+ name = "Dev"
+}
+resource "meraki_network" "test" {
+ organization_id = data.meraki_organization.test.id
+ name = "Network1"
+ product_types = ["switch", "wireless"]
+}
+
+`
+
+// End of section. //template:end testPrerequisites
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccConfigMinimal
+
+func testAccMerakiMulticastRendezvousPointConfig_minimum() string {
+ config := `resource "meraki_multicast_rendezvous_point" "test" {` + "\n"
+ config += ` network_id = meraki_network.test.id` + "\n"
+ config += ` interface_ip = "192.168.1.2"` + "\n"
+ config += ` multicast_group = "Any"` + "\n"
+ config += `}` + "\n"
+ return config
+}
+
+// End of section. //template:end testAccConfigMinimal
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccConfigAll
+
+func testAccMerakiMulticastRendezvousPointConfig_all() string {
+ config := `resource "meraki_multicast_rendezvous_point" "test" {` + "\n"
+ config += ` network_id = meraki_network.test.id` + "\n"
+ config += ` interface_ip = "192.168.1.2"` + "\n"
+ config += ` multicast_group = "Any"` + "\n"
+ config += `}` + "\n"
+ return config
+}
+
+// End of section. //template:end testAccConfigAll
diff --git a/internal/provider/resource_meraki_network_device_claim.go b/internal/provider/resource_meraki_network_device_claim.go
index f9dc9ad..c775758 100644
--- a/internal/provider/resource_meraki_network_device_claim.go
+++ b/internal/provider/resource_meraki_network_device_claim.go
@@ -21,9 +21,10 @@ package provider
import (
"context"
"fmt"
+ "net/url"
+ "strings"
"github.com/CiscoDevNet/terraform-provider-meraki/internal/provider/helpers"
- "github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
@@ -31,7 +32,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/netascode/go-meraki"
- "github.com/tidwall/sjson"
)
// End of section. //template:end imports
@@ -126,6 +126,8 @@ func (r *NetworkDeviceClaimResource) Create(ctx context.Context, req resource.Cr
// End of section. //template:end create
+// Section below is generated&owned by "gen/generator.go". //template:begin read
+
func (r *NetworkDeviceClaimResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state NetworkDeviceClaim
@@ -136,30 +138,26 @@ func (r *NetworkDeviceClaimResource) Read(ctx context.Context, req resource.Read
}
tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Id.String()))
-
- res, err := r.client.Get(state.getDevicesPath())
- if err != nil {
- resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve inventory (GET), got error: %s, %s", err, res.String()))
+ res, err := r.client.Get(state.getPath() + "/" + url.QueryEscape(state.Id.ValueString()))
+ if err != nil && strings.Contains(err.Error(), "StatusCode 404") {
+ resp.State.RemoveResource(ctx)
+ return
+ } else if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object (GET), got error: %s, %s", err, res.String()))
return
}
- var serials, resultSerials []string
- state.Serials.ElementsAs(ctx, &serials, false)
- for _, serial := range serials {
- for _, device := range res.Array() {
- rSerial := device.Get("serial").String()
- if serial == rSerial {
- resultSerials = append(resultSerials, serial)
- }
- }
+ imp, diags := helpers.IsFlagImporting(ctx, req)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
}
- tflog.Debug(ctx, fmt.Sprintf("%s: Retrieved the following serials: %v", state.Id.ValueString(), resultSerials))
- v := make([]attr.Value, len(resultSerials))
- for r := range resultSerials {
- v[r] = types.StringValue(resultSerials[r])
+ // After `terraform import` we switch to a full read.
+ if imp {
+ state.fromBody(ctx, res)
+ } else {
+ state.fromBodyPartial(ctx, res)
}
- state.Serials = types.SetValueMust(types.StringType, v)
tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Id.ValueString()))
@@ -169,6 +167,10 @@ func (r *NetworkDeviceClaimResource) Read(ctx context.Context, req resource.Read
helpers.SetFlagImporting(ctx, false, resp.Private, &resp.Diagnostics)
}
+// End of section. //template:end read
+
+// Section below is generated&owned by "gen/generator.go". //template:begin update
+
func (r *NetworkDeviceClaimResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan, state NetworkDeviceClaim
@@ -186,52 +188,11 @@ func (r *NetworkDeviceClaimResource) Update(ctx context.Context, req resource.Up
tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.Id.ValueString()))
- var planSerials, stateSerials, claimSerials, removeSerials []string
- plan.Serials.ElementsAs(ctx, &planSerials, false)
- state.Serials.ElementsAs(ctx, &stateSerials, false)
-
- for _, planSerial := range planSerials {
- found := false
- for _, stateSerial := range stateSerials {
- if planSerial == stateSerial {
- found = true
- }
- }
- if !found {
- claimSerials = append(claimSerials, planSerial)
- }
- }
-
- for _, stateSerial := range stateSerials {
- found := false
- for _, planSerial := range planSerials {
- if planSerial == stateSerial {
- found = true
- }
- }
- if !found {
- removeSerials = append(removeSerials, stateSerial)
- }
- }
-
- tflog.Debug(ctx, fmt.Sprintf("%s: Serials to be claimed: %v", plan.Id.ValueString(), claimSerials))
- if len(claimSerials) > 0 {
- body, _ := sjson.Set("", "serials", claimSerials)
- res, err := r.client.Post(plan.getPath(), body)
- if err != nil {
- resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to claim devices to network, got error: %s, %s", err, res.String()))
- return
- }
- }
-
- tflog.Debug(ctx, fmt.Sprintf("%s: Serials to be removed: %v", plan.Id.ValueString(), removeSerials))
- for _, serial := range removeSerials {
- body, _ := sjson.Set("", "serial", serial)
- res, err := r.client.Post(plan.getRemovePath(), body)
- if err != nil {
- resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to remove device from network, got error: %s, %s", err, res.String()))
- return
- }
+ body := plan.toBody(ctx, state)
+ res, err := r.client.Put(plan.getPath()+"/"+url.QueryEscape(plan.Id.ValueString()), body)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (PUT), got error: %s, %s", err, res.String()))
+ return
}
tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.Id.ValueString()))
@@ -240,6 +201,10 @@ func (r *NetworkDeviceClaimResource) Update(ctx context.Context, req resource.Up
resp.Diagnostics.Append(diags...)
}
+// End of section. //template:end update
+
+// Section below is generated&owned by "gen/generator.go". //template:begin delete
+
func (r *NetworkDeviceClaimResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var state NetworkDeviceClaim
@@ -250,17 +215,10 @@ func (r *NetworkDeviceClaimResource) Delete(ctx context.Context, req resource.De
}
tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Id.ValueString()))
-
- var stateSerials []string
- state.Serials.ElementsAs(ctx, &stateSerials, false)
-
- for _, serial := range stateSerials {
- body, _ := sjson.Set("", "serial", serial)
- res, err := r.client.Post(state.getRemovePath(), body)
- if err != nil {
- resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to remove device from network, got error: %s, %s", err, res.String()))
- return
- }
+ res, err := r.client.Delete(state.getPath() + "/" + url.QueryEscape(state.Id.ValueString()))
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (DELETE), got error: %s, %s", err, res.String()))
+ return
}
tflog.Debug(ctx, fmt.Sprintf("%s: Delete finished successfully", state.Id.ValueString()))
@@ -268,5 +226,7 @@ func (r *NetworkDeviceClaimResource) Delete(ctx context.Context, req resource.De
resp.State.RemoveResource(ctx)
}
+// End of section. //template:end delete
+
// Section below is generated&owned by "gen/generator.go". //template:begin import
// End of section. //template:end import
diff --git a/internal/provider/resource_meraki_network_device_claim_test.go b/internal/provider/resource_meraki_network_device_claim_test.go
index a63828d..30b062b 100644
--- a/internal/provider/resource_meraki_network_device_claim_test.go
+++ b/internal/provider/resource_meraki_network_device_claim_test.go
@@ -87,10 +87,14 @@ func testAccMerakiNetworkDeviceClaimConfig_minimum() string {
// End of section. //template:end testAccConfigMinimal
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccConfigAll
+
func testAccMerakiNetworkDeviceClaimConfig_all() string {
config := `resource "meraki_network_device_claim" "test" {` + "\n"
config += ` network_id = meraki_network.test.id` + "\n"
- config += ` serials = [var.CLAIM_SERIAL_1, var.CLAIM_SERIAL_2]` + "\n"
+ config += ` serials = [var.CLAIM_SERIAL_1]` + "\n"
config += `}` + "\n"
return config
}
+
+// End of section. //template:end testAccConfigAll
diff --git a/internal/provider/resource_meraki_organization_inventory_claim.go b/internal/provider/resource_meraki_organization_inventory_claim.go
index 9eeb253..246281f 100644
--- a/internal/provider/resource_meraki_organization_inventory_claim.go
+++ b/internal/provider/resource_meraki_organization_inventory_claim.go
@@ -21,9 +21,10 @@ package provider
import (
"context"
"fmt"
+ "net/url"
+ "strings"
"github.com/CiscoDevNet/terraform-provider-meraki/internal/provider/helpers"
- "github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
@@ -31,7 +32,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/netascode/go-meraki"
- "github.com/tidwall/sjson"
)
// End of section. //template:end imports
@@ -126,6 +126,8 @@ func (r *OrganizationInventoryClaimResource) Create(ctx context.Context, req res
// End of section. //template:end create
+// Section below is generated&owned by "gen/generator.go". //template:begin read
+
func (r *OrganizationInventoryClaimResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state OrganizationInventoryClaim
@@ -136,30 +138,26 @@ func (r *OrganizationInventoryClaimResource) Read(ctx context.Context, req resou
}
tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Id.String()))
-
- res, err := r.client.Get(state.getDevicesPath())
- if err != nil {
- resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve inventory (GET), got error: %s, %s", err, res.String()))
+ res, err := r.client.Get(state.getPath() + "/" + url.QueryEscape(state.Id.ValueString()))
+ if err != nil && strings.Contains(err.Error(), "StatusCode 404") {
+ resp.State.RemoveResource(ctx)
+ return
+ } else if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object (GET), got error: %s, %s", err, res.String()))
return
}
- var serials, resultSerials []string
- state.Serials.ElementsAs(ctx, &serials, false)
- for _, serial := range serials {
- for _, device := range res.Array() {
- rSerial := device.Get("serial").String()
- if serial == rSerial {
- resultSerials = append(resultSerials, serial)
- }
- }
+ imp, diags := helpers.IsFlagImporting(ctx, req)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
}
- tflog.Debug(ctx, fmt.Sprintf("%s: Retrieved the following serials: %v", state.Id.ValueString(), resultSerials))
- v := make([]attr.Value, len(resultSerials))
- for r := range resultSerials {
- v[r] = types.StringValue(resultSerials[r])
+ // After `terraform import` we switch to a full read.
+ if imp {
+ state.fromBody(ctx, res)
+ } else {
+ state.fromBodyPartial(ctx, res)
}
- state.Serials = types.SetValueMust(types.StringType, v)
tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Id.ValueString()))
@@ -169,6 +167,10 @@ func (r *OrganizationInventoryClaimResource) Read(ctx context.Context, req resou
helpers.SetFlagImporting(ctx, false, resp.Private, &resp.Diagnostics)
}
+// End of section. //template:end read
+
+// Section below is generated&owned by "gen/generator.go". //template:begin update
+
func (r *OrganizationInventoryClaimResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan, state OrganizationInventoryClaim
@@ -186,52 +188,11 @@ func (r *OrganizationInventoryClaimResource) Update(ctx context.Context, req res
tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.Id.ValueString()))
- var planSerials, stateSerials, claimSerials, releaseSerials []string
- plan.Serials.ElementsAs(ctx, &planSerials, false)
- state.Serials.ElementsAs(ctx, &stateSerials, false)
-
- for _, planSerial := range planSerials {
- found := false
- for _, stateSerial := range stateSerials {
- if planSerial == stateSerial {
- found = true
- }
- }
- if !found {
- claimSerials = append(claimSerials, planSerial)
- }
- }
-
- for _, stateSerial := range stateSerials {
- found := false
- for _, planSerial := range planSerials {
- if planSerial == stateSerial {
- found = true
- }
- }
- if !found {
- releaseSerials = append(releaseSerials, stateSerial)
- }
- }
-
- tflog.Debug(ctx, fmt.Sprintf("%s: Serials to be claimed: %v", plan.Id.ValueString(), claimSerials))
- if len(claimSerials) > 0 {
- body, _ := sjson.Set("", "serials", claimSerials)
- res, err := r.client.Post(plan.getPath(), body)
- if err != nil {
- resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to claim inventory, got error: %s, %s", err, res.String()))
- return
- }
- }
-
- tflog.Debug(ctx, fmt.Sprintf("%s: Serials to be released: %v", plan.Id.ValueString(), releaseSerials))
- if len(releaseSerials) > 0 {
- body, _ := sjson.Set("", "serials", releaseSerials)
- res, err := r.client.Post(plan.getReleasePath(), body)
- if err != nil {
- resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to release inventory, got error: %s, %s", err, res.String()))
- return
- }
+ body := plan.toBody(ctx, state)
+ res, err := r.client.Put(plan.getPath()+"/"+url.QueryEscape(plan.Id.ValueString()), body)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (PUT), got error: %s, %s", err, res.String()))
+ return
}
tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.Id.ValueString()))
@@ -240,6 +201,10 @@ func (r *OrganizationInventoryClaimResource) Update(ctx context.Context, req res
resp.Diagnostics.Append(diags...)
}
+// End of section. //template:end update
+
+// Section below is generated&owned by "gen/generator.go". //template:begin delete
+
func (r *OrganizationInventoryClaimResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var state OrganizationInventoryClaim
@@ -250,11 +215,9 @@ func (r *OrganizationInventoryClaimResource) Delete(ctx context.Context, req res
}
tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Id.ValueString()))
-
- body := state.toBody(ctx, OrganizationInventoryClaim{})
- res, err := r.client.Post(state.getReleasePath(), body)
+ res, err := r.client.Delete(state.getPath() + "/" + url.QueryEscape(state.Id.ValueString()))
if err != nil {
- resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to release inventory, got error: %s, %s", err, res.String()))
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (DELETE), got error: %s, %s", err, res.String()))
return
}
@@ -263,5 +226,7 @@ func (r *OrganizationInventoryClaimResource) Delete(ctx context.Context, req res
resp.State.RemoveResource(ctx)
}
+// End of section. //template:end delete
+
// Section below is generated&owned by "gen/generator.go". //template:begin import
// End of section. //template:end import
diff --git a/internal/provider/resource_meraki_organization_inventory_claim_test.go b/internal/provider/resource_meraki_organization_inventory_claim_test.go
index debe595..edf7e9e 100644
--- a/internal/provider/resource_meraki_organization_inventory_claim_test.go
+++ b/internal/provider/resource_meraki_organization_inventory_claim_test.go
@@ -81,10 +81,14 @@ func testAccMerakiOrganizationInventoryClaimConfig_minimum() string {
// End of section. //template:end testAccConfigMinimal
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccConfigAll
+
func testAccMerakiOrganizationInventoryClaimConfig_all() string {
config := `resource "meraki_organization_inventory_claim" "test" {` + "\n"
config += ` organization_id = data.meraki_organization.test.id` + "\n"
- config += ` serials = [var.CLAIM_SERIAL_1, var.CLAIM_SERIAL_2]` + "\n"
+ config += ` serials = [var.CLAIM_SERIAL_1]` + "\n"
config += `}` + "\n"
return config
}
+
+// End of section. //template:end testAccConfigAll
diff --git a/internal/provider/resource_meraki_switch_link_aggregation_test.go b/internal/provider/resource_meraki_switch_link_aggregation_test.go
index 2c9a601..81e9d61 100644
--- a/internal/provider/resource_meraki_switch_link_aggregation_test.go
+++ b/internal/provider/resource_meraki_switch_link_aggregation_test.go
@@ -78,19 +78,17 @@ func testAccMerakiSwitchLinkAggregationConfig_minimum() string {
// End of section. //template:end testAccConfigMinimal
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccConfigAll
+
func testAccMerakiSwitchLinkAggregationConfig_all() string {
config := `resource "meraki_switch_link_aggregation" "test" {` + "\n"
- config += ` network_id = meraki_network.test.id` + "\n"
- config += ` switch_ports = [` + "\n"
- config += ` {` + "\n"
- config += ` port_id = "1"` + "\n"
- config += ` serial = tolist(meraki_network_device_claim.test.serials)[0]` + "\n"
- config += ` },` + "\n"
- config += ` {` + "\n"
- config += ` port_id = "2"` + "\n"
- config += ` serial = tolist(meraki_network_device_claim.test.serials)[0]` + "\n"
- config += ` }` + "\n"
- config += ` ]` + "\n"
+ config += ` network_id = meraki_network.test.id` + "\n"
+ config += ` switch_ports = [{` + "\n"
+ config += ` port_id = "1"` + "\n"
+ config += ` serial = tolist(meraki_network_device_claim.test.serials)[0]` + "\n"
+ config += ` }]` + "\n"
config += `}` + "\n"
return config
}
+
+// End of section. //template:end testAccConfigAll
diff --git a/internal/provider/resource_meraki_wireless_ssid.go b/internal/provider/resource_meraki_wireless_ssid.go
new file mode 100644
index 0000000..fb10da0
--- /dev/null
+++ b/internal/provider/resource_meraki_wireless_ssid.go
@@ -0,0 +1,692 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "context"
+ "fmt"
+ "net/url"
+ "strings"
+
+ "github.com/CiscoDevNet/terraform-provider-meraki/internal/provider/helpers"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/netascode/go-meraki"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin model
+
+// Ensure provider defined types fully satisfy framework interfaces
+var (
+ _ resource.Resource = &WirelessSSIDResource{}
+ _ resource.ResourceWithImportState = &WirelessSSIDResource{}
+)
+
+func NewWirelessSSIDResource() resource.Resource {
+ return &WirelessSSIDResource{}
+}
+
+type WirelessSSIDResource struct {
+ client *meraki.Client
+}
+
+func (r *WirelessSSIDResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_wireless_ssid"
+}
+
+func (r *WirelessSSIDResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ // This description is used by the documentation generator and the language server.
+ MarkdownDescription: helpers.NewAttributeDescription("This resource can manage the `Wireless SSID` configuration.").String,
+
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The id of the object",
+ Computed: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "network_id": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Network ID").String,
+ Required: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.RequiresReplace(),
+ },
+ },
+ "number": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Wireless SSID number").String,
+ Required: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.RequiresReplace(),
+ },
+ },
+ "adult_content_filtering_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Boolean indicating whether or not adult content will be blocked").String,
+ Optional: true,
+ },
+ "auth_mode": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The association control method for the SSID (`open`, `open-enhanced`, `psk`, `open-with-radius`, `open-with-nac`, `8021x-meraki`, `8021x-nac`, `8021x-radius`, `8021x-google`, `8021x-entra`, `8021x-localradius`, `ipsk-with-radius`, `ipsk-without-radius` or `ipsk-with-nac`)").AddStringEnumDescription("8021x-entra", "8021x-google", "8021x-localradius", "8021x-meraki", "8021x-nac", "8021x-radius", "ipsk-with-nac", "ipsk-with-radius", "ipsk-without-radius", "open", "open-enhanced", "open-with-nac", "open-with-radius", "psk").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("8021x-entra", "8021x-google", "8021x-localradius", "8021x-meraki", "8021x-nac", "8021x-radius", "ipsk-with-nac", "ipsk-with-radius", "ipsk-without-radius", "open", "open-enhanced", "open-with-nac", "open-with-radius", "psk"),
+ },
+ },
+ "available_on_all_aps": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Boolean indicating whether all APs should broadcast the SSID or if it should be restricted to APs matching any availability tags. Can only be false if the SSID has availability tags.").String,
+ Optional: true,
+ },
+ "band_selection": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The client-serving radio frequencies of this SSID in the default indoor RF profile. (`Dual band operation`, `5 GHz band only` or `Dual band operation with Band Steering`)").String,
+ Optional: true,
+ },
+ "concentrator_network_id": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The concentrator to use when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`.").String,
+ Optional: true,
+ },
+ "default_vlan_id": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The default VLAN ID used for `all other APs`. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`").String,
+ Optional: true,
+ },
+ "disassociate_clients_on_vpn_failover": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Disassociate clients when `VPN` concentrator failover occurs in order to trigger clients to re-associate and generate new DHCP requests. This param is only valid if ipAssignmentMode is `VPN`.").String,
+ Optional: true,
+ },
+ "enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not the SSID is enabled").String,
+ Optional: true,
+ },
+ "encryption_mode": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The psk encryption mode for the SSID (`wep` or `wpa`). This param is only valid if the authMode is `psk`").AddStringEnumDescription("open", "wep", "wpa", "wpa-eap").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("open", "wep", "wpa", "wpa-eap"),
+ },
+ },
+ "enterprise_admin_access": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not an SSID is accessible by `enterprise` administrators (`access disabled` or `access enabled`)").AddStringEnumDescription("access disabled", "access enabled").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("access disabled", "access enabled"),
+ },
+ },
+ "ip_assignment_mode": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The client IP assignment mode (`NAT mode`, `Bridge mode`, `Layer 3 roaming`, `Ethernet over GRE`, `Layer 3 roaming with a concentrator` or `VPN`)").String,
+ Optional: true,
+ },
+ "lan_isolation_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Boolean indicating whether Layer 2 LAN isolation should be enabled or disabled. Only configurable when ipAssignmentMode is `Bridge mode`.").String,
+ Optional: true,
+ },
+ "mandatory_dhcp_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("If true, Mandatory DHCP will enforce that clients connecting to this SSID must use the IP address assigned by the DHCP server. Clients who use a static IP address won`t be able to associate.").String,
+ Optional: true,
+ },
+ "min_bitrate": schema.Float64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The minimum bitrate in Mbps of this SSID in the default indoor RF profile. (`1`, `2`, `5.5`, `6`, `9`, `11`, `12`, `18`, `24`, `36`, `48` or `54`)").String,
+ Optional: true,
+ },
+ "name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The name of the SSID").String,
+ Required: true,
+ },
+ "per_client_bandwidth_limit_down": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The download bandwidth limit in Kbps. (0 represents no limit.)").String,
+ Optional: true,
+ },
+ "per_client_bandwidth_limit_up": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The upload bandwidth limit in Kbps. (0 represents no limit.)").String,
+ Optional: true,
+ },
+ "per_ssid_bandwidth_limit_down": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The total download bandwidth limit in Kbps. (0 represents no limit.)").String,
+ Optional: true,
+ },
+ "per_ssid_bandwidth_limit_up": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The total upload bandwidth limit in Kbps. (0 represents no limit.)").String,
+ Optional: true,
+ },
+ "psk": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The passkey for the SSID. This param is only valid if the authMode is `psk`").String,
+ Optional: true,
+ },
+ "radius_accounting_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not RADIUS accounting is enabled. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius`").String,
+ Optional: true,
+ },
+ "radius_accounting_interim_interval": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The interval (in seconds) in which accounting information is updated and sent to the RADIUS accounting server.").String,
+ Optional: true,
+ },
+ "radius_attribute_for_group_policies": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify the RADIUS attribute used to look up group policies (`Filter-Id`, `Reply-Message`, `Airespace-ACL-Name` or `Aruba-User-Role`). Access points must receive this attribute in the RADIUS Access-Accept message").AddStringEnumDescription("Airespace-ACL-Name", "Aruba-User-Role", "Filter-Id", "Reply-Message").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("Airespace-ACL-Name", "Aruba-User-Role", "Filter-Id", "Reply-Message"),
+ },
+ },
+ "radius_authentication_nas_id": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The template of the NAS identifier to be used for RADIUS authentication (ex. $NODE_MAC$:$VAP_NUM$).").String,
+ Optional: true,
+ },
+ "radius_called_station_id": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The template of the called station identifier to be used for RADIUS (ex. $NODE_MAC$:$VAP_NUM$).").String,
+ Optional: true,
+ },
+ "radius_coa_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("If true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server.").String,
+ Optional: true,
+ },
+ "radius_failover_policy": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("This policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable (`Deny access` or `Allow access`)").AddStringEnumDescription("Allow access", "Deny access").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("Allow access", "Deny access"),
+ },
+ },
+ "radius_fallback_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not higher priority RADIUS servers should be retried after 60 seconds.").String,
+ Optional: true,
+ },
+ "radius_guest_vlan_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not RADIUS Guest VLAN is enabled. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode").String,
+ Optional: true,
+ },
+ "radius_guest_vlan_id": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("VLAN ID of the RADIUS Guest VLAN. This param is only valid if the authMode is `open-with-radius` and addressing mode is not set to `isolated` or `nat` mode").String,
+ Optional: true,
+ },
+ "radius_load_balancing_policy": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("This policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts (`Strict priority order` or `Round robin`)").AddStringEnumDescription("Round robin", "Strict priority order").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("Round robin", "Strict priority order"),
+ },
+ },
+ "radius_override": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("If true, the RADIUS response can override VLAN tag. This is not valid when ipAssignmentMode is `NAT mode`.").String,
+ Optional: true,
+ },
+ "radius_proxy_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("If true, Meraki devices will proxy RADIUS messages through the Meraki cloud to the configured RADIUS auth and accounting servers.").String,
+ Optional: true,
+ },
+ "radius_server_attempts_limit": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The maximum number of transmit attempts after which a RADIUS server is failed over (must be between 1-5).").String,
+ Optional: true,
+ },
+ "radius_server_timeout": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The amount of time for which a RADIUS client waits for a reply from the RADIUS server (must be between 1-10 seconds).").String,
+ Optional: true,
+ },
+ "radius_testing_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("If true, Meraki devices will periodically send Access-Request messages to configured RADIUS servers using identity `meraki_8021x_test` to ensure that the RADIUS servers are reachable.").String,
+ Optional: true,
+ },
+ "secondary_concentrator_network_id": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The secondary concentrator to use when the ipAssignmentMode is `VPN`. If configured, the APs will switch to using this concentrator if the primary concentrator is unreachable. This param is optional. (`disabled` represents no secondary concentrator.)").String,
+ Optional: true,
+ },
+ "splash_page": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The type of splash page for the SSID (`None`, `Click-through splash page`, `Billing`, `Password-protected with Meraki RADIUS`, `Password-protected with custom RADIUS`, `Password-protected with Active Directory`, `Password-protected with LDAP`, `SMS authentication`, `Systems Manager Sentry`, `Facebook Wi-Fi`, `Google OAuth`, `Microsoft Entra ID`, `Sponsored guest`, `Cisco ISE` or `Google Apps domain`). This attribute is not supported for template children.").AddStringEnumDescription("Billing", "Cisco ISE", "Click-through splash page", "Facebook Wi-Fi", "Google Apps domain", "Google OAuth", "Microsoft Entra ID", "None", "Password-protected with Active Directory", "Password-protected with LDAP", "Password-protected with Meraki RADIUS", "Password-protected with custom RADIUS", "SMS authentication", "Sponsored guest", "Systems Manager Sentry").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("Billing", "Cisco ISE", "Click-through splash page", "Facebook Wi-Fi", "Google Apps domain", "Google OAuth", "Microsoft Entra ID", "None", "Password-protected with Active Directory", "Password-protected with LDAP", "Password-protected with Meraki RADIUS", "Password-protected with custom RADIUS", "SMS authentication", "Sponsored guest", "Systems Manager Sentry"),
+ },
+ },
+ "use_vlan_tagging": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not traffic should be directed to use specific VLANs. This param is only valid if the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`").String,
+ Optional: true,
+ },
+ "visible": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Boolean indicating whether APs should advertise or hide this SSID. APs will only broadcast this SSID if set to true").String,
+ Optional: true,
+ },
+ "vlan_id": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The VLAN ID used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Layer 3 roaming with a concentrator` or `VPN`").String,
+ Optional: true,
+ },
+ "walled_garden_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Allow access to a configurable list of IP ranges, which users may access prior to sign-on.").String,
+ Optional: true,
+ },
+ "wpa_encryption_mode": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The types of WPA encryption. (`WPA1 only`, `WPA1 and WPA2`, `WPA2 only`, `WPA3 Transition Mode`, `WPA3 only` or `WPA3 192-bit Security`)").AddStringEnumDescription("WPA1 and WPA2", "WPA1 only", "WPA2 only", "WPA3 192-bit Security", "WPA3 Transition Mode", "WPA3 only").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("WPA1 and WPA2", "WPA1 only", "WPA2 only", "WPA3 192-bit Security", "WPA3 Transition Mode", "WPA3 only"),
+ },
+ },
+ "active_directory_credentials_logon_name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The logon name of the Active Directory account.").String,
+ Optional: true,
+ },
+ "active_directory_credentials_password": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The password to the Active Directory user account.").String,
+ Optional: true,
+ },
+ "active_directory_servers": schema.ListNestedAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The Active Directory servers to be used for authentication.").String,
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "host": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("IP address (or FQDN) of your Active Directory server.").String,
+ Required: true,
+ },
+ "port": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("(Optional) UDP port the Active Directory server listens on. By default, uses port 3268.").String,
+ Optional: true,
+ },
+ },
+ },
+ },
+ "dns_rewrite_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Boolean indicating whether or not DNS server rewrite is enabled. If disabled, upstream DNS will be used").String,
+ Optional: true,
+ },
+ "dns_rewrite_dns_custom_nameservers": schema.ListAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("User specified DNS servers (up to two servers)").String,
+ ElementType: types.StringType,
+ Optional: true,
+ },
+ "dot11r_adaptive": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("(Optional) Whether 802.11r is adaptive or not.").String,
+ Optional: true,
+ },
+ "dot11r_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether 802.11r is enabled or not.").String,
+ Optional: true,
+ },
+ "dot11w_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether 802.11w is enabled or not.").String,
+ Optional: true,
+ },
+ "dot11w_required": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("(Optional) Whether 802.11w is required or not.").String,
+ Optional: true,
+ },
+ "gre_key": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Optional numerical identifier that will add the GRE key field to the GRE header. Used to identify an individual traffic flow within a tunnel.").String,
+ Optional: true,
+ },
+ "gre_concentrator_host": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The EoGRE concentrator`s IP or FQDN. This param is required when ipAssignmentMode is `Ethernet over GRE`.").String,
+ Optional: true,
+ },
+ "ldap_base_distinguished_name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The base distinguished name of users on the LDAP server.").String,
+ Optional: true,
+ },
+ "ldap_credentials_distinguished_name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The distinguished name of the LDAP user account (example: cn=user,dc=meraki,dc=com).").String,
+ Optional: true,
+ },
+ "ldap_credentials_password": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The password of the LDAP user account.").String,
+ Optional: true,
+ },
+ "ldap_server_ca_certificate_contents": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The contents of the CA certificate. Must be in PEM or DER format.").String,
+ Optional: true,
+ },
+ "ldap_servers": schema.ListNestedAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The LDAP servers to be used for authentication.").String,
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "host": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("IP address (or FQDN) of your LDAP server.").String,
+ Required: true,
+ },
+ "port": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("UDP port the LDAP server listens on.").String,
+ Required: true,
+ },
+ },
+ },
+ },
+ "local_radius_cache_timeout": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The duration (in seconds) for which LDAP and OCSP lookups are cached.").String,
+ Optional: true,
+ },
+ "local_radius_certificate_authentication_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not to use EAP-TLS certificate-based authentication to validate wireless clients.").String,
+ Optional: true,
+ },
+ "local_radius_certificate_authentication_ocsp_responder_url": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("(Optional) The URL of the OCSP responder to verify client certificate status.").String,
+ Optional: true,
+ },
+ "local_radius_certificate_authentication_use_ldap": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not to verify the certificate with LDAP.").String,
+ Optional: true,
+ },
+ "local_radius_certificate_authentication_use_ocsp": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not to verify the certificate with OCSP.").String,
+ Optional: true,
+ },
+ "local_radius_certificate_authentication_client_root_ca_certificate_contents": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The contents of the Client CA Certificate. Must be in PEM or DER format.").String,
+ Optional: true,
+ },
+ "local_radius_password_authentication_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not to use EAP-TTLS/PAP or PEAP-GTC password-based authentication via LDAP lookup.").String,
+ Optional: true,
+ },
+ "named_vlans_radius_guest_vlan_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not RADIUS guest named VLAN is enabled.").String,
+ Optional: true,
+ },
+ "named_vlans_radius_guest_vlan_name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("RADIUS guest VLAN name.").String,
+ Optional: true,
+ },
+ "named_vlans_tagging_default_vlan_name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The default VLAN name used to tag traffic in the absence of a matching AP tag.").String,
+ Optional: true,
+ },
+ "named_vlans_tagging_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Whether or not traffic should be directed to use specific VLAN names.").String,
+ Optional: true,
+ },
+ "named_vlans_tagging_by_ap_tags": schema.ListNestedAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The list of AP tags and VLAN names used for named VLAN tagging. If an AP has a tag matching one in the list, then traffic on this SSID will be directed to use the VLAN name associated to the tag.").String,
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "vlan_name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("VLAN name that will be used to tag traffic.").String,
+ Optional: true,
+ },
+ "tags": schema.ListAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("List of AP tags.").String,
+ ElementType: types.StringType,
+ Optional: true,
+ },
+ },
+ },
+ },
+ "oauth_allowed_domains": schema.ListAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("(Optional) The list of domains allowed access to the network.").String,
+ ElementType: types.StringType,
+ Optional: true,
+ },
+ "speed_burst_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Boolean indicating whether or not to allow users to temporarily exceed the bandwidth limit for short periods while still keeping them under the bandwidth limit over time.").String,
+ Optional: true,
+ },
+ "ap_tags_and_vlan_ids": schema.ListNestedAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The list of tags and VLAN IDs used for VLAN tagging. This param is only valid when the ipAssignmentMode is `Bridge mode` or `Layer 3 roaming`").String,
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "vlan_id": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Numerical identifier that is assigned to the VLAN").String,
+ Optional: true,
+ },
+ "tags": schema.ListAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Array of AP tags").String,
+ ElementType: types.StringType,
+ Optional: true,
+ },
+ },
+ },
+ },
+ "availability_tags": schema.ListAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Accepts a list of tags for this SSID. If availableOnAllAps is false, then the SSID will only be broadcast by APs with tags matching any of the tags in this list.").String,
+ ElementType: types.StringType,
+ Optional: true,
+ },
+ "radius_accounting_servers": schema.ListNestedAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The RADIUS accounting 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius` and radiusAccountingEnabled is `true`").String,
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "ca_certificate": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Certificate used for authorization for the RADSEC Server").String,
+ Optional: true,
+ },
+ "host": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("IP address (or FQDN) to which the APs will send RADIUS accounting messages").String,
+ Required: true,
+ },
+ "port": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Port on the RADIUS server that is listening for accounting messages").String,
+ Optional: true,
+ },
+ "radsec_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Use RADSEC (TLS over TCP) to connect to this RADIUS accounting server. Requires radiusProxyEnabled.").String,
+ Optional: true,
+ },
+ "secret": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Shared key used to authenticate messages between the APs and RADIUS server").String,
+ Optional: true,
+ },
+ },
+ },
+ },
+ "radius_servers": schema.ListNestedAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The RADIUS 802.1X servers to be used for authentication. This param is only valid if the authMode is `open-with-radius`, `8021x-radius` or `ipsk-with-radius`").String,
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "ca_certificate": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Certificate used for authorization for the RADSEC Server").String,
+ Optional: true,
+ },
+ "host": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("IP address (or FQDN) of your RADIUS server").String,
+ Required: true,
+ },
+ "open_roaming_certificate_id": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The ID of the Openroaming Certificate attached to radius server.").String,
+ Optional: true,
+ },
+ "port": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("UDP port the RADIUS server listens on for Access-requests").String,
+ Optional: true,
+ },
+ "radsec_enabled": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Use RADSEC (TLS over TCP) to connect to this RADIUS server. Requires radiusProxyEnabled.").String,
+ Optional: true,
+ },
+ "secret": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("RADIUS client shared secret").String,
+ Optional: true,
+ },
+ },
+ },
+ },
+ "splash_guest_sponsor_domains": schema.ListAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Array of valid sponsor email domains for sponsored guest splash type.").String,
+ ElementType: types.StringType,
+ Optional: true,
+ },
+ "walled_garden_ranges": schema.ListAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify your walled garden by entering an array of addresses, ranges using CIDR notation, domain names, and domain wildcards (e.g. `192.168.1.1/24`, `192.168.37.10/32`, `www.yahoo.com`, `*.google.com`]). Meraki`s splash page is automatically included in your walled garden.").String,
+ ElementType: types.StringType,
+ Optional: true,
+ },
+ },
+ }
+}
+
+func (r *WirelessSSIDResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ r.client = req.ProviderData.(*MerakiProviderData).Client
+}
+
+// End of section. //template:end model
+
+func (r *WirelessSSIDResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan WirelessSSID
+
+ // Read plan
+ diags := req.Plan.Get(ctx, &plan)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Create", plan.Id.ValueString()))
+
+ // Create object
+ body := plan.toBody(ctx, WirelessSSID{})
+ res, err := r.client.Put(plan.getPath()+"/"+url.QueryEscape(plan.Id.ValueString()), body)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (POST/PUT), got error: %s, %s", err, res.String()))
+ return
+ }
+ plan.Id = types.StringValue(res.Get("number").String())
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+
+ helpers.SetFlagImporting(ctx, false, resp.Private, &resp.Diagnostics)
+}
+
+// Section below is generated&owned by "gen/generator.go". //template:begin read
+
+func (r *WirelessSSIDResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state WirelessSSID
+
+ // Read state
+ diags := req.State.Get(ctx, &state)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Id.String()))
+ res, err := r.client.Get(state.getPath())
+ if err != nil && strings.Contains(err.Error(), "StatusCode 404") {
+ resp.State.RemoveResource(ctx)
+ return
+ } else if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object (GET), got error: %s, %s", err, res.String()))
+ return
+ }
+
+ imp, diags := helpers.IsFlagImporting(ctx, req)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ // After `terraform import` we switch to a full read.
+ if imp {
+ state.fromBody(ctx, res)
+ } else {
+ state.fromBodyPartial(ctx, res)
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+
+ helpers.SetFlagImporting(ctx, false, resp.Private, &resp.Diagnostics)
+}
+
+// End of section. //template:end read
+
+// Section below is generated&owned by "gen/generator.go". //template:begin update
+
+func (r *WirelessSSIDResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan, state WirelessSSID
+
+ // Read plan
+ diags := req.Plan.Get(ctx, &plan)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Read state
+ diags = req.State.Get(ctx, &state)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.Id.ValueString()))
+
+ body := plan.toBody(ctx, state)
+ res, err := r.client.Put(plan.getPath(), body)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (PUT), got error: %s, %s", err, res.String()))
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+}
+
+// End of section. //template:end update
+
+// Section below is generated&owned by "gen/generator.go". //template:begin delete
+
+func (r *WirelessSSIDResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state WirelessSSID
+
+ // Read state
+ diags := req.State.Get(ctx, &state)
+ if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Id.ValueString()))
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Delete finished successfully", state.Id.ValueString()))
+
+ resp.State.RemoveResource(ctx)
+}
+
+// End of section. //template:end delete
+
+// Section below is generated&owned by "gen/generator.go". //template:begin import
+func (r *WirelessSSIDResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ idParts := strings.Split(req.ID, ",")
+
+ if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
+ resp.Diagnostics.AddError(
+ "Unexpected Import Identifier",
+ fmt.Sprintf("Expected import identifier with format: ,. Got: %q", req.ID),
+ )
+ return
+ }
+ resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("network_id"), idParts[0])...)
+ resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("number"), idParts[1])...)
+
+ helpers.SetFlagImporting(ctx, true, resp.Private, &resp.Diagnostics)
+}
+
+// End of section. //template:end import
diff --git a/internal/provider/resource_meraki_wireless_ssid_test.go b/internal/provider/resource_meraki_wireless_ssid_test.go
new file mode 100644
index 0000000..c513a69
--- /dev/null
+++ b/internal/provider/resource_meraki_wireless_ssid_test.go
@@ -0,0 +1,229 @@
+// Copyright © 2024 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+// Section below is generated&owned by "gen/generator.go". //template:begin imports
+import (
+ "os"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+// End of section. //template:end imports
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAcc
+
+func TestAccMerakiWirelessSSID(t *testing.T) {
+ var checks []resource.TestCheckFunc
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "number", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "adult_content_filtering_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "auth_mode", "8021x-radius"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "available_on_all_aps", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "band_selection", "5 GHz band only"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "default_vlan_id", "1"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "disassociate_clients_on_vpn_failover", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "encryption_mode", "wpa"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "ip_assignment_mode", "Bridge mode"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "lan_isolation_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "mandatory_dhcp_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "min_bitrate", "5.5"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "name", "My SSID"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "per_client_bandwidth_limit_down", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "per_client_bandwidth_limit_up", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "per_ssid_bandwidth_limit_down", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "per_ssid_bandwidth_limit_up", "0"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "psk", "deadbeef"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_accounting_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_accounting_interim_interval", "5"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_attribute_for_group_policies", "Filter-Id"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_authentication_nas_id", "00-11-22-33-44-55:AP1"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_called_station_id", "00-11-22-33-44-55:AP1"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_coa_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_failover_policy", "Deny access"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_fallback_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_guest_vlan_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_guest_vlan_id", "1"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_load_balancing_policy", "Round robin"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_override", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_proxy_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_server_attempts_limit", "5"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_server_timeout", "5"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_testing_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "secondary_concentrator_network_id", "disabled"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "splash_page", "Click-through splash page"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "use_vlan_tagging", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "visible", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "vlan_id", "10"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "walled_garden_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "wpa_encryption_mode", "WPA2 only"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "dot11r_adaptive", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "dot11r_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "dot11w_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "dot11w_required", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "gre_key", "5"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "gre_concentrator_host", "192.168.1.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "local_radius_cache_timeout", "60"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "local_radius_certificate_authentication_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "local_radius_certificate_authentication_ocsp_responder_url", "http://ocsp-server.example.com"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "local_radius_certificate_authentication_use_ldap", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "local_radius_certificate_authentication_use_ocsp", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "local_radius_certificate_authentication_client_root_ca_certificate_contents", "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "local_radius_password_authentication_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "named_vlans_radius_guest_vlan_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "named_vlans_tagging_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "speed_burst_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "ap_tags_and_vlan_ids.0.vlan_id", "100"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "ap_tags_and_vlan_ids.0.tags.0", "tag1"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "availability_tags.0", "tag1"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_servers.0.ca_certificate", "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_servers.0.host", "0.0.0.0"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_servers.0.port", "3000"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_servers.0.radsec_enabled", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("meraki_wireless_ssid.test", "radius_servers.0.secret", "secret-string"))
+
+ var steps []resource.TestStep
+ if os.Getenv("SKIP_MINIMUM_TEST") == "" {
+ steps = append(steps, resource.TestStep{
+ Config: testAccMerakiWirelessSSIDPrerequisitesConfig + testAccMerakiWirelessSSIDConfig_minimum(),
+ })
+ }
+ steps = append(steps, resource.TestStep{
+ Config: testAccMerakiWirelessSSIDPrerequisitesConfig + testAccMerakiWirelessSSIDConfig_all(),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ })
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: steps,
+ })
+}
+
+// End of section. //template:end testAcc
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testPrerequisites
+
+const testAccMerakiWirelessSSIDPrerequisitesConfig = `
+data "meraki_organization" "test" {
+ name = "Dev"
+}
+resource "meraki_network" "test" {
+ organization_id = data.meraki_organization.test.id
+ name = "Network1"
+ product_types = ["switch", "wireless"]
+}
+
+`
+
+// End of section. //template:end testPrerequisites
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccConfigMinimal
+
+func testAccMerakiWirelessSSIDConfig_minimum() string {
+ config := `resource "meraki_wireless_ssid" "test" {` + "\n"
+ config += ` network_id = meraki_network.test.id` + "\n"
+ config += ` number = "0"` + "\n"
+ config += ` name = "My SSID"` + "\n"
+ config += `}` + "\n"
+ return config
+}
+
+// End of section. //template:end testAccConfigMinimal
+
+// Section below is generated&owned by "gen/generator.go". //template:begin testAccConfigAll
+
+func testAccMerakiWirelessSSIDConfig_all() string {
+ config := `resource "meraki_wireless_ssid" "test" {` + "\n"
+ config += ` network_id = meraki_network.test.id` + "\n"
+ config += ` number = "0"` + "\n"
+ config += ` adult_content_filtering_enabled = false` + "\n"
+ config += ` auth_mode = "8021x-radius"` + "\n"
+ config += ` available_on_all_aps = false` + "\n"
+ config += ` band_selection = "5 GHz band only"` + "\n"
+ config += ` default_vlan_id = 1` + "\n"
+ config += ` disassociate_clients_on_vpn_failover = false` + "\n"
+ config += ` enabled = false` + "\n"
+ config += ` encryption_mode = "wpa"` + "\n"
+ config += ` ip_assignment_mode = "Bridge mode"` + "\n"
+ config += ` lan_isolation_enabled = false` + "\n"
+ config += ` mandatory_dhcp_enabled = false` + "\n"
+ config += ` min_bitrate = 5.5` + "\n"
+ config += ` name = "My SSID"` + "\n"
+ config += ` per_client_bandwidth_limit_down = 0` + "\n"
+ config += ` per_client_bandwidth_limit_up = 0` + "\n"
+ config += ` per_ssid_bandwidth_limit_down = 0` + "\n"
+ config += ` per_ssid_bandwidth_limit_up = 0` + "\n"
+ config += ` psk = "deadbeef"` + "\n"
+ config += ` radius_accounting_enabled = false` + "\n"
+ config += ` radius_accounting_interim_interval = 5` + "\n"
+ config += ` radius_attribute_for_group_policies = "Filter-Id"` + "\n"
+ config += ` radius_authentication_nas_id = "00-11-22-33-44-55:AP1"` + "\n"
+ config += ` radius_called_station_id = "00-11-22-33-44-55:AP1"` + "\n"
+ config += ` radius_coa_enabled = false` + "\n"
+ config += ` radius_failover_policy = "Deny access"` + "\n"
+ config += ` radius_fallback_enabled = false` + "\n"
+ config += ` radius_guest_vlan_enabled = false` + "\n"
+ config += ` radius_guest_vlan_id = 1` + "\n"
+ config += ` radius_load_balancing_policy = "Round robin"` + "\n"
+ config += ` radius_override = false` + "\n"
+ config += ` radius_proxy_enabled = false` + "\n"
+ config += ` radius_server_attempts_limit = 5` + "\n"
+ config += ` radius_server_timeout = 5` + "\n"
+ config += ` radius_testing_enabled = false` + "\n"
+ config += ` secondary_concentrator_network_id = "disabled"` + "\n"
+ config += ` splash_page = "Click-through splash page"` + "\n"
+ config += ` use_vlan_tagging = false` + "\n"
+ config += ` visible = false` + "\n"
+ config += ` vlan_id = 10` + "\n"
+ config += ` walled_garden_enabled = false` + "\n"
+ config += ` wpa_encryption_mode = "WPA2 only"` + "\n"
+ config += ` dot11r_adaptive = false` + "\n"
+ config += ` dot11r_enabled = false` + "\n"
+ config += ` dot11w_enabled = false` + "\n"
+ config += ` dot11w_required = false` + "\n"
+ config += ` gre_key = 5` + "\n"
+ config += ` gre_concentrator_host = "192.168.1.1"` + "\n"
+ config += ` local_radius_cache_timeout = 60` + "\n"
+ config += ` local_radius_certificate_authentication_enabled = false` + "\n"
+ config += ` local_radius_certificate_authentication_ocsp_responder_url = "http://ocsp-server.example.com"` + "\n"
+ config += ` local_radius_certificate_authentication_use_ldap = false` + "\n"
+ config += ` local_radius_certificate_authentication_use_ocsp = false` + "\n"
+ config += ` local_radius_certificate_authentication_client_root_ca_certificate_contents = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"` + "\n"
+ config += ` local_radius_password_authentication_enabled = false` + "\n"
+ config += ` named_vlans_radius_guest_vlan_enabled = false` + "\n"
+ config += ` named_vlans_tagging_enabled = false` + "\n"
+ config += ` speed_burst_enabled = false` + "\n"
+ config += ` ap_tags_and_vlan_ids = [{` + "\n"
+ config += ` vlan_id = 100` + "\n"
+ config += ` tags = ["tag1"]` + "\n"
+ config += ` }]` + "\n"
+ config += ` availability_tags = ["tag1"]` + "\n"
+ config += ` radius_servers = [{` + "\n"
+ config += ` ca_certificate = "-----BEGIN CERTIFICATE-----\nMIIEKjCCAxKgAwIBAgIRANb+lsED3eb4+6YKLFFYqEkwDQYJKoZIhvcNAQELBQAw\ngYcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhT\nYW4gSm9zZTEcMBoGA1UECgwTQ2lzY28gU3lzdGVtcywgSW5jLjESMBAGA1UECwwJ\nRE5BU3BhY2VzMR4wHAYDVQQDDBVjaXNjby5vcGVucm9hbWluZy5vcmcwHhcNMjAx\nMTA1MjEzMzM1WhcNMjExMTA1MjIzMzM1WjCBpDEcMBoGCgmSJomT8ixkAQETDGRu\nYXNwYWNlczpVUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ4wDAYDVQQKEwVD\naXNjbzEcMBoGA1UECxMTV0JBOldSSVggRW5kLUVudGl0eTE8MDoGA1UEAxMzNjQ3\nMDcwNDM4NDQ5NjQxMjAwMDAuMTg4MzQuaHMuY2lzY28ub3BlbnJvYW1pbmcub3Jn\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoqjP9QgRGyUO3p7SH9QK\nuTq6UYK7nAyjImgS4yQxeBkyZ5f2EUkX8m/AOcewpPxxPBhjPKRwxGeX3S50ksiA\nayFomUeslR0S0Z7RN9rzJa+CFyi9MwWIHMbLgXpB8tsSpgTAqwrzoTzOGq9fgC6u\npZhdZrBkg3FeJgD88goCi9mZDsY2YAoeGRLFJ2fR8iICqIVQy+Htq9pE22WBLpnS\nKjL3+mR9FArHNFtWlhKF2YHMUqyHHrnZnF/Ns7QNoMMF7/CK18iAKgnb+2wuGKM2\naEMddOeOTtz+i/rgjkp/RGMt011EdCsso0/cTo9qqX/bxOOCE4/Mne/ChMkQPnNU\nCwIDAQABo3IwcDAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFIG+4l5yiB01gP0sw4ML\nUSopqYcuMB0GA1UdDgQWBBSby1T9leYVOVVdOZXiHCSaDDEMiDAOBgNVHQ8BAf8E\nBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAEyE\n1mjSUyY6uNp6W4l20w7SskALSJDRKkOeZxAgF3VMxlsCuEl70s9oEfntwIpyQtSa\njON/9yJHbwm/Az824bmk8Dc7AXIPhay+dftXb8j529gPuYB9AKoPNg0NctkyYCQh\na/3YQVdDWX7XgmEiXkL57M7G6+IdcPDONLArfjOcT9qHdkVVq1AIjlMSx3OQQmm/\nuoLb/G9q/97QA2/l8shG/Na8HjVqGLcl5TNZdbNhs2w9ogxr/GNzqdvym6RQ8vT/\nUR2n+uwH4n1MUxmHYYeyot5dnIV1IJ6hQ54JAncM9HvCLFk1WHz6RKshQUCuPBiJ\nwTw70BVktzJnb0VLeDg=\n-----END CERTIFICATE-----"` + "\n"
+ config += ` host = "0.0.0.0"` + "\n"
+ config += ` port = 3000` + "\n"
+ config += ` radsec_enabled = false` + "\n"
+ config += ` secret = "secret-string"` + "\n"
+ config += ` }]` + "\n"
+ config += `}` + "\n"
+ return config
+}
+
+// End of section. //template:end testAccConfigAll