feat: add support for LCD Monitor (LCM) settings with unifi_setting_lcd_monitor resource (#46)

This commit is contained in:
Mateusz Filipowicz
2025-03-11 11:07:45 +01:00
committed by GitHub
parent fcea1e0ba4
commit 72dcdd03ce
3 changed files with 274 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
package acctest
import (
"fmt"
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 settingLcmLock = &sync.Mutex{}
func TestAccSettingLcm(t *testing.T) {
AcceptanceTest(t, AcceptanceTestCase{
Lock: settingLcmLock,
Steps: []resource.TestStep{
{
// Test creating with LCM enabled and all optional fields set
Config: testAccSettingLcmConfig(true, 75, 300, true, true),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("unifi_setting_lcd_monitor.test", "id"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "site", "default"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "enabled", "true"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "brightness", "75"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "idle_timeout", "300"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "sync", "true"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "touch_event", "true"),
),
ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_lcd_monitor.test", plancheck.ResourceActionCreate),
},
pt.ImportStepWithSite("unifi_setting_lcd_monitor.test"),
{
// Test updating with different values
Config: testAccSettingLcmConfig(true, 50, 600, false, true),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("unifi_setting_lcd_monitor.test", "id"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "site", "default"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "enabled", "true"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "brightness", "50"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "idle_timeout", "600"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "sync", "false"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "touch_event", "true"),
),
ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_lcd_monitor.test", plancheck.ResourceActionUpdate),
},
{
// Test disabling LCM (all optional fields should be removed)
Config: testAccSettingLcmConfigDisabled(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("unifi_setting_lcd_monitor.test", "id"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "site", "default"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "enabled", "false"),
resource.TestCheckNoResourceAttr("unifi_setting_lcd_monitor.test", "brightness"),
resource.TestCheckNoResourceAttr("unifi_setting_lcd_monitor.test", "idle_timeout"),
resource.TestCheckNoResourceAttr("unifi_setting_lcd_monitor.test", "sync"),
resource.TestCheckNoResourceAttr("unifi_setting_lcd_monitor.test", "touch_event"),
),
ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_lcd_monitor.test", plancheck.ResourceActionUpdate),
},
{
// Test re-enabling LCM with different values
Config: testAccSettingLcmConfig(true, 100, 3600, true, false),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("unifi_setting_lcd_monitor.test", "id"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "site", "default"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "enabled", "true"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "brightness", "100"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "idle_timeout", "3600"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "sync", "true"),
resource.TestCheckResourceAttr("unifi_setting_lcd_monitor.test", "touch_event", "false"),
),
ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_lcd_monitor.test", plancheck.ResourceActionUpdate),
},
},
})
}
// Test that validation errors are raised when trying to set fields with LCM disabled
func TestAccSettingLcmValidation(t *testing.T) {
AcceptanceTest(t, AcceptanceTestCase{
Lock: settingLcmLock,
Steps: []resource.TestStep{
{
Config: testAccSettingLcmConfigInvalid(),
ExpectError: regexp.MustCompile(`any of those attributes must not be configured`),
},
},
})
}
func testAccSettingLcmConfig(enabled bool, brightness, idleTimeout int, sync, touchEvent bool) string {
return fmt.Sprintf(`
resource "unifi_setting_lcd_monitor" "test" {
enabled = %t
brightness = %d
idle_timeout = %d
sync = %t
touch_event = %t
}
`, enabled, brightness, idleTimeout, sync, touchEvent)
}
func testAccSettingLcmConfigDisabled() string {
return `
resource "unifi_setting_lcd_monitor" "test" {
enabled = false
}
`
}
func testAccSettingLcmConfigInvalid() string {
return `
resource "unifi_setting_lcd_monitor" "test" {
enabled = false
brightness = 50
}
`
}

View File

@@ -176,10 +176,14 @@ func (p *unifiProvider) Resources(_ context.Context) []func() resource.Resource
dns.NewDnsRecordResource,
settings.NewAutoSpeedtestResource,
settings.NewCountryResource,
//settings.NewDpiResource,
//settings.NewIpsResource,
settings.NewLcmResource,
settings.NewLocaleResource,
settings.NewMagicSiteToSiteVpnResource,
settings.NewNetworkOptimizationResource,
settings.NewNtpResource,
//settings.NewRsyslogdResource,
settings.NewSslInspectionResource,
settings.NewTeleportResource,
settings.NewUsgResource,

View File

@@ -0,0 +1,150 @@
package settings
import (
"context"
"github.com/filipowm/terraform-provider-unifi/internal/provider/validators"
"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 lcmModel struct {
base.Model
Enabled types.Bool `tfsdk:"enabled"`
Brightness types.Int64 `tfsdk:"brightness"`
IdleTimeout types.Int64 `tfsdk:"idle_timeout"`
Sync types.Bool `tfsdk:"sync"`
TouchEvent types.Bool `tfsdk:"touch_event"`
}
func (d *lcmModel) AsUnifiModel(_ context.Context) (interface{}, diag.Diagnostics) {
diags := diag.Diagnostics{}
model := &unifi.SettingLcm{
ID: d.ID.ValueString(),
Enabled: d.Enabled.ValueBool(),
}
// Only set optional fields if LCM is enabled
if d.Enabled.ValueBool() {
if !d.Brightness.IsNull() {
model.Brightness = int(d.Brightness.ValueInt64())
}
if !d.IdleTimeout.IsNull() {
model.IDleTimeout = int(d.IdleTimeout.ValueInt64())
}
if !d.Sync.IsNull() {
model.Sync = d.Sync.ValueBool()
}
if !d.TouchEvent.IsNull() {
model.TouchEvent = d.TouchEvent.ValueBool()
}
}
return model, diags
}
func (d *lcmModel) Merge(_ context.Context, other interface{}) diag.Diagnostics {
diags := diag.Diagnostics{}
model, ok := other.(*unifi.SettingLcm)
if !ok {
diags.AddError("Cannot merge", "Cannot merge type that is not *unifi.SettingLcm")
return diags
}
d.ID = types.StringValue(model.ID)
d.Enabled = types.BoolValue(model.Enabled)
// Only set optional fields if LCM is enabled
if model.Enabled {
d.Brightness = types.Int64Value(int64(model.Brightness))
d.IdleTimeout = types.Int64Value(int64(model.IDleTimeout))
d.Sync = types.BoolValue(model.Sync)
d.TouchEvent = types.BoolValue(model.TouchEvent)
} else {
d.Brightness = types.Int64Null()
d.IdleTimeout = types.Int64Null()
d.Sync = types.BoolNull()
d.TouchEvent = types.BoolNull()
}
return diags
}
var (
_ base.ResourceModel = &lcmModel{}
_ resource.Resource = &lcmResource{}
_ resource.ResourceWithConfigure = &lcmResource{}
_ resource.ResourceWithImportState = &lcmResource{}
_ resource.ResourceWithConfigValidators = &lcmResource{}
)
type lcmResource struct {
*BaseSettingResource[*lcmModel]
}
func (r *lcmResource) ConfigValidators(_ context.Context) []resource.ConfigValidator {
return []resource.ConfigValidator{
validators.RequiredNoneIf(path.MatchRoot("enabled"), types.BoolValue(false), path.MatchRoot("brightness"), path.MatchRoot("idle_timeout"), path.MatchRoot("sync"), path.MatchRoot("touch_event")),
}
}
func (r *lcmResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Manages LCD Monitor (LCM) settings for UniFi devices with built-in displays, such as the UniFi Dream Machine Pro (UDM Pro) and UniFi Network Video Recorder (UNVR).",
Attributes: map[string]schema.Attribute{
"id": base.ID(),
"site": base.SiteAttribute(),
"enabled": schema.BoolAttribute{
MarkdownDescription: "Whether the LCD display is enabled.",
Required: true,
},
"brightness": schema.Int64Attribute{
MarkdownDescription: "The brightness level of the LCD display. Valid values are 1-100.",
Optional: true,
Validators: []validator.Int64{
int64validator.Between(1, 100),
},
},
"idle_timeout": schema.Int64Attribute{
MarkdownDescription: "The time in seconds after which the display turns off when idle. Valid values are 10-3600.",
Optional: true,
Validators: []validator.Int64{
int64validator.Between(10, 3600),
},
},
"sync": schema.BoolAttribute{
MarkdownDescription: "Whether to synchronize display settings across multiple devices.",
Optional: true,
},
"touch_event": schema.BoolAttribute{
MarkdownDescription: "Whether touch interactions with the display are enabled.",
Optional: true,
},
},
}
}
func NewLcmResource() resource.Resource {
r := &lcmResource{}
r.BaseSettingResource = NewBaseSettingResource(
"unifi_setting_lcd_monitor",
func() *lcmModel { return &lcmModel{} },
func(ctx context.Context, client *base.Client, site string) (interface{}, error) {
return client.GetSettingLcm(ctx, site)
},
func(ctx context.Context, client *base.Client, site string, body interface{}) (interface{}, error) {
return client.UpdateSettingLcm(ctx, site, body.(*unifi.SettingLcm))
},
)
return r
}