Skip to content

Commit d511e8c

Browse files
committed
Impl: updated all API models
The http client now works with latest versions of Coder
1 parent 7477fcf commit d511e8c

19 files changed

+276
-58
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
## [Unreleased]
66
### Added
77

8-
- upgraded API models
8+
- upgraded support to the latest Coder platform
99

1010
### Fixed
1111

src/main/kotlin/com/coder/gateway/models/WorkspaceAgentModel.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.coder.gateway.models
22

33
import com.coder.gateway.sdk.Arch
44
import com.coder.gateway.sdk.OS
5+
import com.coder.gateway.sdk.v2.models.WorkspaceTransition
56
import java.util.UUID
67

78
data class WorkspaceAgentModel(
@@ -12,7 +13,7 @@ data class WorkspaceAgentModel(
1213
val templateName: String,
1314
val status: WorkspaceVersionStatus,
1415
val agentStatus: WorkspaceAgentStatus,
15-
val lastBuildTransition: String,
16+
val lastBuildTransition: WorkspaceTransition,
1617
val agentOS: OS?,
1718
val agentArch: Arch?,
1819
val homeDirectory: String?

src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt

+7-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.coder.gateway.sdk.v2.models.User
1313
import com.coder.gateway.sdk.v2.models.Workspace
1414
import com.coder.gateway.sdk.v2.models.WorkspaceAgent
1515
import com.coder.gateway.sdk.v2.models.WorkspaceBuild
16+
import com.coder.gateway.sdk.v2.models.WorkspaceTransition
1617
import com.google.gson.Gson
1718
import com.google.gson.GsonBuilder
1819
import com.intellij.openapi.components.Service
@@ -55,7 +56,7 @@ class CoderRestClientService {
5556
.create()
5657

5758
val interceptor = HttpLoggingInterceptor()
58-
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
59+
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC)
5960
retroRestClient = Retrofit.Builder()
6061
.baseUrl(url.toString())
6162
.client(
@@ -91,7 +92,7 @@ class CoderRestClientService {
9192
throw WorkspaceResponseException("Could not retrieve Coder Workspaces:${workspacesResponse.code()}, reason: ${workspacesResponse.message()}")
9293
}
9394

94-
return workspacesResponse.body()!!
95+
return workspacesResponse.body()!!.workspaces
9596
}
9697

9798
private fun buildInfo(): BuildInfo {
@@ -126,7 +127,7 @@ class CoderRestClientService {
126127
}
127128

128129
fun startWorkspace(workspaceID: UUID, workspaceName: String): WorkspaceBuild {
129-
val buildRequest = CreateWorkspaceBuildRequest(null, "start", null, null, null)
130+
val buildRequest = CreateWorkspaceBuildRequest(null, WorkspaceTransition.START, null, null, null, null)
130131
val buildResponse = retroRestClient.createWorkspaceBuild(workspaceID, buildRequest).execute()
131132
if (buildResponse.code() != HTTP_CREATED) {
132133
throw WorkspaceResponseException("Failed to build workspace ${workspaceName}: ${buildResponse.code()}, reason: ${buildResponse.message()}")
@@ -136,7 +137,7 @@ class CoderRestClientService {
136137
}
137138

138139
fun stopWorkspace(workspaceID: UUID, workspaceName: String): WorkspaceBuild {
139-
val buildRequest = CreateWorkspaceBuildRequest(null, "stop", null, null, null)
140+
val buildRequest = CreateWorkspaceBuildRequest(null, WorkspaceTransition.STOP, null, null, null, null)
140141
val buildResponse = retroRestClient.createWorkspaceBuild(workspaceID, buildRequest).execute()
141142
if (buildResponse.code() != HTTP_CREATED) {
142143
throw WorkspaceResponseException("Failed to stop workspace ${workspaceName}: ${buildResponse.code()}, reason: ${buildResponse.message()}")
@@ -145,10 +146,10 @@ class CoderRestClientService {
145146
return buildResponse.body()!!
146147
}
147148

148-
fun updateWorkspace(workspaceID: UUID, workspaceName: String, lastWorkspaceTransition: String, templateID: UUID): WorkspaceBuild {
149+
fun updateWorkspace(workspaceID: UUID, workspaceName: String, lastWorkspaceTransition: WorkspaceTransition, templateID: UUID): WorkspaceBuild {
149150
val template = template(templateID)
150151

151-
val buildRequest = CreateWorkspaceBuildRequest(template.activeVersionID, lastWorkspaceTransition, null, null, null)
152+
val buildRequest = CreateWorkspaceBuildRequest(template.activeVersionID, lastWorkspaceTransition, null, null, null, null)
152153
val buildResponse = retroRestClient.createWorkspaceBuild(workspaceID, buildRequest).execute()
153154
if (buildResponse.code() != HTTP_CREATED) {
154155
throw WorkspaceResponseException("Failed to update workspace ${workspaceName}: ${buildResponse.code()}, reason: ${buildResponse.message()}")

src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import com.coder.gateway.sdk.v2.models.BuildInfo
44
import com.coder.gateway.sdk.v2.models.CreateWorkspaceBuildRequest
55
import com.coder.gateway.sdk.v2.models.Template
66
import com.coder.gateway.sdk.v2.models.User
7-
import com.coder.gateway.sdk.v2.models.Workspace
87
import com.coder.gateway.sdk.v2.models.WorkspaceBuild
98
import com.coder.gateway.sdk.v2.models.WorkspaceResource
9+
import com.coder.gateway.sdk.v2.models.WorkspacesResponse
1010
import retrofit2.Call
1111
import retrofit2.http.Body
1212
import retrofit2.http.GET
@@ -27,7 +27,7 @@ interface CoderV2RestFacade {
2727
* Retrieves all workspaces the authenticated user has access to.
2828
*/
2929
@GET("api/v2/workspaces")
30-
fun workspaces(@Query("q") searchParams: String): Call<List<Workspace>>
30+
fun workspaces(@Query("q") searchParams: String): Call<WorkspacesResponse>
3131

3232
@GET("api/v2/buildinfo")
3333
fun buildInfo(): Call<BuildInfo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.coder.gateway.sdk.v2.models
2+
3+
import com.google.gson.annotations.SerializedName
4+
5+
enum class BuildReason {
6+
// "initiator" is used when a workspace build is triggered by a user.
7+
// Combined with the initiator id/username, it indicates which user initiated the build.
8+
@SerializedName("initiator")
9+
INITIATOR,
10+
11+
// "autostart" is used when a build to start a workspace is triggered by Autostart.
12+
// The initiator id/username in this case is the workspace owner and can be ignored.
13+
@SerializedName("autostart")
14+
AUTOSTART,
15+
16+
// "autostop" is used when a build to stop a workspace is triggered by Autostop.
17+
// The initiator id/username in this case is the workspace owner and can be ignored.
18+
@SerializedName("autostop")
19+
AUTOSTOP
20+
}

src/main/kotlin/com/coder/gateway/sdk/v2/models/CreateParameterRequest.kt

+22-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,25 @@ data class CreateParameterRequest(
77
@SerializedName("copy_from_parameter") val cloneID: UUID?,
88
@SerializedName("name") val name: String,
99
@SerializedName("source_value") val sourceValue: String,
10-
@SerializedName("source_scheme") val sourceScheme: String,
11-
@SerializedName("destination_scheme") val destinationScheme: String
12-
)
10+
@SerializedName("source_scheme") val sourceScheme: ParameterSourceScheme,
11+
@SerializedName("destination_scheme") val destinationScheme: ParameterDestinationScheme
12+
)
13+
14+
enum class ParameterSourceScheme {
15+
@SerializedName("none")
16+
NONE,
17+
18+
@SerializedName("data")
19+
DATA
20+
}
21+
22+
enum class ParameterDestinationScheme {
23+
@SerializedName("none")
24+
NONE,
25+
26+
@SerializedName("environment_variable")
27+
ENVIRONMENT_VARIABLE,
28+
29+
@SerializedName("provisioner_variable")
30+
PROVISIONER_VARIABLE
31+
}

src/main/kotlin/com/coder/gateway/sdk/v2/models/CreateWorkspaceBuildRequest.kt

+11-9
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import java.util.UUID
55

66
data class CreateWorkspaceBuildRequest(
77
@SerializedName("template_version_id") val templateVersionID: UUID?,
8-
@SerializedName("transition") val transition: String,
8+
@SerializedName("transition") val transition: WorkspaceTransition,
99
@SerializedName("dry_run") val dryRun: Boolean?,
10-
@SerializedName("state") val state: Array<Byte>?,
10+
@SerializedName("state") val provisionerState: Array<Byte>?,
11+
// Orphan may be set for the Destroy transition.
12+
@SerializedName("orphan") val orphan: Boolean?,
1113
@SerializedName("parameter_values") val parameterValues: Array<CreateParameterRequest>?
1214
) {
13-
1415
override fun equals(other: Any?): Boolean {
1516
if (this === other) return true
1617
if (javaClass != other?.javaClass) return false
@@ -20,10 +21,11 @@ data class CreateWorkspaceBuildRequest(
2021
if (templateVersionID != other.templateVersionID) return false
2122
if (transition != other.transition) return false
2223
if (dryRun != other.dryRun) return false
23-
if (state != null) {
24-
if (other.state == null) return false
25-
if (!state.contentEquals(other.state)) return false
26-
} else if (other.state != null) return false
24+
if (provisionerState != null) {
25+
if (other.provisionerState == null) return false
26+
if (!provisionerState.contentEquals(other.provisionerState)) return false
27+
} else if (other.provisionerState != null) return false
28+
if (orphan != other.orphan) return false
2729
if (parameterValues != null) {
2830
if (other.parameterValues == null) return false
2931
if (!parameterValues.contentEquals(other.parameterValues)) return false
@@ -36,9 +38,9 @@ data class CreateWorkspaceBuildRequest(
3638
var result = templateVersionID?.hashCode() ?: 0
3739
result = 31 * result + transition.hashCode()
3840
result = 31 * result + (dryRun?.hashCode() ?: 0)
39-
result = 31 * result + (state?.contentHashCode() ?: 0)
41+
result = 31 * result + (provisionerState?.contentHashCode() ?: 0)
42+
result = 31 * result + (orphan?.hashCode() ?: 0)
4043
result = 31 * result + (parameterValues?.contentHashCode() ?: 0)
4144
return result
4245
}
4346
}
44-

src/main/kotlin/com/coder/gateway/sdk/v2/models/ProvisionerJob.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import java.util.UUID
77
data class ProvisionerJob(
88
@SerializedName("id") val id: UUID,
99
@SerializedName("created_at") val createdAt: Instant,
10-
@SerializedName("started_at") val startedAt: Instant,
11-
@SerializedName("completed_at") val completedAt: Instant,
12-
@SerializedName("canceled_at") val canceledAt: Instant,
13-
@SerializedName("error") val error: String,
10+
@SerializedName("started_at") val startedAt: Instant?,
11+
@SerializedName("completed_at") val completedAt: Instant?,
12+
@SerializedName("canceled_at") val canceledAt: Instant?,
13+
@SerializedName("error") val error: String?,
1414
@SerializedName("status") val status: ProvisionerJobStatus,
15-
@SerializedName("worker_id") val workerID: UUID,
15+
@SerializedName("worker_id") val workerID: UUID?,
1616
@SerializedName("file_id") val fileID: UUID,
1717
@SerializedName("tags") val tags: Map<String, String>,
1818
)

src/main/kotlin/com/coder/gateway/sdk/v2/models/Role.kt

+31-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,34 @@ package com.coder.gateway.sdk.v2.models
22

33
import com.google.gson.annotations.SerializedName
44

5-
data class Role(@SerializedName("name") val name: String, @SerializedName("display_name") val displayName: String)
5+
data class Role(
6+
@SerializedName("name") val name: String,
7+
@SerializedName("display_name") val displayName: String,
8+
@SerializedName("site") val site: Permission,
9+
// Org is a map of orgid to permissions. We represent orgid as a string.
10+
// We scope the organizations in the role so we can easily combine all the
11+
// roles.
12+
@SerializedName("org") val org: Map<String, List<Permission>>,
13+
@SerializedName("user") val user: List<Permission>,
14+
15+
)
16+
17+
data class Permission(
18+
@SerializedName("negate") val negate: Boolean,
19+
@SerializedName("resource_type") val resourceType: String,
20+
@SerializedName("action") val action: Action,
21+
)
22+
23+
enum class Action {
24+
@SerializedName("create")
25+
CREATE,
26+
27+
@SerializedName("read")
28+
READ,
29+
30+
@SerializedName("update")
31+
UPDATE,
32+
33+
@SerializedName("delete")
34+
DELETE
35+
}

src/main/kotlin/com/coder/gateway/sdk/v2/models/Template.kt

+17-3
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,26 @@ data class Template(
1010
@SerializedName("updated_at") val updatedAt: Instant,
1111
@SerializedName("organization_id") val organizationIterator: UUID,
1212
@SerializedName("name") val name: String,
13-
@SerializedName("provisioner") val provisioner: String,
13+
@SerializedName("display_name") val displayName: String,
14+
@SerializedName("provisioner") val provisioner: ProvisionerType,
1415
@SerializedName("active_version_id") val activeVersionID: UUID,
1516
@SerializedName("workspace_owner_count") val workspaceOwnerCount: Int,
17+
@SerializedName("active_user_count") val activeUserCount: Int,
18+
@SerializedName("build_time_stats") val buildTimeStats: Map<WorkspaceTransition, TransitionStats>,
1619
@SerializedName("description") val description: String,
17-
@SerializedName("max_ttl_ms") val maxTTLMillis: Long,
18-
@SerializedName("min_autostart_interval_ms") val minAutostartIntervalMillis: Long,
20+
@SerializedName("icon") val icon: String,
21+
@SerializedName("default_ttl_ms") val defaultTTLMillis: Long,
1922
@SerializedName("created_by_id") val createdByID: UUID,
2023
@SerializedName("created_by_name") val createdByName: String,
24+
@SerializedName("allow_user_cancel_workspace_jobs") val allowUserCancelWorkspaceJobs: Boolean,
2125
)
26+
27+
enum class ProvisionerType {
28+
@SerializedName("echo")
29+
ECHO,
30+
31+
@SerializedName("terraform")
32+
TERRAFORM
33+
}
34+
35+
data class TransitionStats(val p50: Long, val p95: Long)

src/main/kotlin/com/coder/gateway/sdk/v2/models/User.kt

+13-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,21 @@ import java.util.UUID
66

77
data class User(
88
@SerializedName("id") val id: UUID,
9-
@SerializedName("email") val email: String,
109
@SerializedName("username") val username: String,
10+
@SerializedName("email") val email: String,
1111
@SerializedName("created_at") val createdAt: Instant,
12+
@SerializedName("last_seen_at") val lastSeenAt: Instant,
1213

13-
@SerializedName("status") val status: String?,
14-
@SerializedName("organization_ids") val organizationIDs: List<UUID>?,
14+
@SerializedName("status") val status: UserStatus,
15+
@SerializedName("organization_ids") val organizationIDs: List<UUID>,
1516
@SerializedName("roles") val roles: List<Role>?,
17+
@SerializedName("avatar_url") val avatarURL: String,
1618
)
19+
20+
enum class UserStatus {
21+
@SerializedName("active")
22+
ACTIVE,
23+
24+
@SerializedName("suspended")
25+
SUSPENDED
26+
}

src/main/kotlin/com/coder/gateway/sdk/v2/models/Workspace.kt

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@ data class Workspace(
1515
@SerializedName("owner_name") val ownerName: String,
1616
@SerializedName("template_id") val templateID: UUID,
1717
@SerializedName("template_name") val templateName: String,
18+
@SerializedName("template_display_name") val templateDisplayName: String,
19+
@SerializedName("template_icon") val templateIcon: String,
20+
@SerializedName("template_allow_user_cancel_workspace_jobs") val templateAllowUserCancelWorkspaceJobs: Boolean,
1821
@SerializedName("latest_build") val latestBuild: WorkspaceBuild,
1922
@SerializedName("outdated") val outdated: Boolean,
2023
@SerializedName("name") val name: String,
21-
@SerializedName("autostart_schedule") val autostartSchedule: String,
22-
@SerializedName("ttl") val ttl: Long,
24+
@SerializedName("autostart_schedule") val autostartSchedule: String?,
25+
@SerializedName("ttl_ms") val ttlMillis: Long?,
26+
@SerializedName("last_used_at") val lastUsedAt: Instant,
2327
)

src/main/kotlin/com/coder/gateway/sdk/v2/models/WorkspaceAgent.kt

+27-4
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,37 @@ data class WorkspaceAgent(
1111
@SerializedName("first_connected_at") val firstConnectedAt: Instant?,
1212
@SerializedName("last_connected_at") val lastConnectedAt: Instant?,
1313
@SerializedName("disconnected_at") val disconnectedAt: Instant?,
14-
@SerializedName("status") val status: String,
14+
@SerializedName("status") val status: WorkspaceAgentStatus,
1515
@SerializedName("name") val name: String,
1616
@SerializedName("resource_id") val resourceID: UUID,
17-
@SerializedName("instance_id") val instanceID: String,
17+
@SerializedName("instance_id") val instanceID: String?,
1818
@SerializedName("architecture") val architecture: String,
1919
@SerializedName("environment_variables") val envVariables: Map<String, String>,
2020
@SerializedName("operating_system") val operatingSystem: String,
21-
@SerializedName("startup_script") val startupScript: String,
21+
@SerializedName("startup_script") val startupScript: String?,
2222
@SerializedName("directory") val directory: String?,
23-
@SerializedName("apps") val apps: List<WorkspaceApp>
23+
@SerializedName("version") val version: String,
24+
@SerializedName("apps") val apps: List<WorkspaceApp>,
25+
@SerializedName("latency") val derpLatency: Map<String, DERPRegion>?,
26+
@SerializedName("connection_timeout_seconds") val connectionTimeoutSeconds: Int,
27+
@SerializedName("troubleshooting_url") val troubleshootingURL: String
28+
)
29+
30+
enum class WorkspaceAgentStatus {
31+
@SerializedName("connecting")
32+
CONNECTING,
33+
34+
@SerializedName("connected")
35+
CONNECTED,
36+
37+
@SerializedName("disconnected")
38+
DISCONNECTED,
39+
40+
@SerializedName("timeout")
41+
TIMEOUT
42+
}
43+
44+
data class DERPRegion(
45+
@SerializedName("preferred") val preferred: Boolean,
46+
@SerializedName("latency_ms") val latencyMillis: Double
2447
)

0 commit comments

Comments
 (0)