From 9be2c52e12d8afa51c019f2d669372b2094c56fa Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Mon, 22 Sep 2025 10:02:45 +0200 Subject: [PATCH] fix: do not panic if monitors undefined --- provider/agent.go | 23 +++++++++++++++++------ provider/agent_test.go | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/provider/agent.go b/provider/agent.go index 32da2e58..b9f8a6d3 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -383,16 +383,28 @@ func agentResource() *schema.Resource { } if rd.HasChange("resources_monitoring") { - monitors, ok := rd.Get("resources_monitoring").(*schema.Set) + rmResource, ok := rd.Get("resources_monitoring").(*schema.Set) if !ok { - return xerrors.Errorf("unexpected type %T for resources_monitoring.0.volume, expected []any", rd.Get("resources_monitoring.0.volume")) + return xerrors.Errorf("unexpected type %T for resources_monitoring, expected []any", rd.Get("resources_monitoring")) } - monitor := monitors.List()[0].(map[string]any) + rmResourceAsList := rmResource.List() + if len(rmResourceAsList) == 0 { + return xerrors.Errorf("developer error: resources_monitoring cannot be empty") + } + rawMonitors := rmResourceAsList[0] + if rawMonitors == nil { + return xerrors.Errorf("resources_monitoring must define at least one monitor") + } + + monitors, ok := rawMonitors.(map[string]any) + if !ok { + return xerrors.Errorf("unexpected type %T for resources_monitoring.0.volume, expected []any", rawMonitors) + } - volumes, ok := monitor["volume"].(*schema.Set) + volumes, ok := monitors["volume"].(*schema.Set) if !ok { - return xerrors.Errorf("unexpected type %T for resources_monitoring.0.volume, expected []any", monitor["volume"]) + return xerrors.Errorf("unexpected type %T for resources_monitoring.0.volume, expected []any", monitors["volume"]) } paths := map[string]bool{} @@ -403,7 +415,6 @@ func agentResource() *schema.Resource { } // print path for debug purpose - path, ok := obj["path"].(string) if !ok { return xerrors.Errorf("unexpected type %T for volume path, expected string", obj["path"]) diff --git a/provider/agent_test.go b/provider/agent_test.go index 82e8691f..34e88f1e 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -352,6 +352,26 @@ func TestAgent_ResourcesMonitoring(t *testing.T) { }) }) + t.Run("MissingMonitors", func(t *testing.T) { + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + resources_monitoring {} + }`, + Check: nil, + ExpectError: regexp.MustCompile(`resources_monitoring must define at least one monitor`), + }}, + }) + }) + t.Run("DuplicatePaths", func(t *testing.T) { resource.Test(t, resource.TestCase{ ProviderFactories: coderFactory(),