Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feature: Add setting to remove/set custom workspace filter for connections view.#490

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
bcpeinhardt merged 6 commits intomainfrombcpeinhardt/workspaces-filter
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes fromall 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
6 changes: 6 additions & 0 deletionsCHANGELOG.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,12 @@

## Unreleased

### Added

- Add ability to customize filter for workspace connections view.
- Add owner column to connections view table.
- Add ability to connect to workspaces you don't own but have permissions for.

## 2.14.2 - 2024-09-23

### Changed
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -144,6 +144,11 @@ class CoderSettingsConfigurable : BoundConfigurable("Coder") {
.bindText(state::sshLogDirectory)
.comment(CoderGatewayBundle.message("gateway.connector.settings.ssh-log-directory.comment"))
}.layout(RowLayout.PARENT_GRID)
row(CoderGatewayBundle.message("gateway.connector.settings.workspace-filter.title")) {
textField().resizableColumn().align(AlignX.FILL)
.bindText(state::workspaceFilter)
.comment(CoderGatewayBundle.message("gateway.connector.settings.workspace-filter.comment"))
}.layout(RowLayout.PARENT_GRID)
}
}

Expand Down
55 changes: 43 additions & 12 deletionssrc/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,6 +3,9 @@
import com.coder.gateway.cli.ex.MissingVersionException
import com.coder.gateway.cli.ex.ResponseException
import com.coder.gateway.cli.ex.SSHConfigFormatException
import com.coder.gateway.sdk.v2.models.User
import com.coder.gateway.sdk.v2.models.Workspace
import com.coder.gateway.sdk.v2.models.WorkspaceAgent
import com.coder.gateway.settings.CoderSettings
import com.coder.gateway.settings.CoderSettingsState
import com.coder.gateway.util.CoderHostnameVerifier
Expand DownExpand Up@@ -219,11 +222,12 @@
* This can take supported features for testing purposes only.
*/
fun configSsh(
workspaceNames: Set<String>,
workspacesAndAgents: Set<Pair<Workspace, WorkspaceAgent>>,
currentUser: User,
feats: Features = features,
) {
logger.info("Configuring SSH config at ${settings.sshConfigPath}")
writeSSHConfig(modifySSHConfig(readSSHConfig(),workspaceNames, feats))
writeSSHConfig(modifySSHConfig(readSSHConfig(),workspacesAndAgents, feats, currentUser))
}

/**
Expand All@@ -245,8 +249,9 @@
*/
private fun modifySSHConfig(
contents: String?,
workspaceNames: Set<String>,
workspaceNames: Set<Pair<Workspace, WorkspaceAgent>>,
feats: Features,
currentUser: User,
): String? {
val host = deploymentURL.safeHost()
val startBlock = "# --- START CODER JETBRAINS $host"
Expand DownExpand Up@@ -287,8 +292,8 @@
System.lineSeparator() + endBlock,
transform = {
"""
Host ${getHostName(deploymentURL, it)}
ProxyCommand ${proxyArgs.joinToString(" ")} $it
Host ${getHostName(deploymentURL, it.first, currentUser, it.second)}
ProxyCommand ${proxyArgs.joinToString(" ")} ${getWorkspaceParts(it.first, it.second)}
ConnectTimeout 0
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Expand All@@ -299,8 +304,8 @@
.plus("\n")
.plus(
"""
Host ${getBackgroundHostName(deploymentURL, it)}
ProxyCommand ${backgroundProxyArgs.joinToString(" ")} $it
Host ${getBackgroundHostName(deploymentURL, it.first, currentUser, it.second)}
ProxyCommand ${backgroundProxyArgs.joinToString(" ")} ${getWorkspaceParts(it.first, it.second)}
ConnectTimeout 0
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Expand DownExpand Up@@ -478,21 +483,47 @@

private val tokenRegex = "--token [^ ]+".toRegex()

/**
* This function returns the ssh host name generated for connecting to the workspace.
*/
@JvmStatic
fun getHostName(
url: URL,
workspaceName: String,
): String = "coder-jetbrains--$workspaceName--${url.safeHost()}"
workspace: Workspace,
currentUser: User,
agent: WorkspaceAgent,
): String =
// For a user's own workspace, we use the old syntax without a username for backwards compatibility,
// since the user might have recent connections that still use the old syntax.
if (currentUser.username == workspace.ownerName) {
"coder-jetbrains--${workspace.name}.${agent.name}--${url.safeHost()}"
} else {
"coder-jetbrains--${workspace.ownerName}--${workspace.name}.${agent.name}--${url.safeHost()}"
}

@JvmStatic
fun getBackgroundHostName(
url: URL,
workspaceName: String,
): String = getHostName(url, workspaceName) + "--bg"
workspace: Workspace,
currentUser: User,
agent: WorkspaceAgent,
): String {
return getHostName(url, workspace, currentUser, agent) + "--bg"
}


/**
* This function returns the identifier for the workspace to pass to the
* coder ssh proxy command.
*/
@JvmStatic
fun getWorkspaceParts(
workspace: Workspace,
agent: WorkspaceAgent,
): String = "${workspace.ownerName}/${workspace.name}.${agent.name}"

@JvmStatic
fun getBackgroundHostName(
hostname: String,
): String = hostname + "--bg"

Check notice on line 527 in src/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt

View workflow job for this annotation

GitHub Actions/ Qodana Community for JVM

String concatenation that can be converted to string template

'String' concatenation can be converted to a template
}
}
15 changes: 4 additions & 11 deletionssrc/main/kotlin/com/coder/gateway/sdk/CoderRestClient.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,14 +8,7 @@ import com.coder.gateway.sdk.convertors.OSConverter
import com.coder.gateway.sdk.convertors.UUIDConverter
import com.coder.gateway.sdk.ex.APIResponseException
import com.coder.gateway.sdk.v2.CoderV2RestFacade
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.WorkspaceTransition
import com.coder.gateway.sdk.v2.models.*
import com.coder.gateway.settings.CoderSettings
import com.coder.gateway.settings.CoderSettingsState
import com.coder.gateway.util.CoderHostnameVerifier
Expand DownExpand Up@@ -166,7 +159,7 @@ open class CoderRestClient(
* @throws [APIResponseException].
*/
fun workspaces(): List<Workspace> {
val workspacesResponse = retroRestClient.workspaces("owner:me").execute()
val workspacesResponse = retroRestClient.workspaces(settings.workspaceFilter).execute()
if (!workspacesResponse.isSuccessful) {
throw APIResponseException("retrieve workspaces", url, workspacesResponse)
}
Expand All@@ -178,12 +171,12 @@ open class CoderRestClient(
* Retrieves all the agent names for all workspaces, including those that
* are off. Meant to be used when configuring SSH.
*/
funagentNames(workspaces: List<Workspace>): Set<String> {
funwithAgents(workspaces: List<Workspace>): Set<Pair<Workspace, WorkspaceAgent>> {
// It is possible for there to be resources with duplicate names so we
// need to use a set.
return workspaces.flatMap { ws ->
ws.latestBuild.resources.ifEmpty { resources(ws) }.filter { it.agents != null }.flatMap { it.agents!! }.map {
"${ws.name}.${it.name}"
ws to it
}
}.toSet()
}
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,7 @@ data class Workspace(
@Json(name = "latest_build") val latestBuild: WorkspaceBuild,
@Json(name = "outdated") val outdated: Boolean,
@Json(name = "name") val name: String,
@Json(name = "owner_name") val ownerName: String,
)

/**
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -98,6 +98,8 @@ open class CoderSettingsState(
open var defaultURL: String = "",
// Value for --log-dir.
open var sshLogDirectory: String = "",
// Default filter for fetching workspaces
open var workspaceFilter: String = "owner:me"
)

/**
Expand DownExpand Up@@ -135,6 +137,12 @@ open class CoderSettings(
val enableDownloads: Boolean
get() = state.enableDownloads

/**
* The filter to apply when fetching workspaces (default is owner:me)
*/
val workspaceFilter: String
get() = state.workspaceFilter

/**
* Whether falling back to the data directory is allowed if the binary
* directory is not writable.
Expand Down
5 changes: 1 addition & 4 deletionssrc/main/kotlin/com/coder/gateway/util/Dialogs.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,14 +32,13 @@
* A dialog wrapper around CoderWorkspaceStepView.
*/
private class CoderWorkspaceStepDialog(
name: String,
private val state: CoderWorkspacesStepSelection,
) : DialogWrapper(true) {
private val view = CoderWorkspaceProjectIDEStepView(showTitle = false)

init {
init()
title = CoderGatewayBundle.message("gateway.connector.view.coder.remoteproject.choose.text",name)
title = CoderGatewayBundle.message("gateway.connector.view.coder.remoteproject.choose.text",CoderCLIManager.getWorkspaceParts(state.workspace, state.agent))

Check warning on line 41 in src/main/kotlin/com/coder/gateway/util/Dialogs.kt

View workflow job for this annotation

GitHub Actions/ Qodana Community for JVM

Incorrect string capitalization

String 'Choose IDE and project for workspace {0}' is not properly capitalized. It should have title capitalization
}

override fun show() {
Expand DownExpand Up@@ -71,7 +70,6 @@
}

fun askIDE(
name: String,
agent: WorkspaceAgent,
workspace: Workspace,
cli: CoderCLIManager,
Expand All@@ -82,7 +80,6 @@
ApplicationManager.getApplication().invokeAndWait {
val dialog =
CoderWorkspaceStepDialog(
name,
CoderWorkspacesStepSelection(agent, workspace, cli, client, workspaces),
)
data = dialog.showAndGetData()
Expand Down
6 changes: 3 additions & 3 deletionssrc/main/kotlin/com/coder/gateway/util/LinkHandler.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,7 +106,7 @@ open class LinkHandler(
}

indicator?.invoke("Configuring Coder CLI...")
cli.configSsh(client.agentNames(workspaces))
cli.configSsh(workspacesAndAgents =client.withAgents(workspaces), currentUser = client.me)

val name = "${workspace.name}.${agent.name}"
val openDialog =
Expand All@@ -116,14 +116,14 @@ open class LinkHandler(
parameters.folder().isNullOrBlank()

return if (openDialog) {
askIDE(name,agent, workspace, cli, client, workspaces) ?: throw MissingArgumentException("IDE selection aborted; unable to connect")
askIDE(agent, workspace, cli, client, workspaces) ?: throw MissingArgumentException("IDE selection aborted; unable to connect")
} else {
// Check that both the domain and the redirected domain are
// allowlisted. If not, check with the user whether to proceed.
verifyDownloadLink(parameters)
WorkspaceProjectIDE.fromInputs(
name = name,
hostname = CoderCLIManager.getHostName(deploymentURL.toURL(),name),
hostname = CoderCLIManager.getHostName(deploymentURL.toURL(),workspace, client.me, agent),
projectPath = parameters.folder(),
ideProductCode = parameters.ideProductCode(),
ideBuildNumber = parameters.ideBuildNumber(),
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -184,23 +184,22 @@ class CoderWorkspaceProjectIDEStepView(

// We use this when returning the connection params from data().
state = data

val name = "${data.workspace.name}.${data.agent.name}"
val name = CoderCLIManager.getWorkspaceParts(data.workspace, data.agent)
logger.info("Initializing workspace step for $name")

val homeDirectory = data.agent.expandedDirectory ?: data.agent.directory
tfProject.text = if (homeDirectory.isNullOrBlank()) "/home" else homeDirectory
titleLabel.text = CoderGatewayBundle.message("gateway.connector.view.coder.remoteproject.choose.text", name)
titleLabel.isVisible = showTitle
terminalLink.url = data.client.url.withPath("/me/$name/terminal").toString()
terminalLink.url = data.client.url.withPath("/$name/terminal").toString()

ideResolvingJob =
cs.launch(ModalityState.current().asContextElement()) {
try {
logger.info("Configuring Coder CLI...")
cbIDE.renderer = IDECellRenderer("Configuring Coder CLI...")
withContext(Dispatchers.IO) {
data.cliManager.configSsh(data.client.agentNames(data.workspaces))
data.cliManager.configSsh(data.client.withAgents(data.workspaces), data.client.me)
}

val ides =
Expand All@@ -215,7 +214,7 @@ class CoderWorkspaceProjectIDEStepView(
} else {
IDECellRenderer(CoderGatewayBundle.message("gateway.connector.view.coder.connect-ssh"))
}
val executor = createRemoteExecutor(CoderCLIManager.getBackgroundHostName(data.client.url,name))
val executor = createRemoteExecutor(CoderCLIManager.getBackgroundHostName(data.client.url,data.workspace, data.client.me, data.agent))

if (ComponentValidator.getInstance(tfProject).isEmpty) {
logger.info("Installing remote path validator...")
Expand DownExpand Up@@ -338,7 +337,7 @@ class CoderWorkspaceProjectIDEStepView(
workspace: Workspace,
agent: WorkspaceAgent,
): List<IdeWithStatus> {
val name ="${workspace.name}.${agent.name}"
val name =CoderCLIManager.getWorkspaceParts(workspace,agent)
logger.info("Retrieving available IDEs for $name...")
val workspaceOS =
if (agent.operatingSystem != null && agent.architecture != null) {
Expand DownExpand Up@@ -406,7 +405,7 @@ class CoderWorkspaceProjectIDEStepView(
val name = "${state.workspace.name}.${state.agent.name}"
selectedIDE.withWorkspaceProject(
name = name,
hostname = CoderCLIManager.getHostName(state.client.url,name),
hostname = CoderCLIManager.getHostName(state.client.url,state.workspace, state.client.me, state.agent),
projectPath = tfProject.text,
deploymentURL = state.client.url,
)
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
import com.intellij.openapi.application.asContextElement
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.observable.properties.ObservableMutableProperty

Check warning on line 36 in src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt

View workflow job for this annotation

GitHub Actions/ Qodana Community for JVM

Unused import directive

Unused import directive
import com.intellij.openapi.rd.util.launchUnderBackgroundProgress
import com.intellij.openapi.ui.panel.ComponentPanelBuilder
import com.intellij.openapi.ui.setEmptyState
Expand DownExpand Up@@ -89,7 +90,7 @@
private data class CoderWorkspacesFormFields(
var coderURL: String = "",
var token: Pair<String, Source>? = null,
var useExistingToken: Boolean = false,
var useExistingToken: Boolean = false
)

/**
Expand DownExpand Up@@ -751,7 +752,7 @@
override fun data(): CoderWorkspacesStepSelection {
val selected = tableOfWorkspaces.selectedObject
return withoutNull(client, cliManager, selected?.agent, selected?.workspace) { client, cli, agent, workspace ->
val name ="${workspace.name}.${agent.name}"
val name =CoderCLIManager.getWorkspaceParts(workspace,agent)
logger.info("Returning data for $name")
CoderWorkspacesStepSelection(
agent = agent,
Expand DownExpand Up@@ -783,6 +784,7 @@
ListTableModel<WorkspaceAgentListModel>(
WorkspaceIconColumnInfo(""),
WorkspaceNameColumnInfo("Name"),
WorkspaceOwnerColumnInfo("Owner"),
WorkspaceTemplateNameColumnInfo("Template"),
WorkspaceVersionColumnInfo("Version"),
WorkspaceStatusColumnInfo("Status"),
Expand DownExpand Up@@ -849,6 +851,36 @@
}
}

private class WorkspaceOwnerColumnInfo(columnName: String) : ColumnInfo<WorkspaceAgentListModel, String>(columnName) {
override fun valueOf(item: WorkspaceAgentListModel?): String? = item?.workspace?.ownerName

override fun getComparator(): Comparator<WorkspaceAgentListModel> = Comparator { a, b ->
a.workspace.ownerName.compareTo(b.workspace.ownerName, ignoreCase = true)
}

override fun getRenderer(item: WorkspaceAgentListModel?): TableCellRenderer {
return object : DefaultTableCellRenderer() {
override fun getTableCellRendererComponent(
table: JTable,
value: Any,
isSelected: Boolean,
hasFocus: Boolean,
row: Int,
column: Int,
): Component {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column)
if (value is String) {
text = value
}

font = RelativeFont.BOLD.derive(table.tableHeader.font)
border = JBUI.Borders.empty(0, 8)
return this
}
}
}
}

private class WorkspaceTemplateNameColumnInfo(columnName: String) : ColumnInfo<WorkspaceAgentListModel, String>(columnName) {
override fun valueOf(item: WorkspaceAgentListModel?): String? = item?.workspace?.templateName

Expand DownExpand Up@@ -879,7 +911,7 @@
}

private class WorkspaceVersionColumnInfo(columnName: String) : ColumnInfo<WorkspaceAgentListModel, String>(columnName) {
override fun valueOf(workspace: WorkspaceAgentListModel?): String? = if (workspace == null) {

Check warning on line 914 in src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt

View workflow job for this annotation

GitHub Actions/ Qodana Community for JVM

Redundant nullable return type

'valueOf' always returns non-null type
"Unknown"
} else if (workspace.workspace.outdated) {
"Outdated"
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp