diff --git a/CHANGELOG.md b/CHANGELOG.md index 52baa52f..5782292d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ ## Unreleased +### Changed + +Retrieve workspace directly in link handler when using wildcardSSH feature + ## 2.19.0 - 2025-02-21 ### Added diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderRestClient.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderRestClient.kt index 40d5934a..71c6e1ba 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderRestClient.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/CoderRestClient.kt @@ -176,6 +176,19 @@ open class CoderRestClient( return workspacesResponse.body()!!.workspaces } + /** + * Retrieves a specific workspace by owner and name. + * @throws [APIResponseException]. + */ + fun workspaceByOwnerAndName(owner: String, workspaceName: String): Workspace { + val workspaceResponse = retroRestClient.workspaceByOwnerAndName(owner, workspaceName).execute() + if (!workspaceResponse.isSuccessful) { + throw APIResponseException("retrieve workspace", url, workspaceResponse) + } + + return workspaceResponse.body()!! + } + /** * Retrieves all the agent names for all workspaces, including those that * are off. Meant to be used when configuring SSH. diff --git a/src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt b/src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt index b610a314..81976ed8 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt @@ -4,6 +4,7 @@ import com.coder.gateway.sdk.v2.models.BuildInfo import com.coder.gateway.sdk.v2.models.CreateWorkspaceBuildRequest import com.coder.gateway.sdk.v2.models.Template import com.coder.gateway.sdk.v2.models.User +import com.coder.gateway.sdk.v2.models.Workspace import com.coder.gateway.sdk.v2.models.WorkspaceBuild import com.coder.gateway.sdk.v2.models.WorkspaceResource import com.coder.gateway.sdk.v2.models.WorkspacesResponse @@ -22,6 +23,15 @@ interface CoderV2RestFacade { @GET("api/v2/users/me") fun me(): Call<User> + /** + * Retrieves a specific workspace by owner and name. + */ + @GET("api/v2/users/{user}/workspace/{workspace}") + fun workspaceByOwnerAndName( + @Path("user") user: String, + @Path("workspace") workspace: String, + ): Call<Workspace> + /** * Retrieves all workspaces the authenticated user has access to. */ diff --git a/src/main/kotlin/com/coder/gateway/util/LinkHandler.kt b/src/main/kotlin/com/coder/gateway/util/LinkHandler.kt index fbd5584b..c32a136e 100644 --- a/src/main/kotlin/com/coder/gateway/util/LinkHandler.kt +++ b/src/main/kotlin/com/coder/gateway/util/LinkHandler.kt @@ -57,11 +57,27 @@ open class LinkHandler( // owner is included, assume the current user. val owner = (parameters.owner() ?: client.me.username).ifBlank { client.me.username } - val workspaces = client.workspaces() - val workspace = - workspaces.firstOrNull { - it.ownerName == owner && it.name == workspaceName - } ?: throw IllegalArgumentException("The workspace $workspaceName does not exist") + val cli = + ensureCLI( + deploymentURL.toURL(), + client.buildInfo().version, + settings, + indicator, + ) + + var workspace : Workspace + var workspaces : List<Workspace> = emptyList() + var workspacesAndAgents : Set<Pair<Workspace, WorkspaceAgent>> = emptySet() + if (cli.features.wildcardSSH) { + workspace = client.workspaceByOwnerAndName(owner, workspaceName) + } else { + workspaces = client.workspaces() + workspace = + workspaces.firstOrNull { + it.ownerName == owner && it.name == workspaceName + } ?: throw IllegalArgumentException("The workspace $workspaceName does not exist") + workspacesAndAgents = client.withAgents(workspaces) + } when (workspace.latestBuild.status) { WorkspaceStatus.PENDING, WorkspaceStatus.STARTING -> @@ -96,14 +112,6 @@ open class LinkHandler( throw IllegalArgumentException("The agent \"${agent.name}\" has a status of \"${status.toString().lowercase()}\"; unable to connect") } - val cli = - ensureCLI( - deploymentURL.toURL(), - client.buildInfo().version, - settings, - indicator, - ) - // We only need to log in if we are using token-based auth. if (client.token != null) { indicator?.invoke("Authenticating Coder CLI...") @@ -111,11 +119,7 @@ open class LinkHandler( } indicator?.invoke("Configuring Coder CLI...") - if (cli.features.wildcardSSH) { - cli.configSsh(workspacesAndAgents = emptySet(), currentUser = client.me) - } else { - cli.configSsh(workspacesAndAgents = client.withAgents(workspaces), currentUser = client.me) - } + cli.configSsh(workspacesAndAgents, currentUser = client.me) val openDialog = parameters.ideProductCode().isNullOrBlank() ||