Skip to content

Commit 4d6ce7b

Browse files
committed
Connection setup
- download and execute coder cli login&config-ssh - execute the connector
1 parent 3031a85 commit 4d6ce7b

File tree

5 files changed

+65
-17
lines changed

5 files changed

+65
-17
lines changed

src/main/kotlin/com/coder/gateway/CoderGatewayConnectionProvider.kt

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,45 @@
11
package com.coder.gateway
22

33
import com.coder.gateway.views.CoderGatewayConnectionComponent
4+
import com.intellij.remote.RemoteCredentialsHolder
45
import com.jetbrains.gateway.api.ConnectionRequestor
56
import com.jetbrains.gateway.api.GatewayConnectionHandle
67
import com.jetbrains.gateway.api.GatewayConnectionProvider
8+
import com.jetbrains.gateway.ssh.ClientOverSshTunnelConnector
79
import com.jetbrains.rd.util.lifetime.LifetimeDefinition
10+
import java.net.URI
11+
import java.net.URL
812
import java.util.logging.Logger
913
import javax.swing.JComponent
1014

1115
class CoderGatewayConnectionProvider : GatewayConnectionProvider {
1216
private val connections = mutableSetOf<CoderConnectionMetadata>()
1317
override suspend fun connect(parameters: Map<String, String>, requestor: ConnectionRequestor): GatewayConnectionHandle? {
1418
val coderUrl = parameters["coder_url"]
15-
val workspaceId = parameters["workspace_id"]
19+
val workspaceName = parameters["workspace_name"]
20+
val user = parameters["username"]
21+
val privateSSHKey = parameters["private_ssh_key"]
22+
val projectPath = parameters["project_path"]
1623

17-
if (coderUrl != null && workspaceId != null) {
18-
val connection = CoderConnectionMetadata(coderUrl, workspaceId)
24+
if (coderUrl != null && workspaceName != null) {
25+
val connection = CoderConnectionMetadata(coderUrl, workspaceName)
1926
if (connection in connections) {
2027
logger.warning("There is already a connection started on ${connection.url} using the workspace ${connection.workspaceId}")
2128
return null
2229
}
30+
val url = URL(coderUrl)
2331
val clientLifetime = LifetimeDefinition()
32+
val credentials = RemoteCredentialsHolder()
33+
credentials.apply {
34+
setHost("coder.${workspaceName}")
35+
userName = user
36+
setPrivateKeyFile(privateSSHKey)
37+
}
38+
var tcpJoinLink = "jetbrains-gateway://connect#projectPath=${projectPath}&host=${url.host}&port=22&user=${user}&type=ssh&deploy=true&buildNumber=221.5591.52&productCode=IU"
39+
ClientOverSshTunnelConnector(clientLifetime, credentials, URI(tcpJoinLink)).connect()
2440
return object : GatewayConnectionHandle(clientLifetime) {
2541
override fun createComponent(): JComponent {
26-
return CoderGatewayConnectionComponent(clientLifetime, coderUrl, workspaceId)
42+
return CoderGatewayConnectionComponent(clientLifetime, coderUrl, workspaceName)
2743
}
2844

2945
override fun getTitle(): String {

src/main/kotlin/com/coder/gateway/views/CoderGatewayConnectorWizardView.kt

+1-4
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ class CoderGatewayConnectorWizardView : BorderLayoutPanel(), Disposable {
5555
}
5656

5757
private fun previous() {
58-
nextButton.isVisible = true
5958
if (currentStep == 0) {
6059
GatewayUI.Companion.getInstance().reset()
6160
} else {
@@ -74,8 +73,8 @@ class CoderGatewayConnectorWizardView : BorderLayoutPanel(), Disposable {
7473

7574
private fun next() {
7675
cs.launch {
76+
withContext(Dispatchers.Main) { doNextCallback() }
7777
if (currentStep + 1 < steps.size) {
78-
withContext(Dispatchers.Main) { doNextCallback() }
7978
remove(steps[currentStep].component)
8079
updateUI()
8180
currentStep++
@@ -87,8 +86,6 @@ class CoderGatewayConnectorWizardView : BorderLayoutPanel(), Disposable {
8786
nextButton.text = nextActionText
8887
previousButton.text = previousActionText
8988
}
90-
91-
nextButton.isVisible = currentStep != steps.size - 1
9289
}
9390
}
9491
}

src/main/kotlin/com/coder/gateway/views/steps/CoderAuthStepView.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class CoderAuthStepView : CoderWorkspacesWizardStep, Disposable {
8686
CoderGatewayBundle.message("gateway.connector.view.login.credentials.dialog.title"),
8787
CoderGatewayBundle.message("gateway.connector.view.login.password.label"),
8888
CredentialAttributes("Coder"),
89-
true
89+
false
9090
)
9191

9292
model.password = password
@@ -96,7 +96,6 @@ class CoderAuthStepView : CoderWorkspacesWizardStep, Disposable {
9696
wizardModel.apply {
9797
loginModel = model.copy()
9898
}
99-
10099
}
101100

102101

src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt

+40-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.coder.gateway.views.steps
22

33
import com.coder.gateway.CoderGatewayBundle
44
import com.coder.gateway.models.CoderWorkspacesWizardModel
5+
import com.coder.gateway.sdk.CoderCLIManager
56
import com.coder.gateway.sdk.CoderRestClientService
67
import com.coder.gateway.sdk.v2.models.Workspace
78
import com.intellij.ide.IdeBundle
@@ -11,23 +12,31 @@ import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeScreenUIManager
1112
import com.intellij.ui.CollectionListModel
1213
import com.intellij.ui.IconManager
1314
import com.intellij.ui.components.JBList
15+
import com.intellij.ui.components.JBTextField
1416
import com.intellij.ui.dsl.builder.BottomGap
1517
import com.intellij.ui.dsl.builder.RightGap
1618
import com.intellij.ui.dsl.builder.TopGap
1719
import com.intellij.ui.dsl.builder.panel
1820
import com.intellij.ui.dsl.gridLayout.HorizontalAlign
1921
import com.intellij.ui.dsl.gridLayout.VerticalAlign
2022
import com.intellij.util.ui.JBFont
23+
import com.jetbrains.gateway.api.GatewayUI
2124
import kotlinx.coroutines.CoroutineScope
2225
import kotlinx.coroutines.Dispatchers
2326
import kotlinx.coroutines.launch
2427
import kotlinx.coroutines.withContext
28+
import org.zeroturnaround.exec.ProcessExecutor
29+
import java.net.URL
2530
import javax.swing.DefaultComboBoxModel
2631

2732
class CoderWorkspacesStepView : CoderWorkspacesWizardStep, Disposable {
2833
private val cs = CoroutineScope(Dispatchers.Main)
2934
private var workspaces = CollectionListModel<Workspace>()
3035
private var workspacesView = JBList(workspaces)
36+
37+
private lateinit var tfProject: JBTextField
38+
private lateinit var wizardModel: CoderWorkspacesWizardModel
39+
3140
private val coderClient: CoderRestClientService = ApplicationManager.getApplication().getService(CoderRestClientService::class.java)
3241

3342
override val component = panel {
@@ -44,12 +53,12 @@ class CoderWorkspacesStepView : CoderWorkspacesWizardStep, Disposable {
4453
comboBox(model)
4554
.gap(RightGap.SMALL)
4655
label("Project directory:")
47-
textField()
56+
tfProject = textField()
4857
.resizableColumn()
4958
.horizontalAlign(HorizontalAlign.FILL)
5059
.applyToComponent {
5160
this.text = "/home/ifaur/workspace/"
52-
}
61+
}.component
5362
cell()
5463
}.topGap(TopGap.NONE)
5564

@@ -62,9 +71,10 @@ class CoderWorkspacesStepView : CoderWorkspacesWizardStep, Disposable {
6271
}.apply { background = WelcomeScreenUIManager.getMainAssociatedComponentBackground() }
6372

6473
override val previousActionText = IdeBundle.message("button.back")
65-
override val nextActionText = CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.next.text")
74+
override val nextActionText = "Connect"
6675

67-
override fun onInit(wizardModel: CoderWorkspacesWizardModel) {
76+
override fun onInit(wm: CoderWorkspacesWizardModel) {
77+
wizardModel = wm
6878
workspaces.removeAll()
6979
workspacesView.cellRenderer = WorkspaceCellRenderer()
7080

@@ -79,6 +89,32 @@ class CoderWorkspacesStepView : CoderWorkspacesWizardStep, Disposable {
7989
}
8090

8191
override suspend fun onNext(wizardModel: CoderWorkspacesWizardModel) {
92+
val workspace = workspacesView.selectedValue
93+
println(">>> ${workspace.name} was selected")
94+
cs.launch {
95+
val privateSSHKey = withContext(Dispatchers.IO) {
96+
val url = URL(wizardModel.loginModel.uriScheme.toString().toLowerCase(), wizardModel.loginModel.host, wizardModel.loginModel.port, "")
97+
val cliManager = CoderCLIManager(URL(url.protocol, url.host, url.port, ""))
98+
val cli = cliManager.download() ?: throw IllegalStateException("Could not download coder binary")
99+
val loginOutput = ProcessExecutor().command(cli.toAbsolutePath().toString(), "login", url.toString(), "--token", coderClient.sessionToken).readOutput(true).execute().outputUTF8()
100+
println(">>> coder-cli login output: $loginOutput")
101+
val sshConfigOutput = ProcessExecutor().command(cli.toAbsolutePath().toString(), "config-ssh").readOutput(true).execute().outputUTF8()
102+
println(">>> coder-cli config-ssh output: $sshConfigOutput")
103+
104+
coderClient.userSSHKeys().privateKey
105+
}
106+
107+
GatewayUI.getInstance().connect(
108+
mapOf(
109+
"type" to "coder",
110+
"coder_url" to URL(wizardModel.loginModel.uriScheme.toString().toLowerCase(), wizardModel.loginModel.host, wizardModel.loginModel.port.toString()).toString(),
111+
"workspace_name" to workspace.name,
112+
"username" to coderClient.me.username,
113+
"private_ssh_key" to privateSSHKey,
114+
"project_path" to tfProject.text
115+
)
116+
)
117+
}
82118

83119
}
84120

src/main/kotlin/com/coder/gateway/views/steps/WorkspaceCellRenderer.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package com.coder.gateway.views.steps
33
import com.coder.gateway.sdk.v2.models.ProvisionerJobStatus
44
import com.coder.gateway.sdk.v2.models.Workspace
55
import com.coder.gateway.sdk.v2.models.WorkspaceBuildTransition
6+
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeScreenUIManager
67
import com.intellij.ui.IconManager
78
import com.intellij.ui.dsl.builder.panel
8-
import com.intellij.ui.dsl.gridLayout.HorizontalAlign
99
import com.intellij.util.ui.JBFont
1010
import java.awt.Component
1111
import javax.swing.JList
@@ -27,10 +27,10 @@ class WorkspaceCellRenderer : ListCellRenderer<Workspace> {
2727
label(labelForStatus(workspace))
2828
}
2929
}
30-
31-
button("Open", {}).horizontalAlign(HorizontalAlign.RIGHT)
3230
}
3331
}
32+
}.apply {
33+
background = WelcomeScreenUIManager.getProjectsSelectionBackground(true)
3434
}
3535
}
3636

0 commit comments

Comments
 (0)