diff --git a/CHANGELOG.md b/CHANGELOG.md index 49ffb93f3..64846472e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/main/kotlin/com/coder/gateway/CoderSettingsConfigurable.kt b/src/main/kotlin/com/coder/gateway/CoderSettingsConfigurable.kt index 5fb9e428c..5b69f39eb 100644 --- a/src/main/kotlin/com/coder/gateway/CoderSettingsConfigurable.kt +++ b/src/main/kotlin/com/coder/gateway/CoderSettingsConfigurable.kt @@ -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) } } diff --git a/src/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt b/src/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt index adef3871f..f3d72e7a1 100644 --- a/src/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt +++ b/src/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt @@ -3,6 +3,9 @@ package com.coder.gateway.cli 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 @@ -219,11 +222,12 @@ class CoderCLIManager( * This can take supported features for testing purposes only. */ fun configSsh( - workspaceNames: Set, + workspacesAndAgents: Set>, + currentUser: User, feats: Features = features, ) { logger.info("Configuring SSH config at ${settings.sshConfigPath}") - writeSSHConfig(modifySSHConfig(readSSHConfig(), workspaceNames, feats)) + writeSSHConfig(modifySSHConfig(readSSHConfig(), workspacesAndAgents, feats, currentUser)) } /** @@ -245,8 +249,9 @@ class CoderCLIManager( */ private fun modifySSHConfig( contents: String?, - workspaceNames: Set, + workspaceNames: Set>, feats: Features, + currentUser: User, ): String? { val host = deploymentURL.safeHost() val startBlock = "# --- START CODER JETBRAINS $host" @@ -287,8 +292,8 @@ class CoderCLIManager( 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 @@ -299,8 +304,8 @@ class CoderCLIManager( .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 @@ -478,17 +483,43 @@ class CoderCLIManager( 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( diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderRestClient.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderRestClient.kt index 69806f078..66aa07881 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderRestClient.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/CoderRestClient.kt @@ -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 @@ -166,7 +159,7 @@ open class CoderRestClient( * @throws [APIResponseException]. */ fun workspaces(): List { - val workspacesResponse = retroRestClient.workspaces("owner:me").execute() + val workspacesResponse = retroRestClient.workspaces(settings.workspaceFilter).execute() if (!workspacesResponse.isSuccessful) { throw APIResponseException("retrieve workspaces", url, workspacesResponse) } @@ -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. */ - fun agentNames(workspaces: List): Set { + fun withAgents(workspaces: List): Set> { // 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() } diff --git a/src/main/kotlin/com/coder/gateway/sdk/v2/models/Workspace.kt b/src/main/kotlin/com/coder/gateway/sdk/v2/models/Workspace.kt index 84b641d45..ca6b10888 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/v2/models/Workspace.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/v2/models/Workspace.kt @@ -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, ) /** diff --git a/src/main/kotlin/com/coder/gateway/settings/CoderSettings.kt b/src/main/kotlin/com/coder/gateway/settings/CoderSettings.kt index f0f9cc62a..d3d9a647b 100644 --- a/src/main/kotlin/com/coder/gateway/settings/CoderSettings.kt +++ b/src/main/kotlin/com/coder/gateway/settings/CoderSettings.kt @@ -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" ) /** @@ -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. diff --git a/src/main/kotlin/com/coder/gateway/util/Dialogs.kt b/src/main/kotlin/com/coder/gateway/util/Dialogs.kt index 72c1e5305..0e360363e 100644 --- a/src/main/kotlin/com/coder/gateway/util/Dialogs.kt +++ b/src/main/kotlin/com/coder/gateway/util/Dialogs.kt @@ -32,14 +32,13 @@ import javax.swing.border.Border * 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)) } override fun show() { @@ -71,7 +70,6 @@ private class CoderWorkspaceStepDialog( } fun askIDE( - name: String, agent: WorkspaceAgent, workspace: Workspace, cli: CoderCLIManager, @@ -82,7 +80,6 @@ fun askIDE( ApplicationManager.getApplication().invokeAndWait { val dialog = CoderWorkspaceStepDialog( - name, CoderWorkspacesStepSelection(agent, workspace, cli, client, workspaces), ) data = dialog.showAndGetData() diff --git a/src/main/kotlin/com/coder/gateway/util/LinkHandler.kt b/src/main/kotlin/com/coder/gateway/util/LinkHandler.kt index 1a656391f..506d37778 100644 --- a/src/main/kotlin/com/coder/gateway/util/LinkHandler.kt +++ b/src/main/kotlin/com/coder/gateway/util/LinkHandler.kt @@ -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 = @@ -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(), diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspaceProjectIDEStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspaceProjectIDEStepView.kt index 629fe7a74..4aa05f960 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspaceProjectIDEStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspaceProjectIDEStepView.kt @@ -184,15 +184,14 @@ 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()) { @@ -200,7 +199,7 @@ class CoderWorkspaceProjectIDEStepView( 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 = @@ -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...") @@ -338,7 +337,7 @@ class CoderWorkspaceProjectIDEStepView( workspace: Workspace, agent: WorkspaceAgent, ): List { - 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) { @@ -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, ) diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt index 1ee62571e..17bab7ca7 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt @@ -33,6 +33,7 @@ import com.intellij.openapi.application.ModalityState 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 import com.intellij.openapi.rd.util.launchUnderBackgroundProgress import com.intellij.openapi.ui.panel.ComponentPanelBuilder import com.intellij.openapi.ui.setEmptyState @@ -89,7 +90,7 @@ private const val SESSION_TOKEN_KEY = "session-token" private data class CoderWorkspacesFormFields( var coderURL: String = "", var token: Pair? = null, - var useExistingToken: Boolean = false, + var useExistingToken: Boolean = false ) /** @@ -751,7 +752,7 @@ class CoderWorkspacesStepView : 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, @@ -783,6 +784,7 @@ class WorkspacesTableModel : ListTableModel( WorkspaceIconColumnInfo(""), WorkspaceNameColumnInfo("Name"), + WorkspaceOwnerColumnInfo("Owner"), WorkspaceTemplateNameColumnInfo("Template"), WorkspaceVersionColumnInfo("Version"), WorkspaceStatusColumnInfo("Status"), @@ -849,6 +851,36 @@ class WorkspacesTableModel : } } + private class WorkspaceOwnerColumnInfo(columnName: String) : ColumnInfo(columnName) { + override fun valueOf(item: WorkspaceAgentListModel?): String? = item?.workspace?.ownerName + + override fun getComparator(): Comparator = 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(columnName) { override fun valueOf(item: WorkspaceAgentListModel?): String? = item?.workspace?.templateName diff --git a/src/main/resources/messages/CoderGatewayBundle.properties b/src/main/resources/messages/CoderGatewayBundle.properties index 73b055c1b..19acf2bc7 100644 --- a/src/main/resources/messages/CoderGatewayBundle.properties +++ b/src/main/resources/messages/CoderGatewayBundle.properties @@ -50,12 +50,12 @@ gateway.connector.coder.connecting=Connecting... gateway.connector.coder.connecting.retry=Connecting (attempt {0})... gateway.connector.coder.connection.failed=Failed to connect gateway.connector.coder.connecting.failed.retry=Failed to connect...retrying {0} -gateway.connector.settings.data-directory.title=Data directory: +gateway.connector.settings.data-directory.title=Data directory gateway.connector.settings.data-directory.comment=Directories are created \ here that store the credentials for each domain to which the plugin \ connects. \ Defaults to {0}. -gateway.connector.settings.binary-source.title=CLI source: +gateway.connector.settings.binary-source.title=CLI source gateway.connector.settings.binary-source.comment=Used to download the Coder \ CLI which is necessary to make SSH connections. The If-None-Match header \ will be set to the SHA1 of the CLI and can be used for caching. Absolute \ @@ -66,7 +66,7 @@ gateway.connector.settings.enable-downloads.title=Enable CLI downloads gateway.connector.settings.enable-downloads.comment=Checking this box will \ allow the plugin to download the CLI if the current one is out of date or \ does not exist. -gateway.connector.settings.binary-destination.title=CLI directory: +gateway.connector.settings.binary-destination.title=CLI directory gateway.connector.settings.binary-destination.comment=Directories are created \ here that store the CLI for each domain to which the plugin connects. \ Defaults to the data directory. @@ -74,32 +74,32 @@ gateway.connector.settings.enable-binary-directory-fallback.title=Fall back to d gateway.connector.settings.enable-binary-directory-fallback.comment=Checking this \ box will allow the plugin to fall back to the data directory when the CLI \ directory is not writable. -gateway.connector.settings.header-command.title=Header command: +gateway.connector.settings.header-command.title=Header command gateway.connector.settings.header-command.comment=An external command that \ outputs additional HTTP headers added to all requests. The command must \ output each header as `key=value` on its own line. The following \ environment variables will be available to the process: CODER_URL. -gateway.connector.settings.tls-cert-path.title=Cert path: +gateway.connector.settings.tls-cert-path.title=Cert path gateway.connector.settings.tls-cert-path.comment=Optionally set this to \ the path of a certificate to use for TLS connections. The certificate \ should be in X.509 PEM format. If a certificate and key are set, token \ authentication will be disabled. -gateway.connector.settings.tls-key-path.title=Key path: +gateway.connector.settings.tls-key-path.title=Key path gateway.connector.settings.tls-key-path.comment=Optionally set this to \ the path of the private key that corresponds to the above cert path to use \ for TLS connections. The key should be in X.509 PEM format. If a certificate \ and key are set, token authentication will be disabled. -gateway.connector.settings.tls-ca-path.title=CA path: +gateway.connector.settings.tls-ca-path.title=CA path gateway.connector.settings.tls-ca-path.comment=Optionally set this to \ the path of a file containing certificates for an alternate certificate \ authority used to verify TLS certs returned by the Coder service. \ The file should be in X.509 PEM format. -gateway.connector.settings.tls-alt-name.title=Alt hostname: +gateway.connector.settings.tls-alt-name.title=Alt hostname gateway.connector.settings.tls-alt-name.comment=Optionally set this to \ an alternate hostname used for verifying TLS connections. This is useful \ when the hostname used to connect to the Coder service does not match the \ hostname in the TLS certificate. -gateway.connector.settings.disable-autostart.heading=Autostart: +gateway.connector.settings.disable-autostart.heading=Autostart gateway.connector.settings.disable-autostart.title=Disable autostart gateway.connector.settings.disable-autostart.comment=Checking this box will \ cause the plugin to configure the CLI with --disable-autostart. You must go \ @@ -110,7 +110,7 @@ gateway.connector.settings.ssh-config-options.comment=Extra SSH config options \ to use when connecting to a workspace. This text will be appended as-is to \ the SSH configuration block for each workspace. If left blank the \ environment variable {0} will be used, if set. -gateway.connector.settings.setup-command.title=Setup command: +gateway.connector.settings.setup-command.title=Setup command gateway.connector.settings.setup-command.comment=An external command that \ will be executed on the remote in the bin directory of the IDE before \ connecting to it. If the command exits with non-zero, the exit code, stdout, \ @@ -120,12 +120,15 @@ gateway.connector.settings.ignore-setup-failure.title=Ignore setup command failu gateway.connector.settings.ignore-setup-failure.comment=Checking this box will \ cause the plugin to ignore failures (any non-zero exit code) from the setup \ command and continue connecting. -gateway.connector.settings.default-url.title=Default URL: +gateway.connector.settings.default-url.title=Default URL gateway.connector.settings.default-url.comment=The default URL to set in the \ URL field in the connection window when there is no last used URL. If this \ is not set, it will try CODER_URL then the URL in the Coder CLI config \ directory. -gateway.connector.settings.ssh-log-directory.title=SSH log directory: +gateway.connector.settings.ssh-log-directory.title=SSH log directory gateway.connector.settings.ssh-log-directory.comment=If set, the Coder CLI will \ output extra SSH information into this directory, which can be helpful for \ debugging connectivity issues. +gateway.connector.settings.workspace-filter.title=Workspace filter +gateway.connector.settings.workspace-filter.comment=The filter to apply when fetching workspaces. Leave blank to fetch \ + all workspaces. diff --git a/src/test/fixtures/outputs/append-blank-newlines.conf b/src/test/fixtures/outputs/append-blank-newlines.conf index 93543e1f7..bb9086ed0 100644 --- a/src/test/fixtures/outputs/append-blank-newlines.conf +++ b/src/test/fixtures/outputs/append-blank-newlines.conf @@ -3,15 +3,15 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/append-blank.conf b/src/test/fixtures/outputs/append-blank.conf index efd48b6e3..d948949f7 100644 --- a/src/test/fixtures/outputs/append-blank.conf +++ b/src/test/fixtures/outputs/append-blank.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/append-no-blocks.conf b/src/test/fixtures/outputs/append-no-blocks.conf index 039e53592..002915c76 100644 --- a/src/test/fixtures/outputs/append-no-blocks.conf +++ b/src/test/fixtures/outputs/append-no-blocks.conf @@ -4,15 +4,15 @@ Host test2 Port 443 # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/append-no-newline.conf b/src/test/fixtures/outputs/append-no-newline.conf index 36c0fa7f0..03af2d617 100644 --- a/src/test/fixtures/outputs/append-no-newline.conf +++ b/src/test/fixtures/outputs/append-no-newline.conf @@ -3,15 +3,15 @@ Host test Host test2 Port 443 # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/append-no-related-blocks.conf b/src/test/fixtures/outputs/append-no-related-blocks.conf index 84ecee978..753055bf4 100644 --- a/src/test/fixtures/outputs/append-no-related-blocks.conf +++ b/src/test/fixtures/outputs/append-no-related-blocks.conf @@ -10,15 +10,15 @@ some jetbrains config # --- END CODER JETBRAINS test.coder.unrelated # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/disable-autostart.conf b/src/test/fixtures/outputs/disable-autostart.conf index b7e095f6e..2c61be580 100644 --- a/src/test/fixtures/outputs/disable-autostart.conf +++ b/src/test/fixtures/outputs/disable-autostart.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --disable-autostart --usage-app=jetbrains foo +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --disable-autostart --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --disable-autostart --usage-app=disable foo +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --disable-autostart --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/extra-config.conf b/src/test/fixtures/outputs/extra-config.conf index 03ff48a61..dd3d5a091 100644 --- a/src/test/fixtures/outputs/extra-config.conf +++ b/src/test/fixtures/outputs/extra-config.conf @@ -1,6 +1,6 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--extra--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains extra +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null @@ -8,8 +8,8 @@ Host coder-jetbrains--extra--test.coder.invalid SetEnv CODER_SSH_SESSION_TYPE=JetBrains ServerAliveInterval 5 ServerAliveCountMax 3 -Host coder-jetbrains--extra--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable extra +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/header-command-windows.conf b/src/test/fixtures/outputs/header-command-windows.conf index 47a179087..f2d605992 100644 --- a/src/test/fixtures/outputs/header-command-windows.conf +++ b/src/test/fixtures/outputs/header-command-windows.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--header--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid --header-command "\"C:\Program Files\My Header Command\HeaderCommand.exe\" --url=\"%%CODER_URL%%\" --test=\"foo bar\"" ssh --stdio --usage-app=jetbrains header +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid --header-command "\"C:\Program Files\My Header Command\HeaderCommand.exe\" --url=\"%%CODER_URL%%\" --test=\"foo bar\"" ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--header--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid --header-command "\"C:\Program Files\My Header Command\HeaderCommand.exe\" --url=\"%%CODER_URL%%\" --test=\"foo bar\"" ssh --stdio --usage-app=disable header +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid --header-command "\"C:\Program Files\My Header Command\HeaderCommand.exe\" --url=\"%%CODER_URL%%\" --test=\"foo bar\"" ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/header-command.conf b/src/test/fixtures/outputs/header-command.conf index fb85cc699..0b1c41b9a 100644 --- a/src/test/fixtures/outputs/header-command.conf +++ b/src/test/fixtures/outputs/header-command.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--header--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid --header-command 'my-header-command --url="$CODER_URL" --test="foo bar" --literal='\''$CODER_URL'\''' ssh --stdio --usage-app=jetbrains header +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid --header-command 'my-header-command --url="$CODER_URL" --test="foo bar" --literal='\''$CODER_URL'\''' ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--header--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid --header-command 'my-header-command --url="$CODER_URL" --test="foo bar" --literal='\''$CODER_URL'\''' ssh --stdio --usage-app=disable header +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid --header-command 'my-header-command --url="$CODER_URL" --test="foo bar" --literal='\''$CODER_URL'\''' ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/log-dir.conf b/src/test/fixtures/outputs/log-dir.conf index 669b7b228..98b3892f0 100644 --- a/src/test/fixtures/outputs/log-dir.conf +++ b/src/test/fixtures/outputs/log-dir.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --log-dir /tmp/coder-gateway/test.coder.invalid/logs --usage-app=jetbrains foo +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --log-dir /tmp/coder-gateway/test.coder.invalid/logs --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/multiple-agents.conf b/src/test/fixtures/outputs/multiple-agents.conf new file mode 100644 index 000000000..bc31a26c0 --- /dev/null +++ b/src/test/fixtures/outputs/multiple-agents.conf @@ -0,0 +1,30 @@ +# --- START CODER JETBRAINS test.coder.invalid +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 + ConnectTimeout 0 + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + LogLevel ERROR + SetEnv CODER_SSH_SESSION_TYPE=JetBrains +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 + ConnectTimeout 0 + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + LogLevel ERROR + SetEnv CODER_SSH_SESSION_TYPE=JetBrains +Host coder-jetbrains--foo.agent2--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent2 + ConnectTimeout 0 + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + LogLevel ERROR + SetEnv CODER_SSH_SESSION_TYPE=JetBrains +Host coder-jetbrains--foo.agent2--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent2 + ConnectTimeout 0 + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + LogLevel ERROR + SetEnv CODER_SSH_SESSION_TYPE=JetBrains +# --- END CODER JETBRAINS test.coder.invalid diff --git a/src/test/fixtures/outputs/multiple-users.conf b/src/test/fixtures/outputs/multiple-users.conf new file mode 100644 index 000000000..c221ba10a --- /dev/null +++ b/src/test/fixtures/outputs/multiple-users.conf @@ -0,0 +1,30 @@ +# --- START CODER JETBRAINS test.coder.invalid +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 + ConnectTimeout 0 + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + LogLevel ERROR + SetEnv CODER_SSH_SESSION_TYPE=JetBrains +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 + ConnectTimeout 0 + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + LogLevel ERROR + SetEnv CODER_SSH_SESSION_TYPE=JetBrains +Host coder-jetbrains--bettertester--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains bettertester/foo.agent1 + ConnectTimeout 0 + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + LogLevel ERROR + SetEnv CODER_SSH_SESSION_TYPE=JetBrains +Host coder-jetbrains--bettertester--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable bettertester/foo.agent1 + ConnectTimeout 0 + StrictHostKeyChecking no + UserKnownHostsFile /dev/null + LogLevel ERROR + SetEnv CODER_SSH_SESSION_TYPE=JetBrains +# --- END CODER JETBRAINS test.coder.invalid diff --git a/src/test/fixtures/outputs/multiple-workspaces.conf b/src/test/fixtures/outputs/multiple-workspaces.conf index 40962c0a4..b623c03b3 100644 --- a/src/test/fixtures/outputs/multiple-workspaces.conf +++ b/src/test/fixtures/outputs/multiple-workspaces.conf @@ -1,27 +1,27 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains bar +Host coder-jetbrains--bar.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/bar.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable bar +Host coder-jetbrains--bar.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/bar.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/no-disable-autostart.conf b/src/test/fixtures/outputs/no-disable-autostart.conf index ddcfc0e47..d948949f7 100644 --- a/src/test/fixtures/outputs/no-disable-autostart.conf +++ b/src/test/fixtures/outputs/no-disable-autostart.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/no-report-usage.conf b/src/test/fixtures/outputs/no-report-usage.conf index 7e48a61b2..ba368ee5b 100644 --- a/src/test/fixtures/outputs/no-report-usage.conf +++ b/src/test/fixtures/outputs/no-report-usage.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio foo +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio foo +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/replace-end-no-newline.conf b/src/test/fixtures/outputs/replace-end-no-newline.conf index 32bb8d31d..fdda5d596 100644 --- a/src/test/fixtures/outputs/replace-end-no-newline.conf +++ b/src/test/fixtures/outputs/replace-end-no-newline.conf @@ -2,15 +2,15 @@ Host test Port 80 Host test2 Port 443 # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/replace-end.conf b/src/test/fixtures/outputs/replace-end.conf index 36c0fa7f0..03af2d617 100644 --- a/src/test/fixtures/outputs/replace-end.conf +++ b/src/test/fixtures/outputs/replace-end.conf @@ -3,15 +3,15 @@ Host test Host test2 Port 443 # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/replace-middle-ignore-unrelated.conf b/src/test/fixtures/outputs/replace-middle-ignore-unrelated.conf index 19b707523..9827deffc 100644 --- a/src/test/fixtures/outputs/replace-middle-ignore-unrelated.conf +++ b/src/test/fixtures/outputs/replace-middle-ignore-unrelated.conf @@ -4,15 +4,15 @@ Host test some coder config # ------------END-CODER------------ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/replace-middle.conf b/src/test/fixtures/outputs/replace-middle.conf index 841f05af4..5dac9023e 100644 --- a/src/test/fixtures/outputs/replace-middle.conf +++ b/src/test/fixtures/outputs/replace-middle.conf @@ -1,15 +1,15 @@ Host test Port 80 # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/replace-only.conf b/src/test/fixtures/outputs/replace-only.conf index efd48b6e3..d948949f7 100644 --- a/src/test/fixtures/outputs/replace-only.conf +++ b/src/test/fixtures/outputs/replace-only.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/replace-start.conf b/src/test/fixtures/outputs/replace-start.conf index b5fcc920b..1ed938295 100644 --- a/src/test/fixtures/outputs/replace-start.conf +++ b/src/test/fixtures/outputs/replace-start.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--foo-bar--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--foo-bar--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable foo-bar +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/fixtures/outputs/url.conf b/src/test/fixtures/outputs/url.conf index 8854325c7..cf59d4e4d 100644 --- a/src/test/fixtures/outputs/url.conf +++ b/src/test/fixtures/outputs/url.conf @@ -1,13 +1,13 @@ # --- START CODER JETBRAINS test.coder.invalid -Host coder-jetbrains--url--test.coder.invalid - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url "https://test.coder.invalid?foo=bar&baz=qux" ssh --stdio --usage-app=jetbrains url +Host coder-jetbrains--foo.agent1--test.coder.invalid + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url "https://test.coder.invalid?foo=bar&baz=qux" ssh --stdio --usage-app=jetbrains tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains--url--test.coder.invalid--bg - ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url "https://test.coder.invalid?foo=bar&baz=qux" ssh --stdio --usage-app=disable url +Host coder-jetbrains--foo.agent1--test.coder.invalid--bg + ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url "https://test.coder.invalid?foo=bar&baz=qux" ssh --stdio --usage-app=disable tester/foo.agent1 ConnectTimeout 0 StrictHostKeyChecking no UserKnownHostsFile /dev/null diff --git a/src/test/kotlin/com/coder/gateway/cli/CoderCLIManagerTest.kt b/src/test/kotlin/com/coder/gateway/cli/CoderCLIManagerTest.kt index 1baafe540..d9e2cc6c6 100644 --- a/src/test/kotlin/com/coder/gateway/cli/CoderCLIManagerTest.kt +++ b/src/test/kotlin/com/coder/gateway/cli/CoderCLIManagerTest.kt @@ -3,6 +3,10 @@ package com.coder.gateway.cli 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.DataGen +import com.coder.gateway.sdk.DataGen.Companion.workspace +import com.coder.gateway.sdk.v2.models.Workspace +import com.coder.gateway.sdk.v2.models.WorkspaceAgent import com.coder.gateway.settings.CODER_SSH_CONFIG_OPTIONS import com.coder.gateway.settings.CoderSettings import com.coder.gateway.settings.CoderSettingsState @@ -25,6 +29,7 @@ import java.net.InetSocketAddress import java.net.URL import java.nio.file.AccessDeniedException import java.nio.file.Path +import java.util.* import kotlin.test.Test import kotlin.test.assertContains import kotlin.test.assertEquals @@ -289,7 +294,7 @@ internal class CoderCLIManagerTest { } data class SSHTest( - val workspaces: List, + val workspaces: List, val input: String?, val output: String, val remove: String, @@ -308,6 +313,14 @@ internal class CoderCLIManagerTest { @Test fun testConfigureSSH() { + + val workspace = workspace("foo", agents = mapOf("agent1" to UUID.randomUUID().toString())) + val workspace2 = workspace("bar", agents = mapOf("agent1" to UUID.randomUUID().toString())) + val betterWorkspace = workspace("foo", agents = mapOf("agent1" to UUID.randomUUID().toString()), ownerName = "bettertester") + val workspaceWithMultipleAgents = workspace("foo", agents = mapOf("agent1" to UUID.randomUUID().toString(), "agent2" to UUID.randomUUID().toString())) + + + val extraConfig = listOf( "ServerAliveInterval 5", @@ -315,22 +328,22 @@ internal class CoderCLIManagerTest { ).joinToString(System.lineSeparator()) val tests = listOf( - SSHTest(listOf("foo", "bar"), null, "multiple-workspaces", "blank"), - SSHTest(listOf("foo", "bar"), null, "multiple-workspaces", "blank"), - SSHTest(listOf("foo-bar"), "blank", "append-blank", "blank"), - SSHTest(listOf("foo-bar"), "blank-newlines", "append-blank-newlines", "blank"), - SSHTest(listOf("foo-bar"), "existing-end", "replace-end", "no-blocks"), - SSHTest(listOf("foo-bar"), "existing-end-no-newline", "replace-end-no-newline", "no-blocks"), - SSHTest(listOf("foo-bar"), "existing-middle", "replace-middle", "no-blocks"), - SSHTest(listOf("foo-bar"), "existing-middle-and-unrelated", "replace-middle-ignore-unrelated", "no-related-blocks"), - SSHTest(listOf("foo-bar"), "existing-only", "replace-only", "blank"), - SSHTest(listOf("foo-bar"), "existing-start", "replace-start", "no-blocks"), - SSHTest(listOf("foo-bar"), "no-blocks", "append-no-blocks", "no-blocks"), - SSHTest(listOf("foo-bar"), "no-related-blocks", "append-no-related-blocks", "no-related-blocks"), - SSHTest(listOf("foo-bar"), "no-newline", "append-no-newline", "no-blocks"), + SSHTest(listOf(workspace, workspace2), null, "multiple-workspaces", "blank"), + SSHTest(listOf(workspace, workspace2), null, "multiple-workspaces", "blank"), + SSHTest(listOf(workspace), "blank", "append-blank", "blank"), + SSHTest(listOf(workspace), "blank-newlines", "append-blank-newlines", "blank"), + SSHTest(listOf(workspace), "existing-end", "replace-end", "no-blocks"), + SSHTest(listOf(workspace), "existing-end-no-newline", "replace-end-no-newline", "no-blocks"), + SSHTest(listOf(workspace), "existing-middle", "replace-middle", "no-blocks"), + SSHTest(listOf(workspace), "existing-middle-and-unrelated", "replace-middle-ignore-unrelated", "no-related-blocks"), + SSHTest(listOf(workspace), "existing-only", "replace-only", "blank"), + SSHTest(listOf(workspace), "existing-start", "replace-start", "no-blocks"), + SSHTest(listOf(workspace), "no-blocks", "append-no-blocks", "no-blocks"), + SSHTest(listOf(workspace), "no-related-blocks", "append-no-related-blocks", "no-related-blocks"), + SSHTest(listOf(workspace), "no-newline", "append-no-newline", "no-blocks"), if (getOS() == OS.WINDOWS) { SSHTest( - listOf("header"), + listOf(workspace), null, "header-command-windows", "blank", @@ -338,7 +351,7 @@ internal class CoderCLIManagerTest { ) } else { SSHTest( - listOf("header"), + listOf(workspace), null, "header-command", "blank", @@ -346,7 +359,7 @@ internal class CoderCLIManagerTest { ) }, SSHTest( - listOf("foo"), + listOf(workspace), null, "disable-autostart", "blank", @@ -357,9 +370,9 @@ internal class CoderCLIManagerTest { reportWorkspaceUsage = true, ), ), - SSHTest(listOf("foo"), null, "no-disable-autostart", "blank", ""), + SSHTest(listOf(workspace), null, "no-disable-autostart", "blank", ""), SSHTest( - listOf("foo"), + listOf(workspace), null, "no-report-usage", "blank", @@ -371,33 +384,45 @@ internal class CoderCLIManagerTest { ), ), SSHTest( - listOf("extra"), + listOf(workspace), null, "extra-config", "blank", extraConfig = extraConfig, ), SSHTest( - listOf("extra"), + listOf(workspace), null, "extra-config", "blank", env = Environment(mapOf(CODER_SSH_CONFIG_OPTIONS to extraConfig)), ), SSHTest( - listOf("foo"), + listOf(workspace), null, "log-dir", "blank", sshLogDirectory = tmpdir.resolve("ssh-logs"), ), SSHTest( - listOf("url"), + listOf(workspace), input = null, output = "url", remove = "blank", url = URL("https://test.coder.invalid?foo=bar&baz=qux"), ), + SSHTest( + listOf(workspace, betterWorkspace), + input = null, + output = "multiple-users", + remove = "blank", + ), + SSHTest( + listOf(workspaceWithMultipleAgents), + input = null, + output = "multiple-agents", + remove = "blank", + ) ) val newlineRe = "\r?\n".toRegex() @@ -443,7 +468,9 @@ internal class CoderCLIManagerTest { } // Add workspaces. - ccm.configSsh(it.workspaces.toSet(), it.features) + ccm.configSsh(it.workspaces.flatMap { ws -> ws.latestBuild.resources.filter { r -> r.agents != null }.flatMap { r -> r.agents!! }.map { a -> + ws to a + } }.toSet(), DataGen.user(), it.features) assertEquals(expectedConf, settings.sshConfigPath.toFile().readText()) @@ -453,7 +480,7 @@ internal class CoderCLIManagerTest { } // Remove configuration. - ccm.configSsh(emptySet(), it.features) + ccm.configSsh(emptySet(), DataGen.user(), it.features) // Remove is the configuration we expect after removing. assertEquals( @@ -490,7 +517,7 @@ internal class CoderCLIManagerTest { assertFailsWith( exceptionClass = SSHConfigFormatException::class, - block = { ccm.configSsh(emptySet()) }, + block = { ccm.configSsh(emptySet(), DataGen.user()) }, ) } } @@ -502,6 +529,11 @@ internal class CoderCLIManagerTest { "new\nline", ) + val workspace = workspace("foo", agents = mapOf("agentid1" to UUID.randomUUID().toString(), "agentid2" to UUID.randomUUID().toString())) + val withAgents = workspace.latestBuild.resources.filter { it.agents != null }.flatMap { it.agents!! }.map { + workspace to it + } + tests.forEach { val ccm = CoderCLIManager( @@ -515,7 +547,7 @@ internal class CoderCLIManagerTest { assertFailsWith( exceptionClass = Exception::class, - block = { ccm.configSsh(setOf("foo", "bar")) }, + block = { ccm.configSsh(withAgents.toSet(), DataGen.user()) }, ) } } diff --git a/src/test/kotlin/com/coder/gateway/sdk/DataGen.kt b/src/test/kotlin/com/coder/gateway/sdk/DataGen.kt index c2c7fb3d4..b6ce8229c 100644 --- a/src/test/kotlin/com/coder/gateway/sdk/DataGen.kt +++ b/src/test/kotlin/com/coder/gateway/sdk/DataGen.kt @@ -50,6 +50,7 @@ class DataGen { name: String, templateID: UUID = UUID.randomUUID(), agents: Map = emptyMap(), + ownerName: String = "tester", ): Workspace { val wsId = UUID.randomUUID() return Workspace( @@ -64,6 +65,7 @@ class DataGen { ), outdated = false, name = name, + ownerName = ownerName ) }