From 9f2573d72c361ce7afb36cb62a42d9fc254f997c Mon Sep 17 00:00:00 2001 From: Mateusz Filipowicz Date: Wed, 12 Mar 2025 00:59:03 +0100 Subject: [PATCH] feat: add support for Remote Syslog settings with `unifi_setting_rsyslog` resource (#47) * feat: add support for Remote Syslog settings with `unifi_setting_rsyslog` resource * set controller version constraint on 8.5 for rsyslogd * require controller version 7.2 for teleport * fix: use dedicated site for USG setting tests to not interfere with other resources --- .../acctest/resource_setting_rsyslogd_test.go | 208 +++++++++++++ .../acctest/resource_setting_teleport_test.go | 2 +- .../acctest/resource_setting_usg_test.go | 162 ++++++----- internal/provider/provider_v2.go | 2 +- .../settings/resource_setting_rsyslogd.go | 274 ++++++++++++++++++ .../settings/resource_setting_teleport.go | 2 +- 6 files changed, 573 insertions(+), 77 deletions(-) create mode 100644 internal/provider/acctest/resource_setting_rsyslogd_test.go create mode 100644 internal/provider/settings/resource_setting_rsyslogd.go diff --git a/internal/provider/acctest/resource_setting_rsyslogd_test.go b/internal/provider/acctest/resource_setting_rsyslogd_test.go new file mode 100644 index 0000000..1194b19 --- /dev/null +++ b/internal/provider/acctest/resource_setting_rsyslogd_test.go @@ -0,0 +1,208 @@ +package acctest + +import ( + pt "github.com/filipowm/terraform-provider-unifi/internal/provider/testing" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + "regexp" + "sync" + "testing" +) + +var settingRsyslogdLock = &sync.Mutex{} + +// TestAccSettingRsyslogdBasic tests the basic creation and import of the rsyslogd settings +func TestAccSettingRsyslogdBasic(t *testing.T) { + AcceptanceTest(t, AcceptanceTestCase{ + VersionConstraint: ">= 8.5", + Lock: settingRsyslogdLock, + Steps: []resource.TestStep{ + { + Config: testAccSettingRsyslogdConfigBasic(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("unifi_setting_rsyslogd.test", "id"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "site", "default"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "enabled", "true"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "ip", "192.168.1.100"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "port", "514"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "contents.#", "2"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "contents.0", "device"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "contents.1", "client"), + ), + ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_rsyslogd.test", plancheck.ResourceActionCreate), + }, + pt.ImportStepWithSite("unifi_setting_rsyslogd.test"), + }, + }) +} + +// TestAccSettingRsyslogdUpdate tests updating the rsyslogd settings with different values +func TestAccSettingRsyslogdUpdate(t *testing.T) { + AcceptanceTest(t, AcceptanceTestCase{ + VersionConstraint: ">= 8.5", + Lock: settingRsyslogdLock, + Steps: []resource.TestStep{ + { + Config: testAccSettingRsyslogdConfigBasic(), + }, + { + Config: testAccSettingRsyslogdConfigUpdate(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("unifi_setting_rsyslogd.test", "id"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "site", "default"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "enabled", "true"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "ip", "192.168.1.200"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "port", "1514"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "contents.#", "3"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "contents.0", "device"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "contents.1", "client"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "contents.2", "admin_activity"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "debug", "true"), + ), + ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_rsyslogd.test", plancheck.ResourceActionUpdate), + }, + }, + }) +} + +// TestAccSettingRsyslogdDisable tests disabling the rsyslogd settings +func TestAccSettingRsyslogdDisable(t *testing.T) { + AcceptanceTest(t, AcceptanceTestCase{ + VersionConstraint: ">= 8.5", + Lock: settingRsyslogdLock, + Steps: []resource.TestStep{ + { + Config: testAccSettingRsyslogdConfigBasic(), + }, + { + Config: testAccSettingRsyslogdConfigDisabled(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("unifi_setting_rsyslogd.test", "id"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "site", "default"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "enabled", "false"), + resource.TestCheckNoResourceAttr("unifi_setting_rsyslogd.test", "ip"), + resource.TestCheckNoResourceAttr("unifi_setting_rsyslogd.test", "port"), + resource.TestCheckNoResourceAttr("unifi_setting_rsyslogd.test", "contents.#"), + resource.TestCheckNoResourceAttr("unifi_setting_rsyslogd.test", "debug"), + ), + ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_rsyslogd.test", plancheck.ResourceActionUpdate), + }, + }, + }) +} + +// TestAccSettingRsyslogdReEnable tests re-enabling the rsyslogd settings with different values +func TestAccSettingRsyslogdReEnable(t *testing.T) { + AcceptanceTest(t, AcceptanceTestCase{ + VersionConstraint: ">= 8.5", + Lock: settingRsyslogdLock, + Steps: []resource.TestStep{ + { + Config: testAccSettingRsyslogdConfigDisabled(), + }, + { + Config: testAccSettingRsyslogdConfigReEnabled(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("unifi_setting_rsyslogd.test", "id"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "site", "default"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "enabled", "true"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "netconsole_enabled", "true"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "netconsole_host", "192.168.1.150"), + resource.TestCheckResourceAttr("unifi_setting_rsyslogd.test", "netconsole_port", "1514"), + ), + ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_rsyslogd.test", plancheck.ResourceActionUpdate), + }, + }, + }) +} + +// TestAccSettingRsyslogdValidation tests validation errors when trying to set fields with rsyslogd disabled +func TestAccSettingRsyslogdValidation(t *testing.T) { + AcceptanceTest(t, AcceptanceTestCase{ + VersionConstraint: ">= 8.5", + Lock: settingRsyslogdLock, + Steps: []resource.TestStep{ + { + Config: testAccSettingRsyslogdConfigInvalid(), + ExpectError: regexp.MustCompile(`any of those attributes must not be configured`), + }, + }, + }) +} + +// TestAccSettingRsyslogdPortValidation tests validation errors for invalid port numbers +func TestAccSettingRsyslogdPortValidation(t *testing.T) { + AcceptanceTest(t, AcceptanceTestCase{ + VersionConstraint: ">= 8.5", + Lock: settingRsyslogdLock, + Steps: []resource.TestStep{ + { + Config: testAccSettingRsyslogdConfigInvalidPort(), + ExpectError: regexp.MustCompile(`value must be between`), + }, + }, + }) +} + +func testAccSettingRsyslogdConfigBasic() string { + return ` +resource "unifi_setting_rsyslogd" "test" { + enabled = true + ip = "192.168.1.100" + port = 514 + contents = ["device", "client"] +} +` +} + +func testAccSettingRsyslogdConfigUpdate() string { + return ` +resource "unifi_setting_rsyslogd" "test" { + enabled = true + ip = "192.168.1.200" + port = 1514 + contents = ["device", "client", "admin_activity"] + debug = true +} +` +} + +func testAccSettingRsyslogdConfigDisabled() string { + return ` +resource "unifi_setting_rsyslogd" "test" { + enabled = false +} +` +} + +func testAccSettingRsyslogdConfigReEnabled() string { + return ` +resource "unifi_setting_rsyslogd" "test" { + enabled = true + contents = ["device", "client"] + ip = "192.168.1.200" + netconsole_enabled = true + netconsole_host = "192.168.1.150" + netconsole_port = 1514 +} +` +} + +func testAccSettingRsyslogdConfigInvalid() string { + return ` +resource "unifi_setting_rsyslogd" "test" { + enabled = false + ip = "192.168.1.100" +} +` +} + +func testAccSettingRsyslogdConfigInvalidPort() string { + return ` +resource "unifi_setting_rsyslogd" "test" { + enabled = true + ip = "192.168.1.100" + port = 70000 +} +` +} diff --git a/internal/provider/acctest/resource_setting_teleport_test.go b/internal/provider/acctest/resource_setting_teleport_test.go index 2b5ba66..cb2a8f1 100644 --- a/internal/provider/acctest/resource_setting_teleport_test.go +++ b/internal/provider/acctest/resource_setting_teleport_test.go @@ -13,7 +13,7 @@ var settingTeleportLock = &sync.Mutex{} func TestAccSettingTeleport(t *testing.T) { AcceptanceTest(t, AcceptanceTestCase{ - VersionConstraint: ">= 7.1", + VersionConstraint: ">= 7.2", Lock: settingTeleportLock, Steps: []resource.TestStep{ { diff --git a/internal/provider/acctest/resource_setting_usg_test.go b/internal/provider/acctest/resource_setting_usg_test.go index 937e19b..0397890 100644 --- a/internal/provider/acctest/resource_setting_usg_test.go +++ b/internal/provider/acctest/resource_setting_usg_test.go @@ -10,6 +10,8 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) +// using dedicated site for each test, because USG settings might interfere with parallel tests of other resources + // using an additional lock to the one around the resource to avoid deadlocking accidentally var settingUsgLock = sync.Mutex{} @@ -19,17 +21,17 @@ func TestAccSettingUsg_mdns_v6(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_mdns(true), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_mdns(true), Check: resource.ComposeTestCheckFunc(), }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_mdns(false), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_mdns(false), Check: resource.ComposeTestCheckFunc(), }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_mdns(true), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_mdns(true), Check: resource.ComposeTestCheckFunc(), }, pt.ImportStepWithSite("unifi_setting_usg.test"), @@ -43,7 +45,7 @@ func TestAccSettingUsg_mdns_v7(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_mdns(true), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_mdns(true), ExpectError: regexp.MustCompile("multicast_dns_enabled is not supported"), }, }, @@ -55,7 +57,7 @@ func TestAccSettingUsg_dhcpRelayServers(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_dhcpRelay(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_dhcpRelay(), Check: resource.ComposeTestCheckFunc(), }, pt.ImportStepWithSite("unifi_setting_usg.test"), @@ -63,31 +65,13 @@ func TestAccSettingUsg_dhcpRelayServers(t *testing.T) { }) } -func TestAccSettingUsg_site(t *testing.T) { - AcceptanceTest(t, AcceptanceTestCase{ - Lock: &settingUsgLock, - Steps: []resource.TestStep{ - { - Config: testAccSettingUsgConfig_site(), - Check: resource.ComposeTestCheckFunc(), - }, - { - ResourceName: "unifi_setting_usg.test", - ImportState: true, - ImportStateIdFunc: pt.SiteAndIDImportStateIDFunc("unifi_setting_usg.test"), - ImportStateVerify: true, - }, - }, - }) -} - func TestAccSettingUsg_geoIpFiltering(t *testing.T) { AcceptanceTest(t, AcceptanceTestCase{ VersionConstraint: ">= 7", Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_geoIpFilteringBasic(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_geoIpFilteringBasic(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "geo_ip_filtering.enabled", "true"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "geo_ip_filtering.block", "block"), @@ -100,7 +84,7 @@ func TestAccSettingUsg_geoIpFiltering(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_geoIpFilteringAllow(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_geoIpFilteringAllow(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "geo_ip_filtering.enabled", "true"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "geo_ip_filtering.block", "allow"), @@ -113,7 +97,7 @@ func TestAccSettingUsg_geoIpFiltering(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_geoIpFilteringDirections(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_geoIpFilteringDirections(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "geo_ip_filtering.enabled", "true"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "geo_ip_filtering.block", "block"), @@ -125,14 +109,14 @@ func TestAccSettingUsg_geoIpFiltering(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_geoIpFilteringDisabled(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_geoIpFilteringDisabled(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "geo_ip_filtering.enabled", "false"), ), }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_geoIpFilteringBasic(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_geoIpFilteringBasic(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "geo_ip_filtering.enabled", "true"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "geo_ip_filtering.block", "block"), @@ -153,14 +137,14 @@ func TestAccSettingUsg_upnp(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_upnpBasic(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_upnpBasic(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "upnp.enabled", "true"), ), }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_upnpAdvanced(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_upnpAdvanced(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "upnp.enabled", "true"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "upnp.nat_pmp_enabled", "true"), @@ -170,7 +154,7 @@ func TestAccSettingUsg_upnp(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_upnpDisabled(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_upnpDisabled(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "upnp.enabled", "false"), ), @@ -186,7 +170,7 @@ func TestAccSettingUsg_dnsVerification(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_dnsVerification(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_dnsVerification(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("unifi_setting_usg.test", "dns_verification.domain"), resource.TestCheckResourceAttrSet("unifi_setting_usg.test", "dns_verification.primary_dns_server"), @@ -196,7 +180,7 @@ func TestAccSettingUsg_dnsVerification(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_dnsVerificationUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_dnsVerificationUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "dns_verification.domain", "example.com"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "dns_verification.primary_dns_server", "1.1.1.1"), @@ -212,7 +196,7 @@ func TestAccSettingUsg_tcpTimeouts(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_tcpTimeouts(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_tcpTimeouts(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "tcp_timeouts.close_timeout", "10"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "tcp_timeouts.established_timeout", "3600"), @@ -226,7 +210,7 @@ func TestAccSettingUsg_tcpTimeouts(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_tcpTimeoutsUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_tcpTimeoutsUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "tcp_timeouts.close_timeout", "20"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "tcp_timeouts.established_timeout", "7200"), @@ -247,7 +231,7 @@ func TestAccSettingUsg_arpCache(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_arpCache(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_arpCache(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "arp_cache_base_reachable", "60"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "arp_cache_timeout", "custom"), @@ -255,7 +239,7 @@ func TestAccSettingUsg_arpCache(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_arpCacheUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_arpCacheUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "arp_cache_base_reachable", "120"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "arp_cache_timeout", "normal"), @@ -270,7 +254,7 @@ func TestAccSettingUsg_dhcpConfig(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_dhcpConfig(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_dhcpConfig(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "broadcast_ping", "true"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "dhcpd_hostfile_update", "true"), @@ -280,7 +264,7 @@ func TestAccSettingUsg_dhcpConfig(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_dhcpConfigUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_dhcpConfigUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "broadcast_ping", "false"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "dhcpd_hostfile_update", "false"), @@ -297,7 +281,7 @@ func TestAccSettingUsg_dhcpRelayConfig(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_dhcpRelayConfig(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_dhcpRelayConfig(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "dhcp_relay.agents_packets", "forward"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "dhcp_relay.hop_count", "5"), @@ -310,7 +294,7 @@ func TestAccSettingUsg_dhcpRelayConfig(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_dhcpRelayConfigUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_dhcpRelayConfigUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "dhcp_relay.agents_packets", "replace"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "dhcp_relay.hop_count", "10"), @@ -331,7 +315,7 @@ func TestAccSettingUsg_networkTools(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_networkTools(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_networkTools(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "echo_server", "echo.example.com"), ), @@ -346,7 +330,7 @@ func TestAccSettingUsg_protocolModules(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_protocolModules(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_protocolModules(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "ftp_module", "true"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "gre_module", "true"), @@ -358,7 +342,7 @@ func TestAccSettingUsg_protocolModules(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_protocolModulesUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_protocolModulesUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "ftp_module", "false"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "gre_module", "true"), @@ -377,7 +361,7 @@ func TestAccSettingUsg_icmpAndLldp(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_icmpAndLldp(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_icmpAndLldp(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "icmp_timeout", "60"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "lldp_enable_all", "true"), @@ -385,7 +369,7 @@ func TestAccSettingUsg_icmpAndLldp(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_icmpAndLldpUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_icmpAndLldpUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "icmp_timeout", "120"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "lldp_enable_all", "false"), @@ -400,7 +384,7 @@ func TestAccSettingUsg_mssClamp(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_mssClamp(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_mssClamp(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "mss_clamp", "auto"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "mss_clamp_mss", "1452"), @@ -408,7 +392,7 @@ func TestAccSettingUsg_mssClamp(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_mssClampUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_mssClampUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "mss_clamp", "custom"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "mss_clamp_mss", "1400"), @@ -423,7 +407,7 @@ func TestAccSettingUsg_offloadSettings(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_offloadSettings(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_offloadSettings(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "offload_accounting", "true"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "offload_l2_blocking", "true"), @@ -432,7 +416,7 @@ func TestAccSettingUsg_offloadSettings(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_offloadSettingsUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_offloadSettingsUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "offload_accounting", "false"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "offload_l2_blocking", "false"), @@ -449,7 +433,7 @@ func TestAccSettingUsg_timeoutSettings(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_timeoutSettings(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_timeoutSettings(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "other_timeout", "600"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "timeout_setting_preference", "auto"), @@ -457,7 +441,7 @@ func TestAccSettingUsg_timeoutSettings(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_timeoutSettingsUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_timeoutSettingsUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "other_timeout", "1200"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "timeout_setting_preference", "manual"), @@ -472,7 +456,7 @@ func TestAccSettingUsg_redirectsAndSecurity(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_redirectsAndSecurity(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_redirectsAndSecurity(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "receive_redirects", "false"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "send_redirects", "true"), @@ -481,7 +465,7 @@ func TestAccSettingUsg_redirectsAndSecurity(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_redirectsAndSecurityUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_redirectsAndSecurityUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "receive_redirects", "true"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "send_redirects", "false"), @@ -497,7 +481,7 @@ func TestAccSettingUsg_udp(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_udp(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_udp(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "udp_other_timeout", "30"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "udp_stream_timeout", "120"), @@ -505,7 +489,7 @@ func TestAccSettingUsg_udp(t *testing.T) { }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_udpUpdated(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_udpUpdated(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "udp_other_timeout", "60"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "udp_stream_timeout", "240"), @@ -521,14 +505,14 @@ func TestAccSettingUsg_unbindWanMonitor(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_unbindWanMonitor(true), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_unbindWanMonitor(true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "unbind_wan_monitors", "true"), ), }, pt.ImportStepWithSite("unifi_setting_usg.test"), { - Config: testAccSettingUsgConfig_unbindWanMonitor(false), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_unbindWanMonitor(false), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("unifi_setting_usg.test", "unbind_wan_monitors", "false"), ), @@ -543,8 +527,9 @@ func TestAccSettingUsg_comprehensive(t *testing.T) { Lock: &settingUsgLock, Steps: []resource.TestStep{ { - Config: testAccSettingUsgConfig_comprehensive(), + Config: testAccSettingUsgSite() + testAccSettingUsgConfig_comprehensive(), Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("unifi_site.test", "id"), // ARP Cache resource.TestCheckResourceAttr("unifi_setting_usg.test", "arp_cache_base_reachable", "60"), resource.TestCheckResourceAttr("unifi_setting_usg.test", "arp_cache_timeout", "custom"), @@ -569,11 +554,19 @@ func TestAccSettingUsg_comprehensive(t *testing.T) { }, }) } +func testAccSettingUsgSite() string { + return ` +resource "unifi_site" "test" { + description = "tfacc-setting-usg" +} +` +} func testAccSettingUsgConfig_mdns(mdns bool) string { return fmt.Sprintf(` resource "unifi_setting_usg" "test" { multicast_dns_enabled = %t + site = unifi_site.test.name } `, mdns) } @@ -585,25 +578,14 @@ resource "unifi_setting_usg" "test" { "10.1.2.3", "10.1.2.4", ] -} -` -} - -func testAccSettingUsgConfig_site() string { - return ` -resource "unifi_site" "test" { - description = "test" -} - -resource "unifi_setting_usg" "test" { site = unifi_site.test.name } ` } - func testAccSettingUsgConfig_geoIpFilteringBasic() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name geo_ip_filtering = { enabled = true countries = ["RU", "CN", "KP"] @@ -615,6 +597,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_geoIpFilteringAllow() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name geo_ip_filtering = { enabled = true block = "allow" @@ -627,6 +610,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_geoIpFilteringDirections() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name geo_ip_filtering = { enabled = true traffic_direction = "ingress" @@ -639,6 +623,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_geoIpFilteringDisabled() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name geo_ip_filtering = { enabled = false } @@ -649,6 +634,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_upnpBasic() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name upnp = { enabled = true } @@ -659,6 +645,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_upnpAdvanced() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name upnp = { enabled = true nat_pmp_enabled = true @@ -672,6 +659,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_upnpDisabled() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name upnp = { enabled = false } @@ -682,9 +670,10 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_dnsVerification() string { return ` resource "unifi_setting_usg" "test" { - dns_verification = { - setting_preference = "auto" - } + site = unifi_site.test.name + dns_verification = { + setting_preference = "auto" + } } ` } @@ -692,6 +681,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_dnsVerificationUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name dns_verification = { domain = "example.com" primary_dns_server = "1.1.1.1" @@ -705,6 +695,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_tcpTimeouts() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name tcp_timeouts = { close_timeout = 10 established_timeout = 3600 @@ -722,6 +713,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_tcpTimeoutsUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name tcp_timeouts = { close_timeout = 20 established_timeout = 7200 @@ -739,6 +731,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_arpCache() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name arp_cache_base_reachable = 60 arp_cache_timeout = "custom" } @@ -748,6 +741,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_dhcpConfig() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name broadcast_ping = true dhcpd_hostfile_update = true dhcpd_use_dnsmasq = true @@ -759,6 +753,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_dhcpRelayConfig() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name dhcp_relay = { agents_packets = "forward" hop_count = 5 @@ -773,6 +768,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_dhcpRelayConfigUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name dhcp_relay = { agents_packets = "replace" hop_count = 10 @@ -787,6 +783,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_networkTools() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name echo_server = "echo.example.com" } ` @@ -795,6 +792,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_protocolModules() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name ftp_module = true gre_module = true h323_module = true @@ -808,6 +806,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_icmpAndLldp() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name icmp_timeout = 60 lldp_enable_all = true } @@ -817,6 +816,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_mssClamp() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name mss_clamp = "auto" mss_clamp_mss = 1452 } @@ -826,6 +826,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_offloadSettings() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name offload_accounting = true offload_l2_blocking = true offload_sch = true @@ -836,6 +837,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_timeoutSettings() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name other_timeout = 600 timeout_setting_preference = "auto" } @@ -845,6 +847,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_redirectsAndSecurity() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name receive_redirects = false send_redirects = true syn_cookies = true @@ -855,6 +858,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_udp() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name udp_other_timeout = 30 udp_stream_timeout = 120 } @@ -864,6 +868,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_comprehensive() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name // ARP Cache Configuration arp_cache_base_reachable = 60 arp_cache_timeout = "custom" @@ -947,6 +952,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_arpCacheUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name arp_cache_base_reachable = 120 arp_cache_timeout = "normal" } @@ -956,6 +962,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_dhcpConfigUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name broadcast_ping = false dhcpd_hostfile_update = false dhcpd_use_dnsmasq = false @@ -967,6 +974,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_protocolModulesUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name ftp_module = false gre_module = true h323_module = false @@ -980,6 +988,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_icmpAndLldpUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name icmp_timeout = 120 lldp_enable_all = false } @@ -989,6 +998,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_mssClampUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name mss_clamp = "custom" mss_clamp_mss = 1400 } @@ -998,6 +1008,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_offloadSettingsUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name offload_accounting = false offload_l2_blocking = false offload_sch = false @@ -1008,6 +1019,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_timeoutSettingsUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name other_timeout = 1200 timeout_setting_preference = "manual" } @@ -1017,6 +1029,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_redirectsAndSecurityUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name receive_redirects = true send_redirects = false syn_cookies = false @@ -1027,6 +1040,7 @@ resource "unifi_setting_usg" "test" { func testAccSettingUsgConfig_udpUpdated() string { return ` resource "unifi_setting_usg" "test" { + site = unifi_site.test.name udp_other_timeout = 60 udp_stream_timeout = 240 } diff --git a/internal/provider/provider_v2.go b/internal/provider/provider_v2.go index c15fe73..ebbf9ff 100644 --- a/internal/provider/provider_v2.go +++ b/internal/provider/provider_v2.go @@ -183,7 +183,7 @@ func (p *unifiProvider) Resources(_ context.Context) []func() resource.Resource settings.NewMagicSiteToSiteVpnResource, settings.NewNetworkOptimizationResource, settings.NewNtpResource, - //settings.NewRsyslogdResource, + settings.NewRsyslogdResource, settings.NewSslInspectionResource, settings.NewTeleportResource, settings.NewUsgResource, diff --git a/internal/provider/settings/resource_setting_rsyslogd.go b/internal/provider/settings/resource_setting_rsyslogd.go new file mode 100644 index 0000000..7de5118 --- /dev/null +++ b/internal/provider/settings/resource_setting_rsyslogd.go @@ -0,0 +1,274 @@ +package settings + +import ( + "context" + "github.com/filipowm/terraform-provider-unifi/internal/provider/validators" + "github.com/filipowm/terraform-provider-unifi/internal/utils" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + + "github.com/filipowm/go-unifi/unifi" + "github.com/filipowm/terraform-provider-unifi/internal/provider/base" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework/diag" + "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/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type rsyslogdModel struct { + base.Model + Enabled types.Bool `tfsdk:"enabled"` + Contents types.List `tfsdk:"contents"` + Debug types.Bool `tfsdk:"debug"` + IP types.String `tfsdk:"ip"` + LogAllContents types.Bool `tfsdk:"log_all_contents"` + NetconsoleEnabled types.Bool `tfsdk:"netconsole_enabled"` + NetconsoleHost types.String `tfsdk:"netconsole_host"` + NetconsolePort types.Int64 `tfsdk:"netconsole_port"` + Port types.Int64 `tfsdk:"port"` + ThisController types.Bool `tfsdk:"this_controller"` + ThisControllerEncryptedOnly types.Bool `tfsdk:"this_controller_encrypted_only"` +} + +func (d *rsyslogdModel) AsUnifiModel(_ context.Context) (interface{}, diag.Diagnostics) { + diags := diag.Diagnostics{} + + model := &unifi.SettingRsyslogd{ + ID: d.ID.ValueString(), + Enabled: d.Enabled.ValueBool(), + Contents: []string{}, + } + + // Only set optional fields if rsyslogd is enabled + if d.Enabled.ValueBool() { + if !d.Debug.IsNull() { + model.Debug = d.Debug.ValueBool() + } + + if !d.IP.IsNull() { + model.IP = d.IP.ValueString() + } + + if !d.LogAllContents.IsNull() { + model.LogAllContents = d.LogAllContents.ValueBool() + } + + if !d.NetconsoleEnabled.IsNull() { + model.NetconsoleEnabled = d.NetconsoleEnabled.ValueBool() + } + + if !d.NetconsoleHost.IsNull() { + model.NetconsoleHost = d.NetconsoleHost.ValueString() + } + + if !d.NetconsolePort.IsNull() { + model.NetconsolePort = int(d.NetconsolePort.ValueInt64()) + } + + if !d.Port.IsNull() { + model.Port = int(d.Port.ValueInt64()) + } + + if !d.ThisController.IsNull() { + model.ThisController = d.ThisController.ValueBool() + } + + if !d.ThisControllerEncryptedOnly.IsNull() { + model.ThisControllerEncryptedOnly = d.ThisControllerEncryptedOnly.ValueBool() + } + + if !d.Contents.IsNull() { + var contents []string + diags.Append(utils.ListElementsAs(d.Contents, &contents)...) + if diags.HasError() { + return nil, diags + } + model.Contents = contents + } + } + + return model, diags +} + +func (d *rsyslogdModel) Merge(ctx context.Context, other interface{}) diag.Diagnostics { + diags := diag.Diagnostics{} + + model, ok := other.(*unifi.SettingRsyslogd) + if !ok { + diags.AddError("Cannot merge", "Cannot merge type that is not *unifi.SettingRsyslogd") + return diags + } + + d.ID = types.StringValue(model.ID) + d.Enabled = types.BoolValue(model.Enabled) + + // Only set optional fields if rsyslogd is enabled + if model.Enabled { + d.Debug = types.BoolValue(model.Debug) + d.IP = types.StringValue(model.IP) + d.LogAllContents = types.BoolValue(model.LogAllContents) + d.NetconsoleEnabled = types.BoolValue(model.NetconsoleEnabled) + d.NetconsoleHost = types.StringValue(model.NetconsoleHost) + d.NetconsolePort = types.Int64Value(int64(model.NetconsolePort)) + d.Port = types.Int64Value(int64(model.Port)) + d.ThisController = types.BoolValue(model.ThisController) + d.ThisControllerEncryptedOnly = types.BoolValue(model.ThisControllerEncryptedOnly) + + // Set the DHCP relay servers list + contents, diags := types.ListValueFrom(ctx, types.StringType, model.Contents) + if diags.HasError() { + return diags + } + d.Contents = contents + } else { + d.Debug = types.BoolNull() + d.IP = types.StringNull() + d.LogAllContents = types.BoolNull() + d.NetconsoleEnabled = types.BoolNull() + d.NetconsoleHost = types.StringNull() + d.NetconsolePort = types.Int64Null() + d.Port = types.Int64Null() + d.ThisController = types.BoolNull() + d.ThisControllerEncryptedOnly = types.BoolNull() + d.Contents = utils.EmptyList(types.StringType) + } + + return diags +} + +var ( + _ base.ResourceModel = &rsyslogdModel{} + _ resource.Resource = &rsyslogdResource{} + _ resource.ResourceWithConfigure = &rsyslogdResource{} + _ resource.ResourceWithImportState = &rsyslogdResource{} + _ resource.ResourceWithConfigValidators = &rsyslogdResource{} + _ resource.ResourceWithModifyPlan = &rsyslogdResource{} +) + +type rsyslogdResource struct { + *BaseSettingResource[*rsyslogdModel] +} + +func (r *rsyslogdResource) ModifyPlan(_ context.Context, _ resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { + resp.Diagnostics.Append(r.RequireMinVersion("8.5")...) +} + +func (r *rsyslogdResource) ConfigValidators(_ context.Context) []resource.ConfigValidator { + return []resource.ConfigValidator{ + validators.RequiredNoneIf(path.MatchRoot("enabled"), types.BoolValue(false), + path.MatchRoot("contents"), + path.MatchRoot("debug"), + path.MatchRoot("ip"), + path.MatchRoot("log_all_contents"), + path.MatchRoot("netconsole_enabled"), + path.MatchRoot("netconsole_host"), + path.MatchRoot("netconsole_port"), + path.MatchRoot("port"), + path.MatchRoot("this_controller"), + path.MatchRoot("this_controller_encrypted_only"), + ), + validators.RequiredTogetherIf(path.MatchRoot("enabled"), types.BoolValue(true), path.MatchRoot("contents"), path.MatchRoot("ip")), + } +} + +func (r *rsyslogdResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: "Manages Remote Syslog (rsyslogd) settings for UniFi devices. Controller version 8.5 or later is required.", + Attributes: map[string]schema.Attribute{ + "id": base.ID(), + "site": base.SiteAttribute(), + "enabled": schema.BoolAttribute{ + MarkdownDescription: "Whether remote syslog is enabled.", + Required: true, + }, + "contents": schema.ListAttribute{ + MarkdownDescription: "List of log types to include in the remote syslog. Valid values: device, client, firewall_default_policy, triggers, updates, admin_activity, critical, security_detections, vpn.", + Optional: true, + Computed: true, + ElementType: types.StringType, + Validators: []validator.List{ + listvalidator.SizeAtLeast(1), + listvalidator.ValueStringsAre(stringvalidator.OneOf("device", "client", "firewall_default_policy", "triggers", "updates", "admin_activity", "critical", "security_detections", "vpn")), + }, + }, + "debug": schema.BoolAttribute{ + MarkdownDescription: "Whether debug logging is enabled.", + Optional: true, + Computed: true, + }, + "ip": schema.StringAttribute{ + MarkdownDescription: "IP address of the remote syslog server.", + Optional: true, + Computed: true, + Validators: []validator.String{ + validators.IPv4(), + }, + }, + "log_all_contents": schema.BoolAttribute{ + MarkdownDescription: "Whether to log all content types.", + Optional: true, + Computed: true, + }, + "netconsole_enabled": schema.BoolAttribute{ + MarkdownDescription: "Whether netconsole logging is enabled.", + Optional: true, + Computed: true, + }, + "netconsole_host": schema.StringAttribute{ + MarkdownDescription: "Hostname or IP address of the netconsole server.", + Optional: true, + Computed: true, + Validators: []validator.String{ + stringvalidator.Any( + validators.Hostname(), + validators.IPv4(), + ), + }, + }, + "netconsole_port": schema.Int64Attribute{ + MarkdownDescription: "Port number for the netconsole server. Valid values: 1-65535.", + Optional: true, + Computed: true, + Validators: []validator.Int64{ + int64validator.Between(1, 65535), + }, + }, + "port": schema.Int64Attribute{ + MarkdownDescription: "Port number for the remote syslog server. Valid values: 1-65535.", + Optional: true, + Computed: true, + Validators: []validator.Int64{ + int64validator.Between(1, 65535), + }, + }, + "this_controller": schema.BoolAttribute{ + MarkdownDescription: "Whether to use this controller as the syslog server.", + Optional: true, + Computed: true, + }, + "this_controller_encrypted_only": schema.BoolAttribute{ + MarkdownDescription: "Whether to only use encrypted connections to this controller for syslog.", + Optional: true, + Computed: true, + }, + }, + } +} + +func NewRsyslogdResource() resource.Resource { + r := &rsyslogdResource{} + r.BaseSettingResource = NewBaseSettingResource( + "unifi_setting_rsyslogd", + func() *rsyslogdModel { return &rsyslogdModel{} }, + func(ctx context.Context, client *base.Client, site string) (interface{}, error) { + return client.GetSettingRsyslogd(ctx, site) + }, + func(ctx context.Context, client *base.Client, site string, body interface{}) (interface{}, error) { + return client.UpdateSettingRsyslogd(ctx, site, body.(*unifi.SettingRsyslogd)) + }, + ) + return r +} diff --git a/internal/provider/settings/resource_setting_teleport.go b/internal/provider/settings/resource_setting_teleport.go index a9006be..251ff82 100644 --- a/internal/provider/settings/resource_setting_teleport.go +++ b/internal/provider/settings/resource_setting_teleport.go @@ -60,7 +60,7 @@ type teleportResource struct { } func (r *teleportResource) ModifyPlan(_ context.Context, _ resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { - resp.Diagnostics.Append(r.RequireMinVersion("7.1")...) + resp.Diagnostics.Append(r.RequireMinVersion("7.2")...) } func (r *teleportResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {