diff --git a/provider/agent.go b/provider/agent.go index 32da2e5..b9f8a6d 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 82e8691..34e88f1 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(),