diff --git a/docs/resources/devcontainer.md b/docs/resources/devcontainer.md new file mode 100644 index 0000000..93d5724 --- /dev/null +++ b/docs/resources/devcontainer.md @@ -0,0 +1,29 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "coder_devcontainer Resource - terraform-provider-coder" +subcategory: "" +description: |- + Define a Dev Container the agent should know of and attempt to autostart (minimum Coder version: v2.21). +--- + +# coder_devcontainer (Resource) + +Define a Dev Container the agent should know of and attempt to autostart (minimum Coder version: v2.21). + + + + +## Schema + +### Required + +- `agent_id` (String) The `id` property of a `coder_agent` resource to associate with. +- `workspace_folder` (String) The workspace folder to for the Dev Container. + +### Optional + +- `config_path` (String) The path to the Dev Container configuration file (devcontainer.json). + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/provider/devcontainer.go b/provider/devcontainer.go new file mode 100644 index 0000000..7d1fe0a --- /dev/null +++ b/provider/devcontainer.go @@ -0,0 +1,46 @@ +package provider + +import ( + "context" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func devcontainerResource() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Description: "Define a Dev Container the agent should know of and attempt to autostart (minimum Coder version: v2.21).", + CreateContext: func(_ context.Context, rd *schema.ResourceData, _ interface{}) diag.Diagnostics { + rd.SetId(uuid.NewString()) + + return nil + }, + ReadContext: schema.NoopContext, + DeleteContext: schema.NoopContext, + Schema: map[string]*schema.Schema{ + "agent_id": { + Type: schema.TypeString, + Description: "The `id` property of a `coder_agent` resource to associate with.", + ForceNew: true, + Required: true, + }, + "workspace_folder": { + Type: schema.TypeString, + Description: "The workspace folder to for the Dev Container.", + ForceNew: true, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "config_path": { + Type: schema.TypeString, + Description: "The path to the Dev Container configuration file (devcontainer.json).", + ForceNew: true, + Optional: true, + }, + }, + } +} diff --git a/provider/devcontainer_test.go b/provider/devcontainer_test.go new file mode 100644 index 0000000..784cfb0 --- /dev/null +++ b/provider/devcontainer_test.go @@ -0,0 +1,98 @@ +package provider_test + +import ( + "regexp" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestDevcontainer(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_devcontainer" "example" { + agent_id = "king" + workspace_folder = "/workspace" + config_path = "/workspace/devcontainer.json" + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + script := state.Modules[0].Resources["coder_devcontainer.example"] + require.NotNil(t, script) + t.Logf("script attributes: %#v", script.Primary.Attributes) + for key, expected := range map[string]string{ + "agent_id": "king", + "workspace_folder": "/workspace", + "config_path": "/workspace/devcontainer.json", + } { + require.Equal(t, expected, script.Primary.Attributes[key]) + } + return nil + }, + }}, + }) +} + +func TestDevcontainerNoConfigPath(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_devcontainer" "example" { + agent_id = "king" + workspace_folder = "/workspace" + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + script := state.Modules[0].Resources["coder_devcontainer.example"] + require.NotNil(t, script) + t.Logf("script attributes: %#v", script.Primary.Attributes) + for key, expected := range map[string]string{ + "agent_id": "king", + "workspace_folder": "/workspace", + } { + require.Equal(t, expected, script.Primary.Attributes[key]) + } + return nil + }, + }}, + }) +} + +func TestDevcontainerNoWorkspaceFolder(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + } + resource "coder_devcontainer" "example" { + agent_id = "" + } + `, + ExpectError: regexp.MustCompile(`The argument "workspace_folder" is required, but no definition was found.`), + }}, + }) +} diff --git a/provider/provider.go b/provider/provider.go index d9780d7..cc2644e 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -76,6 +76,7 @@ func New() *schema.Provider { "coder_metadata": metadataResource(), "coder_script": scriptResource(), "coder_env": envResource(), + "coder_devcontainer": devcontainerResource(), }, } }