@@ -4,8 +4,25 @@ package com.coder.gateway
4
4
5
5
import com.coder.gateway.cli.CoderCLIManager
6
6
import com.coder.gateway.cli.ensureCLI
7
+ import com.coder.gateway.models.AGENT_ID
8
+ import com.coder.gateway.models.AGENT_NAME
9
+ import com.coder.gateway.models.TOKEN
7
10
import com.coder.gateway.models.TokenSource
11
+ import com.coder.gateway.models.URL
12
+ import com.coder.gateway.models.WORKSPACE
8
13
import com.coder.gateway.models.WorkspaceAndAgentStatus
14
+ import com.coder.gateway.models.WorkspaceProjectIDE
15
+ import com.coder.gateway.models.agentID
16
+ import com.coder.gateway.models.agentName
17
+ import com.coder.gateway.models.folder
18
+ import com.coder.gateway.models.ideBuildNumber
19
+ import com.coder.gateway.models.ideDownloadLink
20
+ import com.coder.gateway.models.idePathOnHost
21
+ import com.coder.gateway.models.ideProductCode
22
+ import com.coder.gateway.models.isCoder
23
+ import com.coder.gateway.models.token
24
+ import com.coder.gateway.models.url
25
+ import com.coder.gateway.models.workspace
9
26
import com.coder.gateway.sdk.CoderRestClient
10
27
import com.coder.gateway.sdk.ex.AuthenticationResponseException
11
28
import com.coder.gateway.sdk.v2.models.Workspace
@@ -15,7 +32,7 @@ import com.coder.gateway.services.CoderRestClientService
15
32
import com.coder.gateway.services.CoderSettingsService
16
33
import com.coder.gateway.util.toURL
17
34
import com.coder.gateway.util.withPath
18
- import com.coder.gateway.views.steps.CoderWorkspaceStepView
35
+ import com.coder.gateway.views.steps.CoderWorkspaceIDEStepView
19
36
import com.coder.gateway.views.steps.CoderWorkspacesStepSelection
20
37
import com.intellij.openapi.application.ApplicationManager
21
38
import com.intellij.openapi.components.service
@@ -26,31 +43,17 @@ import com.intellij.util.ui.JBUI
26
43
import com.jetbrains.gateway.api.ConnectionRequestor
27
44
import com.jetbrains.gateway.api.GatewayConnectionHandle
28
45
import com.jetbrains.gateway.api.GatewayConnectionProvider
29
- import java.net.URL
30
46
import javax.swing.JComponent
31
47
import javax.swing.border.Border
32
48
33
- // In addition to `type`, these are the keys that we support in our Gateway
34
- // links.
35
- private const val URL = " url"
36
- private const val TOKEN = " token"
37
- private const val WORKSPACE = " workspace"
38
- private const val AGENT_NAME = " agent"
39
- private const val AGENT_ID = " agent_id"
40
- private const val FOLDER = " folder"
41
- private const val IDE_DOWNLOAD_LINK = " ide_download_link"
42
- private const val IDE_PRODUCT_CODE = " ide_product_code"
43
- private const val IDE_BUILD_NUMBER = " ide_build_number"
44
- private const val IDE_PATH_ON_HOST = " ide_path_on_host"
45
-
46
49
/* *
47
50
* A dialog wrapper around CoderWorkspaceStepView.
48
51
*/
49
52
class CoderWorkspaceStepDialog (
50
53
name : String ,
51
54
private val state : CoderWorkspacesStepSelection ,
52
55
) : DialogWrapper(true ) {
53
- private val view = CoderWorkspaceStepView (showTitle = false )
56
+ private val view = CoderWorkspaceIDEStepView (showTitle = false )
54
57
55
58
init {
56
59
init ()
@@ -65,7 +68,7 @@ class CoderWorkspaceStepDialog(
65
68
view.dispose()
66
69
}
67
70
68
- fun showAndGetData (): Map < String , String > ? {
71
+ fun showAndGetData (): WorkspaceProjectIDE ? {
69
72
if (showAndGet()) {
70
73
return view.data()
71
74
}
@@ -98,16 +101,16 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
98
101
CoderRemoteConnectionHandle ().connect{ indicator ->
99
102
logger.debug(" Launched Coder connection provider" , parameters)
100
103
101
- val deploymentURL = parameters[ URL ]
104
+ val deploymentURL = parameters.url()
102
105
? : CoderRemoteConnectionHandle .ask(" Enter the full URL of your Coder deployment" )
103
106
if (deploymentURL.isNullOrBlank()) {
104
107
throw IllegalArgumentException (" Query parameter \" $URL \" is missing" )
105
108
}
106
109
107
- val (client, username) = authenticate(deploymentURL.toURL() , parameters[ TOKEN ] )
110
+ val (client, username) = authenticate(deploymentURL, parameters.token() )
108
111
109
112
// TODO: If the workspace is missing we could launch the wizard.
110
- val workspaceName = parameters[ WORKSPACE ] ? : throw IllegalArgumentException (" Query parameter \" $WORKSPACE \" is missing" )
113
+ val workspaceName = parameters.workspace() ? : throw IllegalArgumentException (" Query parameter \" $WORKSPACE \" is missing" )
111
114
112
115
val workspaces = client.workspaces()
113
116
val workspace = workspaces.firstOrNull{ it.name == workspaceName } ? : throw IllegalArgumentException (" The workspace $workspaceName does not exist" )
@@ -150,13 +153,13 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
150
153
cli.configSsh(client.agentNames(workspaces))
151
154
152
155
val name = " ${workspace.name} .${agent.name} "
153
- val openDialog = parameters[ IDE_PRODUCT_CODE ] .isNullOrBlank() ||
154
- parameters[ IDE_BUILD_NUMBER ] .isNullOrBlank() ||
155
- (parameters[ IDE_PATH_ON_HOST ]. isNullOrBlank() && parameters[ IDE_DOWNLOAD_LINK ] .isNullOrBlank()) ||
156
- parameters[ FOLDER ] .isNullOrBlank()
156
+ val openDialog = parameters.ideProductCode() .isNullOrBlank() ||
157
+ parameters.ideBuildNumber() .isNullOrBlank() ||
158
+ (parameters.idePathOnHost(). isNullOrBlank() && parameters.ideDownloadLink() .isNullOrBlank()) ||
159
+ parameters.folder() .isNullOrBlank()
157
160
158
161
if (openDialog) {
159
- var data: Map < String , String > ? = null
162
+ var data: WorkspaceProjectIDE ? = null
160
163
ApplicationManager .getApplication().invokeAndWait {
161
164
val dialog = CoderWorkspaceStepDialog (name,
162
165
CoderWorkspacesStepSelection (agent, workspace, cli, client, workspaces))
@@ -167,13 +170,18 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
167
170
// Check that both the domain and the redirected domain are
168
171
// allowlisted. If not, check with the user whether to proceed.
169
172
verifyDownloadLink(parameters)
170
-
171
- parameters
172
- .withWorkspaceHostname(CoderCLIManager .getHostName(deploymentURL.toURL(), name))
173
- .withProjectPath(parameters[FOLDER ]!! )
174
- .withWebTerminalLink(client.url.withPath(" /@$username /$workspace .name/terminal" ).toString())
175
- .withConfigDirectory(cli.coderConfigPath.toString())
176
- .withName(name)
173
+ WorkspaceProjectIDE .fromInputs(
174
+ name = name,
175
+ hostname = CoderCLIManager .getHostName(deploymentURL.toURL(), name),
176
+ projectPath = parameters.folder(),
177
+ ideProductCode = parameters.ideProductCode(),
178
+ ideBuildNumber = parameters.ideBuildNumber(),
179
+ webTerminalLink = client.url.withPath(" /@$username /$workspace .name/terminal" ).toString(),
180
+ configDirectory = cli.coderConfigPath.toString(),
181
+ idePathOnHost = parameters.idePathOnHost(),
182
+ downloadSource = parameters.ideDownloadLink(),
183
+ lastOpened = null , // Have not opened yet.
184
+ )
177
185
}
178
186
}
179
187
return null
@@ -183,22 +191,22 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
183
191
* Return an authenticated Coder CLI and the user's name, asking for the
184
192
* token as long as it continues to result in an authentication failure.
185
193
*/
186
- private fun authenticate (deploymentURL : URL , queryToken : String? , lastToken : Pair <String , TokenSource >? = null): Pair <CoderRestClient , String > {
194
+ private fun authenticate (deploymentURL : String , queryToken : String? , lastToken : Pair <String , TokenSource >? = null): Pair <CoderRestClient , String > {
187
195
// Use the token from the query, unless we already tried that.
188
196
val isRetry = lastToken != null
189
197
val token = if (! queryToken.isNullOrBlank() && ! isRetry)
190
198
Pair (queryToken, TokenSource .QUERY )
191
199
else CoderRemoteConnectionHandle .askToken(
192
- deploymentURL,
200
+ deploymentURL.toURL() ,
193
201
lastToken,
194
202
isRetry,
195
203
useExisting = true ,
196
204
settings,
197
205
)
198
206
if (token == null ) { // User aborted.
199
- throw IllegalArgumentException (" Unable to connect to $deploymentURL , $TOKEN is missing" )
207
+ throw IllegalArgumentException (" Unable to connect to $deploymentURL , query parameter \" $TOKEN \" is missing" )
200
208
}
201
- val client = CoderRestClientService (deploymentURL, token.first)
209
+ val client = CoderRestClientService (deploymentURL.toURL() , token.first)
202
210
return try {
203
211
Pair (client, client.me().username)
204
212
} catch (ex: AuthenticationResponseException ) {
@@ -210,7 +218,7 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
210
218
* Check that the link is allowlisted. If not, confirm with the user.
211
219
*/
212
220
private fun verifyDownloadLink (parameters : Map <String , String >) {
213
- val link = parameters[ IDE_DOWNLOAD_LINK ]
221
+ val link = parameters.ideDownloadLink()
214
222
if (link.isNullOrBlank()) {
215
223
return // Nothing to verify
216
224
}
@@ -244,7 +252,7 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
244
252
}
245
253
246
254
override fun isApplicable (parameters : Map <String , String >): Boolean {
247
- return parameters.areCoderType ()
255
+ return parameters.isCoder ()
248
256
}
249
257
250
258
companion object {
@@ -267,18 +275,18 @@ fun getMatchingAgent(parameters: Map<String, String?>, workspace: Workspace): Wo
267
275
268
276
// If the agent is missing and the workspace has only one, use that.
269
277
// Prefer the ID over the name if both are set.
270
- val agent = if (! parameters[ AGENT_ID ] .isNullOrBlank())
271
- agents.firstOrNull { it.id.toString() == parameters[ AGENT_ID ] }
272
- else if (! parameters[ AGENT_NAME ] .isNullOrBlank())
273
- agents.firstOrNull { it.name == parameters[ AGENT_NAME ] }
278
+ val agent = if (! parameters.agentID() .isNullOrBlank())
279
+ agents.firstOrNull { it.id.toString() == parameters.agentID() }
280
+ else if (! parameters.agentName() .isNullOrBlank())
281
+ agents.firstOrNull { it.name == parameters.agentName() }
274
282
else if (agents.size == 1 ) agents.first()
275
283
else null
276
284
277
285
if (agent == null ) {
278
- if (! parameters[ AGENT_ID ] .isNullOrBlank()) {
279
- throw IllegalArgumentException (" The workspace \" ${workspace.name} \" does not have an agent with ID \" ${parameters[ AGENT_ID ] } \" " )
280
- } else if (! parameters[ AGENT_NAME ] .isNullOrBlank()){
281
- throw IllegalArgumentException (" The workspace \" ${workspace.name} \" does not have an agent named \" ${parameters[ AGENT_NAME ] } \" " )
286
+ if (! parameters.agentID() .isNullOrBlank()) {
287
+ throw IllegalArgumentException (" The workspace \" ${workspace.name} \" does not have an agent with ID \" ${parameters.agentID() } \" " )
288
+ } else if (! parameters.agentName() .isNullOrBlank()){
289
+ throw IllegalArgumentException (" The workspace \" ${workspace.name} \" does not have an agent named \" ${parameters.agentName() } \" " )
282
290
} else {
283
291
throw MissingArgumentException (" Unable to determine which agent to connect to; one of \" $AGENT_NAME \" or \" $AGENT_ID \" must be set because the workspace \" ${workspace.name} \" has more than one agent" )
284
292
}
0 commit comments