-
Notifications
You must be signed in to change notification settings - Fork 22
feat: add coder_env
#174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add coder_env
#174
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "coder_env Resource - terraform-provider-coder" | ||
subcategory: "" | ||
description: |- | ||
Use this resource to set an environment variable in a workspace. | ||
--- | ||
|
||
# coder_env (Resource) | ||
|
||
Use this resource to set an environment variable in a workspace. | ||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `agent_id` (String) The "id" property of a "coder_agent" resource to associate with. | ||
- `name` (String) The name of the environment variable. | ||
|
||
### Optional | ||
|
||
- `value` (String) The value of the environment variable. | ||
|
||
### Read-Only | ||
|
||
- `id` (String) The ID of this resource. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package provider | ||
|
||
import ( | ||
"context" | ||
"regexp" | ||
|
||
"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 envResource() *schema.Resource { | ||
return &schema.Resource{ | ||
Description: "Use this resource to set an environment variable in a workspace.", | ||
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, | ||
}, | ||
"name": { | ||
mafredri marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Type: schema.TypeString, | ||
Description: "The name of the environment variable.", | ||
ForceNew: true, | ||
Required: true, | ||
ValidateFunc: validation.StringMatch( | ||
regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`), | ||
"must be a valid environment variable name", | ||
), | ||
}, | ||
"value": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking loud: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the use-case? Maybe we can add it later if we identify one? Since this is an optional string the default value is empty string, which is just fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something similar to: using generic dot files if the user didn't provide a custom URL. But I agree to postpone it for later until we meet scenario. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe that can be handled in terraform? Like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is fine for now, thanks for challenging |
||
Type: schema.TypeString, | ||
Description: "The value of the environment variable.", | ||
ForceNew: true, | ||
Optional: true, | ||
}, | ||
}, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package provider_test | ||
|
||
import ( | ||
"regexp" | ||
"testing" | ||
|
||
"github.com/coder/terraform-provider-coder/provider" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
) | ||
|
||
func TestEnv(t *testing.T) { | ||
t.Parallel() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
Providers: map[string]*schema.Provider{ | ||
"coder": provider.New(), | ||
}, | ||
IsUnitTest: true, | ||
Steps: []resource.TestStep{{ | ||
Config: ` | ||
provider "coder" { | ||
} | ||
resource "coder_env" "example" { | ||
agent_id = "king" | ||
name = "MESSAGE" | ||
value = "Believe in yourself and there will come a day when others will have no choice but to believe with you." | ||
} | ||
`, | ||
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_env.example"] | ||
require.NotNil(t, script) | ||
t.Logf("script attributes: %#v", script.Primary.Attributes) | ||
for key, expected := range map[string]string{ | ||
"agent_id": "king", | ||
"name": "MESSAGE", | ||
"value": "Believe in yourself and there will come a day when others will have no choice but to believe with you.", | ||
} { | ||
require.Equal(t, expected, script.Primary.Attributes[key]) | ||
} | ||
return nil | ||
}, | ||
}}, | ||
}) | ||
} | ||
|
||
func TestEnvEmptyValue(t *testing.T) { | ||
t.Parallel() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
Providers: map[string]*schema.Provider{ | ||
"coder": provider.New(), | ||
}, | ||
IsUnitTest: true, | ||
Steps: []resource.TestStep{{ | ||
Config: ` | ||
provider "coder" { | ||
} | ||
resource "coder_env" "example" { | ||
agent_id = "king" | ||
name = "MESSAGE" | ||
} | ||
`, | ||
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_env.example"] | ||
require.NotNil(t, script) | ||
t.Logf("script attributes: %#v", script.Primary.Attributes) | ||
for key, expected := range map[string]string{ | ||
"agent_id": "king", | ||
"name": "MESSAGE", | ||
"value": "", | ||
} { | ||
require.Equal(t, expected, script.Primary.Attributes[key]) | ||
} | ||
return nil | ||
}, | ||
}}, | ||
}) | ||
} | ||
|
||
func TestEnvBadName(t *testing.T) { | ||
t.Parallel() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
Providers: map[string]*schema.Provider{ | ||
"coder": provider.New(), | ||
}, | ||
IsUnitTest: true, | ||
Steps: []resource.TestStep{{ | ||
Config: ` | ||
provider "coder" { | ||
} | ||
resource "coder_env" "example" { | ||
agent_id = "" | ||
name = "bad-name" | ||
} | ||
`, | ||
ExpectError: regexp.MustCompile(`must be a valid environment variable name`), | ||
}}, | ||
}) | ||
} | ||
|
||
func TestEnvNoName(t *testing.T) { | ||
mafredri marked this conversation as resolved.
Show resolved
Hide resolved
|
||
t.Parallel() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
Providers: map[string]*schema.Provider{ | ||
"coder": provider.New(), | ||
}, | ||
IsUnitTest: true, | ||
Steps: []resource.TestStep{{ | ||
Config: ` | ||
provider "coder" { | ||
} | ||
resource "coder_env" "example" { | ||
agent_id = "" | ||
} | ||
`, | ||
ExpectError: regexp.MustCompile(`The argument "name" is required, but no definition was found.`), | ||
}}, | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,6 +80,7 @@ func New() *schema.Provider { | |
"coder_app": appResource(), | ||
"coder_metadata": metadataResource(), | ||
"coder_script": scriptResource(), | ||
"coder_env": envResource(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking loud: Do we need an "opposite" resource? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For sure, I'd say that goes as a prop: |
||
}, | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered disallowing envs here, like
PATH
,CODER_AGENT_TOKEN
, etc. However, I opted for doing this agent side instead (we'll log an error).