Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions registry/coder/modules/github-upload-public-key/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ Templates that utilize Github External Auth can automatically ensure that the Co
module "github-upload-public-key" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/github-upload-public-key/coder"
version = "1.0.32"
version = "1.1.0"
agent_id = coder_agent.main.id
key_name = "ACME Coder Workspaces"
}
```

`key_name` is optional. If omitted, GitHub displays the uploaded key as `<Coder access URL> Workspaces`.

## Requirements

This module requires `curl` and `jq` to be installed inside your workspace.
Expand Down Expand Up @@ -47,7 +50,7 @@ data "coder_external_auth" "github" {
module "github-upload-public-key" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/github-upload-public-key/coder"
version = "1.0.32"
version = "1.1.0"
agent_id = coder_agent.main.id
external_auth_id = data.coder_external_auth.github.id
}
Expand Down
42 changes: 36 additions & 6 deletions registry/coder/modules/github-upload-public-key/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const setupContainer = async (
image = "lorello/alpine-bash",
vars: Record<string, string> = {},
) => {
const server = setupServer();
const { server, uploadedKeyNames } = setupServer();
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
...vars,
Expand All @@ -54,12 +54,13 @@ const setupContainer = async (
await removeContainer(id);
});

return { id, instance, server };
return { id, instance, server, uploadedKeyNames };
};

const setupServer = () => {
const fakeGithubHost = serve({
fetch: (req) => {
const uploadedKeyNames: string[] = [];
const server = serve({
fetch: async (req) => {
const url = new URL(req.url);
if (url.pathname === "/api/v2/users/me/gitsshkey") {
return createJSONResponse({
Expand All @@ -69,6 +70,8 @@ const setupServer = () => {

if (url.pathname === "/user/keys") {
if (req.method === "POST") {
const body = (await req.json()) as { title: string };
uploadedKeyNames.push(body.title);
return createJSONResponse(
{
key: "created",
Expand Down Expand Up @@ -107,7 +110,7 @@ const setupServer = () => {
port: 0,
});

return fakeGithubHost;
return { server, uploadedKeyNames };
};

setDefaultTimeout(30 * 1000);
Expand All @@ -122,7 +125,33 @@ describe("github-upload-public-key", () => {
});

it("creates new key if one does not exist", async () => {
const { instance, id, server } = await setupContainer();
const { instance, id, server, uploadedKeyNames } = await setupContainer();
await writeCoder(id, "echo foo");

const url = server.url.toString().slice(0, -1);
const exec = await execContainer(id, [
"env",
`CODER_ACCESS_URL=${url}`,
`GITHUB_API_URL=${url}`,
"CODER_OWNER_SESSION_TOKEN=foo",
"CODER_EXTERNAL_AUTH_ID=github",
"bash",
"-c",
instance.script,
]);
expect(exec.stdout).toContain(
"Your Coder public key has been added to GitHub!",
);
expect(exec.exitCode).toBe(0);
expect(uploadedKeyNames).toEqual([`${url} Workspaces`]);
});

it("uses a custom key name", async () => {
const keyName = "ACME Coder Workspaces";
const { instance, id, server, uploadedKeyNames } = await setupContainer(
undefined,
{ key_name: keyName },
);
await writeCoder(id, "echo foo");

const url = server.url.toString().slice(0, -1);
Expand All @@ -140,6 +169,7 @@ describe("github-upload-public-key", () => {
"Your Coder public key has been added to GitHub!",
);
expect(exec.exitCode).toBe(0);
expect(uploadedKeyNames).toEqual([keyName]);
});

it("does nothing if one already exists", async () => {
Expand Down
9 changes: 8 additions & 1 deletion registry/coder/modules/github-upload-public-key/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ variable "github_api_url" {
default = "https://api.github.com"
}

variable "key_name" {
description = "The title assigned to the uploaded SSH key in GitHub. Defaults to '<Coder access URL> Workspaces'."
type = string
default = null
}

data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

Expand All @@ -36,8 +42,9 @@ resource "coder_script" "github_upload_public_key" {
CODER_ACCESS_URL : data.coder_workspace.me.access_url,
CODER_EXTERNAL_AUTH_ID : var.external_auth_id,
GITHUB_API_URL : var.github_api_url,
CODER_PUBLIC_KEY_NAME : var.key_name == null ? "" : var.key_name,
})
display_name = "Github Upload Public Key"
icon = "/icon/github.svg"
run_on_start = true
}
}
3 changes: 2 additions & 1 deletion registry/coder/modules/github-upload-public-key/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ if [ "$PUBLIC_KEY" = "$GITHUB_MATCH" ]; then
fi

echo "Your Coder public key is not in GitHub. Adding it now..."
CODER_PUBLIC_KEY_NAME="$CODER_ACCESS_URL Workspaces"
CODER_PUBLIC_KEY_NAME="${CODER_PUBLIC_KEY_NAME}"
[ -n "$CODER_PUBLIC_KEY_NAME" ] || CODER_PUBLIC_KEY_NAME="$CODER_ACCESS_URL Workspaces"
UPLOAD_RESPONSE=$(
curl -L -s \
-X POST \
Expand Down