diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index 8b824c37..26396ba1 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -13,11 +13,51 @@ Use this data source to get information for the active workspace build. ## Example Usage ```terraform -data "coder_workspace" "dev" { +provider "coder" {} + +provider "docker" {} + +data "coder_workspace" "me" {} + +data "coder_workspace_owner" "me" {} + +resource "coder_agent" "dev" { + arch = "amd64" + os = "linux" + dir = "/workspace" } -resource "kubernetes_pod" "dev" { - count = data.coder_workspace.dev.transition == "start" ? 1 : 0 +resource "docker_container" "workspace" { + count = data.coder_workspace.me.start_count + image = docker_image.main.name + # Uses lower() to avoid Docker restriction on container names. + name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" + # Hostname makes the shell more user friendly: coder@my-workspace:~$ + hostname = data.coder_workspace.me.name + # Use the docker gateway if the access URL is 127.0.0.1 + entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")] + env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] + host { + host = "host.docker.internal" + ip = "host-gateway" + } + # Add labels in Docker to keep track of orphan resources. + labels { + label = "coder.owner" + value = data.coder_workspace_owner.me.name + } + labels { + label = "coder.owner_id" + value = data.coder_workspace_owner.me.id + } + labels { + label = "coder.workspace_id" + value = data.coder_workspace.me.id + } + labels { + label = "coder.workspace_name" + value = data.coder_workspace.me.name + } } ``` @@ -30,13 +70,6 @@ resource "kubernetes_pod" "dev" { - `access_url` (String) The access URL of the Coder deployment provisioning this workspace. - `id` (String) UUID of the workspace. - `name` (String) Name of the workspace. -- `owner` (String, **Deprecated**: Use `coder_workspace_owner.name` instead.) Username of the workspace owner. -- `owner_email` (String, **Deprecated**: Use `coder_workspace_owner.email` instead.) Email address of the workspace owner. -- `owner_groups` (List of String, **Deprecated**: Use `coder_workspace_owner.groups` instead.) List of groups the workspace owner belongs to. -- `owner_id` (String, **Deprecated**: Use `coder_workspace_owner.id` instead.) UUID of the workspace owner. -- `owner_name` (String, **Deprecated**: Use `coder_workspace_owner.full_name` instead.) Name of the workspace owner. -- `owner_oidc_access_token` (String, **Deprecated**: Use `coder_workspace_owner.oidc_access_token` instead.) A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string. -- `owner_session_token` (String, **Deprecated**: Use `coder_workspace_owner.session_token` instead.) Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started. - `start_count` (Number) A computed count based on `transition` state. If `start`, count will equal 1. - `template_id` (String) ID of the workspace's template. - `template_name` (String) Name of the workspace's template. diff --git a/docs/data-sources/workspace_owner.md b/docs/data-sources/workspace_owner.md index 0deff622..1c64ea50 100644 --- a/docs/data-sources/workspace_owner.md +++ b/docs/data-sources/workspace_owner.md @@ -15,14 +15,12 @@ Use this data source to fetch information about the workspace owner. ```terraform provider "coder" {} -data "coder_workspace" "me" {} - data "coder_workspace_owner" "me" {} resource "coder_agent" "dev" { arch = "amd64" os = "linux" - dir = local.repo_dir + dir = "/workspace" env = { OIDC_TOKEN : data.coder_workspace_owner.me.oidc_access_token, } @@ -36,7 +34,7 @@ resource "coder_env" "git_author_name" { } resource "coder_env" "git_author_email" { - agent_id = var.agent_id + agent_id = coder_agent.dev.id name = "GIT_AUTHOR_EMAIL" value = data.coder_workspace_owner.me.email count = data.coder_workspace_owner.me.email != "" ? 1 : 0 diff --git a/examples/data-sources/coder_workspace/data-source.tf b/examples/data-sources/coder_workspace/data-source.tf index 4898439b..8eb4a8f8 100644 --- a/examples/data-sources/coder_workspace/data-source.tf +++ b/examples/data-sources/coder_workspace/data-source.tf @@ -1,6 +1,46 @@ -data "coder_workspace" "dev" { +provider "coder" {} + +provider "docker" {} + +data "coder_workspace" "me" {} + +data "coder_workspace_owner" "me" {} + +resource "coder_agent" "dev" { + arch = "amd64" + os = "linux" + dir = "/workspace" } -resource "kubernetes_pod" "dev" { - count = data.coder_workspace.dev.transition == "start" ? 1 : 0 +resource "docker_container" "workspace" { + count = data.coder_workspace.me.start_count + image = docker_image.main.name + # Uses lower() to avoid Docker restriction on container names. + name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" + # Hostname makes the shell more user friendly: coder@my-workspace:~$ + hostname = data.coder_workspace.me.name + # Use the docker gateway if the access URL is 127.0.0.1 + entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")] + env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] + host { + host = "host.docker.internal" + ip = "host-gateway" + } + # Add labels in Docker to keep track of orphan resources. + labels { + label = "coder.owner" + value = data.coder_workspace_owner.me.name + } + labels { + label = "coder.owner_id" + value = data.coder_workspace_owner.me.id + } + labels { + label = "coder.workspace_id" + value = data.coder_workspace.me.id + } + labels { + label = "coder.workspace_name" + value = data.coder_workspace.me.name + } } diff --git a/examples/data-sources/coder_workspace_owner/data-source.tf b/examples/data-sources/coder_workspace_owner/data-source.tf index fc27db6c..cad73e1e 100644 --- a/examples/data-sources/coder_workspace_owner/data-source.tf +++ b/examples/data-sources/coder_workspace_owner/data-source.tf @@ -1,13 +1,11 @@ provider "coder" {} -data "coder_workspace" "me" {} - data "coder_workspace_owner" "me" {} resource "coder_agent" "dev" { arch = "amd64" os = "linux" - dir = local.repo_dir + dir = "/workspace" env = { OIDC_TOKEN : data.coder_workspace_owner.me.oidc_access_token, } @@ -21,7 +19,7 @@ resource "coder_env" "git_author_name" { } resource "coder_env" "git_author_email" { - agent_id = var.agent_id + agent_id = coder_agent.dev.id name = "GIT_AUTHOR_EMAIL" value = data.coder_workspace_owner.me.email count = data.coder_workspace_owner.me.email != "" ? 1 : 0 diff --git a/integration/integration_test.go b/integration/integration_test.go index 75b35d20..8208d20a 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -71,25 +71,18 @@ func TestIntegration(t *testing.T) { name: "test-data-source", minVersion: "v0.0.0", expectedOutput: map[string]string{ - "provisioner.arch": runtime.GOARCH, - "provisioner.id": `[a-zA-Z0-9-]+`, - "provisioner.os": runtime.GOOS, - "workspace.access_port": `\d+`, - "workspace.access_url": `https?://\D+:\d+`, - "workspace.id": `[a-zA-z0-9-]+`, - "workspace.name": `test-data-source`, - "workspace.owner": `testing`, - "workspace.owner_email": `testing@coder\.com`, - "workspace.owner_groups": `\[\]`, - "workspace.owner_id": `[a-zA-Z0-9]+`, - "workspace.owner_name": `default`, - "workspace.owner_oidc_access_token": `^$`, // TODO: need a test OIDC integration - "workspace.owner_session_token": `[a-zA-Z0-9-]+`, - "workspace.start_count": `1`, - "workspace.template_id": `[a-zA-Z0-9-]+`, - "workspace.template_name": `test-data-source`, - "workspace.template_version": `.+`, - "workspace.transition": `start`, + "provisioner.arch": runtime.GOARCH, + "provisioner.id": `[a-zA-Z0-9-]+`, + "provisioner.os": runtime.GOOS, + "workspace.access_port": `\d+`, + "workspace.access_url": `https?://\D+:\d+`, + "workspace.id": `[a-zA-z0-9-]+`, + "workspace.name": `test-data-source`, + "workspace.start_count": `1`, + "workspace.template_id": `[a-zA-Z0-9-]+`, + "workspace.template_name": `test-data-source`, + "workspace.template_version": `.+`, + "workspace.transition": `start`, }, }, { @@ -103,13 +96,6 @@ func TestIntegration(t *testing.T) { "workspace.access_url": `https?://\D+:\d+`, "workspace.id": `[a-zA-z0-9-]+`, "workspace.name": ``, - "workspace.owner": `testing`, - "workspace.owner_email": `testing@coder\.com`, - "workspace.owner_groups": `\[\]`, - "workspace.owner_id": `[a-zA-Z0-9]+`, - "workspace.owner_name": `default`, - "workspace.owner_oidc_access_token": `^$`, // TODO: need a test OIDC integration - "workspace.owner_session_token": `[a-zA-Z0-9-]+`, "workspace.start_count": `1`, "workspace.template_id": `[a-zA-Z0-9-]+`, "workspace.template_name": `workspace-owner`, diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index 838125a0..6d4b85cd 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -9,9 +9,8 @@ terraform { } } -// TODO: test coder_external_auth and coder_git_auth +// TODO: test coder_external_auth // data coder_external_auth "me" {} -// data coder_git_auth "me" {} data "coder_provisioner" "me" {} data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} @@ -26,13 +25,6 @@ locals { "workspace.access_url" : data.coder_workspace.me.access_url, "workspace.id" : data.coder_workspace.me.id, "workspace.name" : data.coder_workspace.me.name, - "workspace.owner" : data.coder_workspace.me.owner, - "workspace.owner_email" : data.coder_workspace.me.owner_email, - "workspace.owner_groups" : jsonencode(data.coder_workspace.me.owner_groups), - "workspace.owner_id" : data.coder_workspace.me.owner_id, - "workspace.owner_name" : data.coder_workspace.me.owner_name, - "workspace.owner_oidc_access_token" : data.coder_workspace.me.owner_oidc_access_token, - "workspace.owner_session_token" : data.coder_workspace.me.owner_session_token, "workspace.start_count" : tostring(data.coder_workspace.me.start_count), "workspace.template_id" : data.coder_workspace.me.template_id, "workspace.template_name" : data.coder_workspace.me.template_name, diff --git a/integration/workspace-owner/main.tf b/integration/workspace-owner/main.tf index 580592cb..2be11d8e 100644 --- a/integration/workspace-owner/main.tf +++ b/integration/workspace-owner/main.tf @@ -9,9 +9,8 @@ terraform { } } -// TODO: test coder_external_auth and coder_git_auth +// TODO: test coder_external_auth // data coder_external_auth "me" {} -// data coder_git_auth "me" {} data "coder_provisioner" "me" {} data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} @@ -26,13 +25,6 @@ locals { "workspace.access_url" : data.coder_workspace.me.access_url, "workspace.id" : data.coder_workspace.me.id, "workspace.name" : data.coder_workspace.me.name, - "workspace.owner" : data.coder_workspace.me.owner, - "workspace.owner_email" : data.coder_workspace.me.owner_email, - "workspace.owner_groups" : jsonencode(data.coder_workspace.me.owner_groups), - "workspace.owner_id" : data.coder_workspace.me.owner_id, - "workspace.owner_name" : data.coder_workspace.me.owner_name, - "workspace.owner_oidc_access_token" : data.coder_workspace.me.owner_oidc_access_token, - "workspace.owner_session_token" : data.coder_workspace.me.owner_session_token, "workspace.start_count" : tostring(data.coder_workspace.me.start_count), "workspace.template_id" : data.coder_workspace.me.template_id, "workspace.template_name" : data.coder_workspace.me.template_name, diff --git a/provider/workspace.go b/provider/workspace.go index 3f667e8f..575fd60f 100644 --- a/provider/workspace.go +++ b/provider/workspace.go @@ -2,7 +2,6 @@ package provider import ( "context" - "encoding/json" "reflect" "strconv" @@ -28,37 +27,9 @@ func workspaceDataSource() *schema.Resource { } _ = rd.Set("start_count", count) - owner := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER", "default") - _ = rd.Set("owner", owner) - - ownerEmail := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER_EMAIL", "default@example.com") - _ = rd.Set("owner_email", ownerEmail) - - ownerGroupsText := helpers.OptionalEnv("CODER_WORKSPACE_OWNER_GROUPS") - var ownerGroups []string - if ownerGroupsText != "" { - err := json.Unmarshal([]byte(ownerGroupsText), &ownerGroups) - if err != nil { - return diag.Errorf("couldn't parse owner groups %q", ownerGroupsText) - } - } - _ = rd.Set("owner_groups", ownerGroups) - - ownerName := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER_NAME", "default") - _ = rd.Set("owner_name", ownerName) - - ownerID := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_OWNER_ID", uuid.Nil.String()) - _ = rd.Set("owner_id", ownerID) - - ownerOIDCAccessToken := helpers.OptionalEnv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN") - _ = rd.Set("owner_oidc_access_token", ownerOIDCAccessToken) - name := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_NAME", "default") rd.Set("name", name) - sessionToken := helpers.OptionalEnv("CODER_WORKSPACE_OWNER_SESSION_TOKEN") - _ = rd.Set("owner_session_token", sessionToken) - id := helpers.OptionalEnvOrDefault("CODER_WORKSPACE_ID", uuid.NewString()) rd.SetId(id) @@ -122,47 +93,6 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "Either `start` or `stop`. Use this to start/stop resources with `count`.", }, - "owner": { - Type: schema.TypeString, - Computed: true, - Description: "Username of the workspace owner.", - Deprecated: "Use `coder_workspace_owner.name` instead.", - }, - "owner_email": { - Type: schema.TypeString, - Computed: true, - Description: "Email address of the workspace owner.", - Deprecated: "Use `coder_workspace_owner.email` instead.", - }, - "owner_id": { - Type: schema.TypeString, - Computed: true, - Description: "UUID of the workspace owner.", - Deprecated: "Use `coder_workspace_owner.id` instead.", - }, - "owner_name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of the workspace owner.", - Deprecated: "Use `coder_workspace_owner.full_name` instead.", - }, - "owner_oidc_access_token": { - Type: schema.TypeString, - Computed: true, - Description: "A valid OpenID Connect access token of the workspace owner. " + - "This is only available if the workspace owner authenticated with OpenID Connect. " + - "If a valid token cannot be obtained, this value will be an empty string.", - Deprecated: "Use `coder_workspace_owner.oidc_access_token` instead.", - }, - "owner_groups": { - Type: schema.TypeList, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Computed: true, - Description: "List of groups the workspace owner belongs to.", - Deprecated: "Use `coder_workspace_owner.groups` instead.", - }, "id": { Type: schema.TypeString, Computed: true, @@ -173,12 +103,6 @@ func workspaceDataSource() *schema.Resource { Computed: true, Description: "Name of the workspace.", }, - "owner_session_token": { - Type: schema.TypeString, - Computed: true, - Description: "Session token for authenticating with a Coder deployment. It is regenerated everytime a workspace is started.", - Deprecated: "Use `coder_workspace_owner.session_token` instead.", - }, "template_id": { Type: schema.TypeString, Computed: true, diff --git a/provider/workspace_test.go b/provider/workspace_test.go index e53f30d4..12d5210b 100644 --- a/provider/workspace_test.go +++ b/provider/workspace_test.go @@ -14,13 +14,6 @@ import ( ) func TestWorkspace(t *testing.T) { - t.Setenv("CODER_WORKSPACE_OWNER", "owner123") - t.Setenv("CODER_WORKSPACE_OWNER_ID", "11111111-1111-1111-1111-111111111111") - t.Setenv("CODER_WORKSPACE_OWNER_NAME", "Mr Owner") - t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") - t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") - t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) - t.Setenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", "supersecret") t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") t.Setenv("CODER_WORKSPACE_TEMPLATE_NAME", "template123") t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") @@ -49,16 +42,9 @@ func TestWorkspace(t *testing.T) { t.Log(value) assert.Equal(t, "https://example.com:8080", attribs["access_url"]) assert.Equal(t, "8080", attribs["access_port"]) - assert.Equal(t, "owner123", attribs["owner"]) - assert.Equal(t, "11111111-1111-1111-1111-111111111111", attribs["owner_id"]) - assert.Equal(t, "Mr Owner", attribs["owner_name"]) - assert.Equal(t, "owner123@example.com", attribs["owner_email"]) - assert.Equal(t, "group1", attribs["owner_groups.0"]) - assert.Equal(t, "group2", attribs["owner_groups.1"]) assert.Equal(t, "templateID", attribs["template_id"]) assert.Equal(t, "template123", attribs["template_name"]) assert.Equal(t, "v1.2.3", attribs["template_version"]) - assert.Equal(t, "supersecret", attribs["owner_oidc_access_token"]) return nil }, }}, @@ -66,9 +52,6 @@ func TestWorkspace(t *testing.T) { } func TestWorkspace_UndefinedOwner(t *testing.T) { - t.Setenv("CODER_WORKSPACE_OWNER", "owner123") - t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") - t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") t.Setenv("CODER_WORKSPACE_TEMPLATE_NAME", "template123") t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3") @@ -95,8 +78,9 @@ func TestWorkspace_UndefinedOwner(t *testing.T) { value := attribs["transition"] require.NotNil(t, value) t.Log(value) - assert.Equal(t, "owner123", attribs["owner"]) - assert.Equal(t, "default@example.com", attribs["owner_email"]) + assert.Equal(t, "templateID", attribs["template_id"]) + assert.Equal(t, "template123", attribs["template_name"]) + assert.Equal(t, "v1.2.3", attribs["template_version"]) // Skip other asserts return nil }, @@ -107,13 +91,6 @@ func TestWorkspace_UndefinedOwner(t *testing.T) { func TestWorkspace_MissingTemplateName(t *testing.T) { t.Setenv("CODER_WORKSPACE_BUILD_ID", "1") // Let's pretend this is a workspace build - t.Setenv("CODER_WORKSPACE_OWNER", "owner123") - t.Setenv("CODER_WORKSPACE_OWNER_ID", "11111111-1111-1111-1111-111111111111") - t.Setenv("CODER_WORKSPACE_OWNER_NAME", "Mr Owner") - t.Setenv("CODER_WORKSPACE_OWNER_EMAIL", "owner123@example.com") - t.Setenv("CODER_WORKSPACE_OWNER_SESSION_TOKEN", "abc123") - t.Setenv("CODER_WORKSPACE_OWNER_GROUPS", `["group1", "group2"]`) - t.Setenv("CODER_WORKSPACE_OWNER_OIDC_ACCESS_TOKEN", "supersecret") t.Setenv("CODER_WORKSPACE_TEMPLATE_ID", "templateID") // CODER_WORKSPACE_TEMPLATE_NAME is missing t.Setenv("CODER_WORKSPACE_TEMPLATE_VERSION", "v1.2.3")
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: