From ca6b30b3baa11c2540cb63a99bebe2efdf7760e5 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Fri, 25 Mar 2022 09:43:29 -0600 Subject: [PATCH] feat: Add auth property to coder_agent_script (#5) This enables explicit definition of auth type, so the agent doesn't misinterpret the running environment. This also adds "username" and "name" properties to "coder_workspace" to allow for pretty resource naming inside a cloud. --- docs/data-sources/agent_script.md | 1 + docs/data-sources/workspace.md | 2 ++ docs/resources/agent.md | 10 +------ internal/provider/provider.go | 48 +++++++++++++++++------------- internal/provider/provider_test.go | 8 ++--- 5 files changed, 33 insertions(+), 36 deletions(-) diff --git a/docs/data-sources/agent_script.md b/docs/data-sources/agent_script.md index 3d019bae..c599ccf7 100644 --- a/docs/data-sources/agent_script.md +++ b/docs/data-sources/agent_script.md @@ -37,6 +37,7 @@ resource "kubernetes_pod" "dev" { ### Optional +- **auth** (String) The authentication type the agent will use. Must be one of: "token", "google-instance-identity", "aws-instance-identity", "azure-instance-identity". - **id** (String) The ID of this resource. ### Read-Only diff --git a/docs/data-sources/workspace.md b/docs/data-sources/workspace.md index d5f60a24..77f0e13a 100644 --- a/docs/data-sources/workspace.md +++ b/docs/data-sources/workspace.md @@ -30,6 +30,8 @@ resource "kubernetes_pod" "dev" { ### Read-Only +- **name** (String) Name of the workspace. - **transition** (String) Either "start" or "stop". Use this to start/stop resources with "count". +- **username** (String) Username of the workspace owner. diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 409851ad..237e608f 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -40,21 +40,13 @@ resource "google_compute_instance" "dev" { ### Optional -- **auth** (Block List, Max: 1) Authenticate an instance with zero-trust by using cloud metadata APIs. (see [below for nested schema](#nestedblock--auth)) - **env** (Map of String) A mapping of environment variables to set inside the workspace. - **id** (String) The ID of this resource. +- **instance_id** (String) An instance ID from a provisioned instance to enable zero-trust agent authentication. - **startup_script** (String) A script to run after the agent starts. ### Read-Only - **token** (String) Set the environment variable "CODER_TOKEN" with this token to authenticate an agent. - -### Nested Schema for `auth` - -Optional: - -- **instance_id** (String) A unique ID from the created compute resource to identify with cloud metadata APIs. -- **type** (String) The authentication type to use. Must be one of: "google-instance-identity". - diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 277c9172..65d919c4 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -65,6 +65,8 @@ func New() *schema.Provider { transition = "start" } rd.Set("transition", transition) + rd.Set("username", os.Getenv("CODER_WORKSPACE_USERNAME")) + rd.Set("name", os.Getenv("CODER_WORKSPACE_NAME")) return nil }, Schema: map[string]*schema.Schema{ @@ -73,6 +75,16 @@ func New() *schema.Provider { Computed: true, Description: `Either "start" or "stop". Use this to start/stop resources with "count".`, }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: "Username of the workspace owner.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the workspace.", + }, }, }, "coder_agent_script": { @@ -82,6 +94,10 @@ func New() *schema.Provider { if !valid { return diag.Errorf("config was unexpected type %q", reflect.TypeOf(i).String()) } + auth, valid := resourceData.Get("auth").(string) + if !valid { + return diag.Errorf("auth was unexpected type %q", reflect.TypeOf(resourceData.Get("auth"))) + } operatingSystem, valid := resourceData.Get("os").(string) if !valid { return diag.Errorf("os was unexpected type %q", reflect.TypeOf(resourceData.Get("os"))) @@ -97,6 +113,7 @@ func New() *schema.Provider { script := os.Getenv(fmt.Sprintf("CODER_AGENT_SCRIPT_%s_%s", operatingSystem, arch)) if script != "" { script = strings.ReplaceAll(script, "${ACCESS_URL}", accessURL.String()) + script = strings.ReplaceAll(script, "${AUTH_TYPE}", auth) } err = resourceData.Set("value", script) if err != nil { @@ -106,6 +123,13 @@ func New() *schema.Provider { return nil }, Schema: map[string]*schema.Schema{ + "auth": { + Type: schema.TypeString, + Default: "token", + Optional: true, + Description: `The authentication type the agent will use. Must be one of: "token", "google-instance-identity", "aws-instance-identity", "azure-instance-identity".`, + ValidateFunc: validation.StringInSlice([]string{"token", "google-instance-identity", "aws-instance-identity", "azure-instance-identity"}, false), + }, "os": { Type: schema.TypeString, Required: true, @@ -144,29 +168,11 @@ func New() *schema.Provider { return nil }, Schema: map[string]*schema.Schema{ - "auth": { + "instance_id": { ForceNew: true, - Description: "Authenticate an instance with zero-trust by using cloud metadata APIs.", - Type: schema.TypeList, + Description: "An instance ID from a provisioned instance to enable zero-trust agent authentication.", Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - ForceNew: true, - Description: `The authentication type to use. Must be one of: "google-instance-identity".`, - Optional: true, - Type: schema.TypeString, - ValidateFunc: validation.StringInSlice([]string{"google-instance-identity"}, false), - }, - "instance_id": { - ForceNew: true, - Description: "A unique ID from the created compute resource to identify with cloud metadata APIs.", - Optional: true, - Type: schema.TypeString, - }, - }, - }, + Type: schema.TypeString, }, "env": { ForceNew: true, diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 677b423f..fd98e012 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -117,10 +117,7 @@ func TestAgent(t *testing.T) { url = "https://example.com" } resource "coder_agent" "new" { - auth { - type = "google-instance-identity" - instance_id = "instance" - } + instance_id = "instance" env = { hi = "test" } @@ -133,8 +130,7 @@ func TestAgent(t *testing.T) { require.NotNil(t, resource) for _, key := range []string{ "token", - "auth.0.type", - "auth.0.instance_id", + "instance_id", "env.hi", "startup_script", } {