diff --git a/.gitignore b/.gitignore index 4d5d5ad6..ff9f6a53 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ website/vendor # Binary terraform-provider-coder + +# direnv +.direnv diff --git a/.goreleaser.yml b/.goreleaser.yml index 658a715c..8b2c0012 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -60,3 +60,5 @@ changelog: use: github-native sort: asc abbrev: 0 +git: + tag_sort: -version:creatordate # if two tags reference the same commit, pick the latest one; see https://github.com/goreleaser/goreleaser/issues/4209 \ No newline at end of file diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 7c28b1f4..7df11e34 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -17,9 +17,10 @@ data "coder_workspace" "me" { } resource "coder_agent" "dev" { - os = "linux" - arch = "amd64" - dir = "/workspace" + os = "linux" + arch = "amd64" + dir = "/workspace" + api_key_scope = "all" display_apps { vscode = true vscode_insiders = false @@ -71,6 +72,7 @@ resource "kubernetes_pod" "dev" { ### Optional +- `api_key_scope` (String) Controls what API routes the agent token can access. Options: 'all' (full access) or 'no_user_data' (blocks /external-auth, /gitsshkey, and /gitauth routes) - `auth` (String) The authentication type the agent will use. Must be one of: `"token"`, `"google-instance-identity"`, `"aws-instance-identity"`, `"azure-instance-identity"`. - `connection_timeout` (Number) Time in seconds until the agent is marked as timed out when a connection with the server cannot be established. A value of zero never marks the agent as timed out. - `dir` (String) The starting directory when a user creates a shell session. Defaults to `"$HOME"`. diff --git a/examples/resources/coder_agent/resource.tf b/examples/resources/coder_agent/resource.tf index 6ccb07bf..7c219604 100644 --- a/examples/resources/coder_agent/resource.tf +++ b/examples/resources/coder_agent/resource.tf @@ -2,9 +2,10 @@ data "coder_workspace" "me" { } resource "coder_agent" "dev" { - os = "linux" - arch = "amd64" - dir = "/workspace" + os = "linux" + arch = "amd64" + dir = "/workspace" + api_key_scope = "all" display_apps { vscode = true vscode_insiders = false diff --git a/flake.lock b/flake.lock index d8033e14..ecf99d98 100644 --- a/flake.lock +++ b/flake.lock @@ -20,16 +20,16 @@ }, "nixpkgs": { "locked": { - "lastModified": 1714272655, - "narHash": "sha256-3/ghIWCve93ngkx5eNPdHIKJP/pMzSr5Wc4rNKE1wOc=", + "lastModified": 1746422338, + "narHash": "sha256-NTtKOTLQv6dPfRe00OGSywg37A1FYqldS6xiNmqBUYc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "12430e43bd9b81a6b4e79e64f87c624ade701eaf", + "rev": "5b35d248e9206c1f3baf8de6a7683fee126364aa", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.11", + "ref": "nixos-24.11", "repo": "nixpkgs", "type": "github" } diff --git a/flake.nix b/flake.nix index 87719bf4..40ceb861 100644 --- a/flake.nix +++ b/flake.nix @@ -2,11 +2,11 @@ description = "Terraform provider for Coder"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; flake-utils.url = "github:numtide/flake-utils"; }; - outputs = { self, nixpkgs, flake-utils, ... }: + outputs = { nixpkgs, flake-utils, ... }: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { @@ -21,7 +21,7 @@ name = "devShell"; buildInputs = with pkgs; [ terraform - go_1_20 + go_1_24 ]; }; } diff --git a/provider/agent.go b/provider/agent.go index ad264030..ebd8fff5 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -80,6 +80,17 @@ func agentResource() *schema.Resource { return nil }, Schema: map[string]*schema.Schema{ + "api_key_scope": { + Type: schema.TypeString, + Optional: true, + Default: "all", + ForceNew: true, + Description: "Controls what API routes the agent token can access. Options: 'all' (full access) or 'no_user_data' (blocks /external-auth, /gitsshkey, and /gitauth routes)", + ValidateFunc: validation.StringInSlice([]string{ + "all", + "no_user_data", + }, false), + }, "init_script": { Type: schema.TypeString, Computed: true, diff --git a/provider/agent_test.go b/provider/agent_test.go index a45ac86a..82e8691f 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -709,5 +709,96 @@ func TestAgent_DisplayApps(t *testing.T) { }}, }) }) +} + +// TestAgent_APIKeyScope tests valid states/transitions and invalid values for api_key_scope. +func TestAgent_APIKeyScope(t *testing.T) { + t.Parallel() + + t.Run("ValidTransitions", func(t *testing.T) { + t.Parallel() + + resourceName := "coder_agent.test_scope_valid" + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{ + // Step 1: Default value + { + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "test_scope_valid" { + os = "linux" + arch = "amd64" + # api_key_scope is omitted, should default to "default" + } + `, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "api_key_scope", "all"), + ), + }, + // Step 2: Explicit "default" + { + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "test_scope_valid" { + os = "linux" + arch = "amd64" + api_key_scope = "all" + } + `, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "api_key_scope", "all"), + ), + }, + // Step 3: Explicit "no_user_data" + { + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "test_scope_valid" { + os = "linux" + arch = "amd64" + api_key_scope = "no_user_data" + } + `, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "api_key_scope", "no_user_data"), + ), + }, + }, + }) + }) + + t.Run("InvalidValue", func(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProviderFactories: coderFactory(), + IsUnitTest: true, + Steps: []resource.TestStep{ + // Step 1: Invalid value check + { + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "test_scope_invalid" { // Use unique name + os = "linux" + arch = "amd64" + api_key_scope = "invalid-scope" + } + `, + ExpectError: regexp.MustCompile(`expected api_key_scope to be one of \["all" "no_user_data"\], got invalid-scope`), + PlanOnly: true, + }, + }, + }) + }) } diff --git a/provider/testdata/parameter_table.md b/provider/testdata/parameter_table.md index 6087460f..980a6d19 100644 --- a/provider/testdata/parameter_table.md +++ b/provider/testdata/parameter_table.md @@ -12,6 +12,8 @@ | EmptyMinOpt | number | | | | 1,2,3 | 2-5 | | | | valid option | | EmptyRegexOpt | string | | | | "hello","goodbye" | goodbye | | | | valid option | | EmptyRegexOk | string | | | | | .* | | "" | false | | +| EmptyInc | number | 4 | | | | increasing | | | | monotonicity | +| EmptyDec | number | 4 | | | | decreasing | | | | monotonicity | | | | | | | | | | | | | | | Default Set | | No inputs | | | | | | | | | NumDef | number | | | 5 | | | | 5 | true | |
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: