Compare commits

..

3 Commits

Author SHA1 Message Date
Guspan Tanadi
7c8aa504ae docs(vault-jwt): update OIDC docs link (#388)
Co-authored-by: M Atif Ali <atif@coder.com>
2025-01-29 10:50:57 +00:00
Michael Smith
e64f1ede52 fix: ensure Terraform is available for integration tests (#390) 2025-01-28 11:13:07 +05:00
Phorcys
c8a42f6202 chore: make agent_name unused (#383) 2025-01-10 20:05:24 +00:00
11 changed files with 54 additions and 49 deletions

View File

@@ -16,14 +16,23 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - name: Check out code
- uses: coder/coder/.github/actions/setup-tf@main uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2 - name: Set up Terraform
uses: coder/coder/.github/actions/setup-tf@main
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with: with:
# We're using the latest version of Bun for now, but it might be worth
# reconsidering. They've pushed breaking changes in patch releases
# that have broken our CI.
# Our PR where issues started to pop up: https://github.com/coder/modules/pull/383
# The Bun PR that broke things: https://github.com/oven-sh/bun/pull/16067
bun-version: latest bun-version: latest
- name: Setup - name: Install dependencies
run: bun install run: bun install
- run: bun test - name: Run tests
run: bun test
pretty: pretty:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

View File

@@ -19,7 +19,7 @@ Under the hood, this module uses the [coder dotfiles](https://coder.com/docs/v2/
module "dotfiles" { module "dotfiles" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/dotfiles/coder" source = "registry.coder.com/modules/dotfiles/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```
@@ -32,7 +32,7 @@ module "dotfiles" {
module "dotfiles" { module "dotfiles" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/dotfiles/coder" source = "registry.coder.com/modules/dotfiles/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```
@@ -43,7 +43,7 @@ module "dotfiles" {
module "dotfiles" { module "dotfiles" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/dotfiles/coder" source = "registry.coder.com/modules/dotfiles/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
user = "root" user = "root"
} }
@@ -55,14 +55,14 @@ module "dotfiles" {
module "dotfiles" { module "dotfiles" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/dotfiles/coder" source = "registry.coder.com/modules/dotfiles/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
module "dotfiles-root" { module "dotfiles-root" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/dotfiles/coder" source = "registry.coder.com/modules/dotfiles/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
user = "root" user = "root"
dotfiles_uri = module.dotfiles.dotfiles_uri dotfiles_uri = module.dotfiles.dotfiles_uri
@@ -77,7 +77,7 @@ You can set a default dotfiles repository for all users by setting the `default_
module "dotfiles" { module "dotfiles" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/dotfiles/coder" source = "registry.coder.com/modules/dotfiles/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
default_dotfiles_uri = "https://github.com/coder/dotfiles" default_dotfiles_uri = "https://github.com/coder/dotfiles"
} }

View File

@@ -18,6 +18,6 @@ if [ -n "$${DOTFILES_URI// }" ]; then
CODER_BIN=$(which coder) CODER_BIN=$(which coder)
DOTFILES_USER_HOME=$(eval echo ~"$DOTFILES_USER") DOTFILES_USER_HOME=$(eval echo ~"$DOTFILES_USER")
sudo -u "$DOTFILES_USER" sh -c "'$CODER_BIN' dotfiles '$DOTFILES_URI' -y 2>&1 | tee '$DOTFILES_USER_HOME'/.dotfiles.log || true" sudo -u "$DOTFILES_USER" sh -c "'$CODER_BIN' dotfiles '$DOTFILES_URI' -y 2>&1 | tee '$DOTFILES_USER_HOME'/.dotfiles.log"
fi fi
fi fi

View File

@@ -15,7 +15,7 @@ This module allows you to automatically clone a repository by URL and skip if it
module "git-clone" { module "git-clone" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://github.com/coder/coder" url = "https://github.com/coder/coder"
} }
@@ -29,7 +29,7 @@ module "git-clone" {
module "git-clone" { module "git-clone" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://github.com/coder/coder" url = "https://github.com/coder/coder"
base_dir = "~/projects/coder" base_dir = "~/projects/coder"
@@ -44,7 +44,7 @@ To use with [Git Authentication](https://coder.com/docs/v2/latest/admin/git-prov
module "git-clone" { module "git-clone" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://github.com/coder/coder" url = "https://github.com/coder/coder"
} }
@@ -70,7 +70,7 @@ data "coder_parameter" "git_repo" {
module "git_clone" { module "git_clone" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = data.coder_parameter.git_repo.value url = data.coder_parameter.git_repo.value
} }
@@ -79,7 +79,7 @@ module "git_clone" {
module "code-server" { module "code-server" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/code-server/coder" source = "registry.coder.com/modules/code-server/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
order = 1 order = 1
folder = "/home/${local.username}/${module.git_clone[count.index].folder_name}" folder = "/home/${local.username}/${module.git_clone[count.index].folder_name}"
@@ -104,7 +104,7 @@ Configuring `git-clone` for a self-hosted GitHub Enterprise Server running at `g
module "git-clone" { module "git-clone" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://github.example.com/coder/coder/tree/feat/example" url = "https://github.example.com/coder/coder/tree/feat/example"
git_providers = { git_providers = {
@@ -123,7 +123,7 @@ To GitLab clone with a specific branch like `feat/example`
module "git-clone" { module "git-clone" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://gitlab.com/coder/coder/-/tree/feat/example" url = "https://gitlab.com/coder/coder/-/tree/feat/example"
} }
@@ -135,7 +135,7 @@ Configuring `git-clone` for a self-hosted GitLab running at `gitlab.example.com`
module "git-clone" { module "git-clone" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://gitlab.example.com/coder/coder/-/tree/feat/example" url = "https://gitlab.example.com/coder/coder/-/tree/feat/example"
git_providers = { git_providers = {
@@ -156,7 +156,7 @@ For example, to clone the `feat/example` branch:
module "git-clone" { module "git-clone" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://github.com/coder/coder" url = "https://github.com/coder/coder"
branch_name = "feat/example" branch_name = "feat/example"
@@ -173,7 +173,7 @@ For example, this will clone into the `~/projects/coder/coder-dev` folder:
module "git-clone" { module "git-clone" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.28" version = "1.0.18"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://github.com/coder/coder" url = "https://github.com/coder/coder"
folder_name = "coder-dev" folder_name = "coder-dev"

View File

@@ -9,7 +9,7 @@ CLONE_PATH="$${CLONE_PATH/#\~/$${HOME}}"
# Check if the variable is empty... # Check if the variable is empty...
if [ -z "$REPO_URL" ]; then if [ -z "$REPO_URL" ]; then
echo "No repository specified!" echo "No repository specified!"
exit 0 exit 1
fi fi
# Check if the variable is empty... # Check if the variable is empty...

View File

@@ -15,9 +15,8 @@ This module adds a JetBrains Gateway Button to open any workspace with a single
module "jetbrains_gateway" { module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/jetbrains-gateway/coder" source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.27" version = "1.0.28"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example" folder = "/home/coder/example"
jetbrains_ides = ["CL", "GO", "IU", "PY", "WS"] jetbrains_ides = ["CL", "GO", "IU", "PY", "WS"]
default = "GO" default = "GO"
@@ -34,9 +33,8 @@ module "jetbrains_gateway" {
module "jetbrains_gateway" { module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/jetbrains-gateway/coder" source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.27" version = "1.0.28"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example" folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS"] jetbrains_ides = ["GO", "WS"]
default = "GO" default = "GO"
@@ -49,9 +47,8 @@ module "jetbrains_gateway" {
module "jetbrains_gateway" { module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/jetbrains-gateway/coder" source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.27" version = "1.0.28"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example" folder = "/home/coder/example"
jetbrains_ides = ["IU", "PY"] jetbrains_ides = ["IU", "PY"]
default = "IU" default = "IU"
@@ -65,9 +62,8 @@ module "jetbrains_gateway" {
module "jetbrains_gateway" { module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/jetbrains-gateway/coder" source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.27" version = "1.0.28"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example" folder = "/home/coder/example"
jetbrains_ides = ["IU", "PY"] jetbrains_ides = ["IU", "PY"]
default = "IU" default = "IU"
@@ -91,9 +87,8 @@ module "jetbrains_gateway" {
module "jetbrains_gateway" { module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/jetbrains-gateway/coder" source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.27" version = "1.0.28"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example" folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS"] jetbrains_ides = ["GO", "WS"]
default = "GO" default = "GO"
@@ -110,9 +105,8 @@ Due to the highest priority of the `ide_download_link` parameter in the `(jetbra
module "jetbrains_gateway" { module "jetbrains_gateway" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/jetbrains-gateway/coder" source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.27" version = "1.0.28"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example" folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS"] jetbrains_ides = ["GO", "WS"]
releases_base_link = "https://releases.internal.site/" releases_base_link = "https://releases.internal.site/"

View File

@@ -10,7 +10,6 @@ describe("jetbrains-gateway", async () => {
await testRequiredVariables(import.meta.dir, { await testRequiredVariables(import.meta.dir, {
agent_id: "foo", agent_id: "foo",
agent_name: "foo",
folder: "/home/foo", folder: "/home/foo",
}); });
@@ -18,11 +17,10 @@ describe("jetbrains-gateway", async () => {
const state = await runTerraformApply(import.meta.dir, { const state = await runTerraformApply(import.meta.dir, {
// These are all required. // These are all required.
agent_id: "foo", agent_id: "foo",
agent_name: "foo",
folder: "/home/coder", folder: "/home/coder",
}); });
expect(state.outputs.url.value).toBe( expect(state.outputs.url.value).toBe(
"jetbrains-gateway://connect#type=coder&workspace=default&owner=default&agent=foo&folder=/home/coder&url=https://mydeployment.coder.com&token=$SESSION_TOKEN&ide_product_code=IU&ide_build_number=243.21565.193&ide_download_link=https://download.jetbrains.com/idea/ideaIU-2024.3.tar.gz", "jetbrains-gateway://connect#type=coder&workspace=default&owner=default&folder=/home/coder&url=https://mydeployment.coder.com&token=$SESSION_TOKEN&ide_product_code=IU&ide_build_number=243.21565.193&ide_download_link=https://download.jetbrains.com/idea/ideaIU-2024.3.tar.gz",
); );
const coder_app = state.resources.find( const coder_app = state.resources.find(
@@ -37,7 +35,6 @@ describe("jetbrains-gateway", async () => {
it("default to first ide", async () => { it("default to first ide", async () => {
const state = await runTerraformApply(import.meta.dir, { const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo", agent_id: "foo",
agent_name: "foo",
folder: "/home/foo", folder: "/home/foo",
jetbrains_ides: '["IU", "GO", "PY"]', jetbrains_ides: '["IU", "GO", "PY"]',
}); });

View File

@@ -26,7 +26,9 @@ variable "slug" {
variable "agent_name" { variable "agent_name" {
type = string type = string
description = "Agent name." description = "Agent name. (unused). Will be removed in a future version"
default = ""
} }
variable "folder" { variable "folder" {
@@ -295,8 +297,6 @@ resource "coder_app" "gateway" {
data.coder_workspace.me.name, data.coder_workspace.me.name,
"&owner=", "&owner=",
data.coder_workspace_owner.me.name, data.coder_workspace_owner.me.name,
"&agent=",
var.agent_name,
"&folder=", "&folder=",
var.folder, var.folder,
"&url=", "&url=",

View File

@@ -25,7 +25,7 @@ const removeOldContainers = async () => {
"-a", "-a",
"-q", "-q",
"--filter", "--filter",
`label=modules-test`, "label=modules-test",
]); ]);
let containerIDsRaw = await readableStreamToText(proc.stdout); let containerIDsRaw = await readableStreamToText(proc.stdout);
let exitCode = await proc.exited; let exitCode = await proc.exited;

15
test.ts
View File

@@ -194,13 +194,18 @@ export const testRequiredVariables = <TVars extends TerraformVariables>(
export const runTerraformApply = async <TVars extends TerraformVariables>( export const runTerraformApply = async <TVars extends TerraformVariables>(
dir: string, dir: string,
vars: Readonly<TVars>, vars: Readonly<TVars>,
env?: Record<string, string>, customEnv?: Record<string, string>,
): Promise<TerraformState> => { ): Promise<TerraformState> => {
const stateFile = `${dir}/${crypto.randomUUID()}.tfstate`; const stateFile = `${dir}/${crypto.randomUUID()}.tfstate`;
const combinedEnv = env === undefined ? {} : { ...env }; const childEnv: Record<string, string | undefined> = {
for (const [key, value] of Object.entries(vars)) { ...process.env,
combinedEnv[`TF_VAR_${key}`] = String(value); ...(customEnv ?? {}),
};
for (const [key, value] of Object.entries(vars) as [string, JsonValue][]) {
if (value !== null) {
childEnv[`TF_VAR_${key}`] = String(value);
}
} }
const proc = spawn( const proc = spawn(
@@ -216,7 +221,7 @@ export const runTerraformApply = async <TVars extends TerraformVariables>(
], ],
{ {
cwd: dir, cwd: dir,
env: combinedEnv, env: childEnv,
stderr: "pipe", stderr: "pipe",
stdout: "pipe", stdout: "pipe",
}, },

View File

@@ -10,7 +10,7 @@ tags: [helper, integration, vault, jwt, oidc]
# Hashicorp Vault Integration (JWT) # Hashicorp Vault Integration (JWT)
This module lets you authenticate with [Hashicorp Vault](https://www.vaultproject.io/) in your Coder workspaces by reusing the [OIDC](https://coder.com/docs/admin/auth#openid-connect) access token from Coder's OIDC authentication method. This requires configuring the Vault [JWT/OIDC](https://developer.hashicorp.com/vault/docs/auth/jwt#configuration) auth method. This module lets you authenticate with [Hashicorp Vault](https://www.vaultproject.io/) in your Coder workspaces by reusing the [OIDC](https://coder.com/docs/admin/users/oidc-auth) access token from Coder's OIDC authentication method. This requires configuring the Vault [JWT/OIDC](https://developer.hashicorp.com/vault/docs/auth/jwt#configuration) auth method.
```tf ```tf
module "vault" { module "vault" {