Skip to content

Upgrade coder client authentication API #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Impl: updated all API models
The http client now works with latest versions of Coder
  • Loading branch information
fioan89 committed Nov 22, 2022
commit d511e8c81e7f7efa4713032c17394ef97b9b8e29
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## [Unreleased]
### Added

- upgraded API models
- upgraded support to the latest Coder platform

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.coder.gateway.models

import com.coder.gateway.sdk.Arch
import com.coder.gateway.sdk.OS
import com.coder.gateway.sdk.v2.models.WorkspaceTransition
import java.util.UUID

data class WorkspaceAgentModel(
Expand All @@ -12,7 +13,7 @@ data class WorkspaceAgentModel(
val templateName: String,
val status: WorkspaceVersionStatus,
val agentStatus: WorkspaceAgentStatus,
val lastBuildTransition: String,
val lastBuildTransition: WorkspaceTransition,
val agentOS: OS?,
val agentArch: Arch?,
val homeDirectory: String?
Expand Down
13 changes: 7 additions & 6 deletions src/main/kotlin/com/coder/gateway/sdk/CoderRestClientService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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.sdk.v2.models.WorkspaceBuild
import com.coder.gateway.sdk.v2.models.WorkspaceTransition
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.intellij.openapi.components.Service
Expand Down Expand Up @@ -55,7 +56,7 @@ class CoderRestClientService {
.create()

val interceptor = HttpLoggingInterceptor()
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC)
retroRestClient = Retrofit.Builder()
.baseUrl(url.toString())
.client(
Expand Down Expand Up @@ -91,7 +92,7 @@ class CoderRestClientService {
throw WorkspaceResponseException("Could not retrieve Coder Workspaces:${workspacesResponse.code()}, reason: ${workspacesResponse.message()}")
}

return workspacesResponse.body()!!
return workspacesResponse.body()!!.workspaces
}

private fun buildInfo(): BuildInfo {
Expand Down Expand Up @@ -126,7 +127,7 @@ class CoderRestClientService {
}

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

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

fun updateWorkspace(workspaceID: UUID, workspaceName: String, lastWorkspaceTransition: String, templateID: UUID): WorkspaceBuild {
fun updateWorkspace(workspaceID: UUID, workspaceName: String, lastWorkspaceTransition: WorkspaceTransition, templateID: UUID): WorkspaceBuild {
val template = template(templateID)

val buildRequest = CreateWorkspaceBuildRequest(template.activeVersionID, lastWorkspaceTransition, null, null, null)
val buildRequest = CreateWorkspaceBuildRequest(template.activeVersionID, lastWorkspaceTransition, null, null, null, null)
val buildResponse = retroRestClient.createWorkspaceBuild(workspaceID, buildRequest).execute()
if (buildResponse.code() != HTTP_CREATED) {
throw WorkspaceResponseException("Failed to update workspace ${workspaceName}: ${buildResponse.code()}, reason: ${buildResponse.message()}")
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/com/coder/gateway/sdk/v2/CoderV2RestFacade.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ 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.WorkspacesResponse
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.GET
Expand All @@ -27,7 +27,7 @@ interface CoderV2RestFacade {
* Retrieves all workspaces the authenticated user has access to.
*/
@GET("api/v2/workspaces")
fun workspaces(@Query("q") searchParams: String): Call<List<Workspace>>
fun workspaces(@Query("q") searchParams: String): Call<WorkspacesResponse>

@GET("api/v2/buildinfo")
fun buildInfo(): Call<BuildInfo>
Expand Down
20 changes: 20 additions & 0 deletions src/main/kotlin/com/coder/gateway/sdk/v2/models/BuildReason.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.coder.gateway.sdk.v2.models

import com.google.gson.annotations.SerializedName

enum class BuildReason {
// "initiator" is used when a workspace build is triggered by a user.
// Combined with the initiator id/username, it indicates which user initiated the build.
@SerializedName("initiator")
INITIATOR,

// "autostart" is used when a build to start a workspace is triggered by Autostart.
// The initiator id/username in this case is the workspace owner and can be ignored.
@SerializedName("autostart")
AUTOSTART,

// "autostop" is used when a build to stop a workspace is triggered by Autostop.
// The initiator id/username in this case is the workspace owner and can be ignored.
@SerializedName("autostop")
AUTOSTOP
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ data class CreateParameterRequest(
@SerializedName("copy_from_parameter") val cloneID: UUID?,
@SerializedName("name") val name: String,
@SerializedName("source_value") val sourceValue: String,
@SerializedName("source_scheme") val sourceScheme: String,
@SerializedName("destination_scheme") val destinationScheme: String
)
@SerializedName("source_scheme") val sourceScheme: ParameterSourceScheme,
@SerializedName("destination_scheme") val destinationScheme: ParameterDestinationScheme
)

enum class ParameterSourceScheme {
@SerializedName("none")
NONE,

@SerializedName("data")
DATA
}

enum class ParameterDestinationScheme {
@SerializedName("none")
NONE,

@SerializedName("environment_variable")
ENVIRONMENT_VARIABLE,

@SerializedName("provisioner_variable")
PROVISIONER_VARIABLE
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import java.util.UUID

data class CreateWorkspaceBuildRequest(
@SerializedName("template_version_id") val templateVersionID: UUID?,
@SerializedName("transition") val transition: String,
@SerializedName("transition") val transition: WorkspaceTransition,
@SerializedName("dry_run") val dryRun: Boolean?,
@SerializedName("state") val state: Array<Byte>?,
@SerializedName("state") val provisionerState: Array<Byte>?,
// Orphan may be set for the Destroy transition.
@SerializedName("orphan") val orphan: Boolean?,
@SerializedName("parameter_values") val parameterValues: Array<CreateParameterRequest>?
) {

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
Expand All @@ -20,10 +21,11 @@ data class CreateWorkspaceBuildRequest(
if (templateVersionID != other.templateVersionID) return false
if (transition != other.transition) return false
if (dryRun != other.dryRun) return false
if (state != null) {
if (other.state == null) return false
if (!state.contentEquals(other.state)) return false
} else if (other.state != null) return false
if (provisionerState != null) {
if (other.provisionerState == null) return false
if (!provisionerState.contentEquals(other.provisionerState)) return false
} else if (other.provisionerState != null) return false
if (orphan != other.orphan) return false
if (parameterValues != null) {
if (other.parameterValues == null) return false
if (!parameterValues.contentEquals(other.parameterValues)) return false
Expand All @@ -36,9 +38,9 @@ data class CreateWorkspaceBuildRequest(
var result = templateVersionID?.hashCode() ?: 0
result = 31 * result + transition.hashCode()
result = 31 * result + (dryRun?.hashCode() ?: 0)
result = 31 * result + (state?.contentHashCode() ?: 0)
result = 31 * result + (provisionerState?.contentHashCode() ?: 0)
result = 31 * result + (orphan?.hashCode() ?: 0)
result = 31 * result + (parameterValues?.contentHashCode() ?: 0)
return result
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import java.util.UUID
data class ProvisionerJob(
@SerializedName("id") val id: UUID,
@SerializedName("created_at") val createdAt: Instant,
@SerializedName("started_at") val startedAt: Instant,
@SerializedName("completed_at") val completedAt: Instant,
@SerializedName("canceled_at") val canceledAt: Instant,
@SerializedName("error") val error: String,
@SerializedName("started_at") val startedAt: Instant?,
@SerializedName("completed_at") val completedAt: Instant?,
@SerializedName("canceled_at") val canceledAt: Instant?,
@SerializedName("error") val error: String?,
@SerializedName("status") val status: ProvisionerJobStatus,
@SerializedName("worker_id") val workerID: UUID,
@SerializedName("worker_id") val workerID: UUID?,
@SerializedName("file_id") val fileID: UUID,
@SerializedName("tags") val tags: Map<String, String>,
)
Expand Down
32 changes: 31 additions & 1 deletion src/main/kotlin/com/coder/gateway/sdk/v2/models/Role.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,34 @@ package com.coder.gateway.sdk.v2.models

import com.google.gson.annotations.SerializedName

data class Role(@SerializedName("name") val name: String, @SerializedName("display_name") val displayName: String)
data class Role(
@SerializedName("name") val name: String,
@SerializedName("display_name") val displayName: String,
@SerializedName("site") val site: Permission,
// Org is a map of orgid to permissions. We represent orgid as a string.
// We scope the organizations in the role so we can easily combine all the
// roles.
@SerializedName("org") val org: Map<String, List<Permission>>,
@SerializedName("user") val user: List<Permission>,

)

data class Permission(
@SerializedName("negate") val negate: Boolean,
@SerializedName("resource_type") val resourceType: String,
@SerializedName("action") val action: Action,
)

enum class Action {
@SerializedName("create")
CREATE,

@SerializedName("read")
READ,

@SerializedName("update")
UPDATE,

@SerializedName("delete")
DELETE
}
20 changes: 17 additions & 3 deletions src/main/kotlin/com/coder/gateway/sdk/v2/models/Template.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,26 @@ data class Template(
@SerializedName("updated_at") val updatedAt: Instant,
@SerializedName("organization_id") val organizationIterator: UUID,
@SerializedName("name") val name: String,
@SerializedName("provisioner") val provisioner: String,
@SerializedName("display_name") val displayName: String,
@SerializedName("provisioner") val provisioner: ProvisionerType,
@SerializedName("active_version_id") val activeVersionID: UUID,
@SerializedName("workspace_owner_count") val workspaceOwnerCount: Int,
@SerializedName("active_user_count") val activeUserCount: Int,
@SerializedName("build_time_stats") val buildTimeStats: Map<WorkspaceTransition, TransitionStats>,
@SerializedName("description") val description: String,
@SerializedName("max_ttl_ms") val maxTTLMillis: Long,
@SerializedName("min_autostart_interval_ms") val minAutostartIntervalMillis: Long,
@SerializedName("icon") val icon: String,
@SerializedName("default_ttl_ms") val defaultTTLMillis: Long,
@SerializedName("created_by_id") val createdByID: UUID,
@SerializedName("created_by_name") val createdByName: String,
@SerializedName("allow_user_cancel_workspace_jobs") val allowUserCancelWorkspaceJobs: Boolean,
)

enum class ProvisionerType {
@SerializedName("echo")
ECHO,

@SerializedName("terraform")
TERRAFORM
}

data class TransitionStats(val p50: Long, val p95: Long)
16 changes: 13 additions & 3 deletions src/main/kotlin/com/coder/gateway/sdk/v2/models/User.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,21 @@ import java.util.UUID

data class User(
@SerializedName("id") val id: UUID,
@SerializedName("email") val email: String,
@SerializedName("username") val username: String,
@SerializedName("email") val email: String,
@SerializedName("created_at") val createdAt: Instant,
@SerializedName("last_seen_at") val lastSeenAt: Instant,

@SerializedName("status") val status: String?,
@SerializedName("organization_ids") val organizationIDs: List<UUID>?,
@SerializedName("status") val status: UserStatus,
@SerializedName("organization_ids") val organizationIDs: List<UUID>,
@SerializedName("roles") val roles: List<Role>?,
@SerializedName("avatar_url") val avatarURL: String,
)

enum class UserStatus {
@SerializedName("active")
ACTIVE,

@SerializedName("suspended")
SUSPENDED
}
8 changes: 6 additions & 2 deletions src/main/kotlin/com/coder/gateway/sdk/v2/models/Workspace.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ data class Workspace(
@SerializedName("owner_name") val ownerName: String,
@SerializedName("template_id") val templateID: UUID,
@SerializedName("template_name") val templateName: String,
@SerializedName("template_display_name") val templateDisplayName: String,
@SerializedName("template_icon") val templateIcon: String,
@SerializedName("template_allow_user_cancel_workspace_jobs") val templateAllowUserCancelWorkspaceJobs: Boolean,
@SerializedName("latest_build") val latestBuild: WorkspaceBuild,
@SerializedName("outdated") val outdated: Boolean,
@SerializedName("name") val name: String,
@SerializedName("autostart_schedule") val autostartSchedule: String,
@SerializedName("ttl") val ttl: Long,
@SerializedName("autostart_schedule") val autostartSchedule: String?,
@SerializedName("ttl_ms") val ttlMillis: Long?,
@SerializedName("last_used_at") val lastUsedAt: Instant,
)
31 changes: 27 additions & 4 deletions src/main/kotlin/com/coder/gateway/sdk/v2/models/WorkspaceAgent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,37 @@ data class WorkspaceAgent(
@SerializedName("first_connected_at") val firstConnectedAt: Instant?,
@SerializedName("last_connected_at") val lastConnectedAt: Instant?,
@SerializedName("disconnected_at") val disconnectedAt: Instant?,
@SerializedName("status") val status: String,
@SerializedName("status") val status: WorkspaceAgentStatus,
@SerializedName("name") val name: String,
@SerializedName("resource_id") val resourceID: UUID,
@SerializedName("instance_id") val instanceID: String,
@SerializedName("instance_id") val instanceID: String?,
@SerializedName("architecture") val architecture: String,
@SerializedName("environment_variables") val envVariables: Map<String, String>,
@SerializedName("operating_system") val operatingSystem: String,
@SerializedName("startup_script") val startupScript: String,
@SerializedName("startup_script") val startupScript: String?,
@SerializedName("directory") val directory: String?,
@SerializedName("apps") val apps: List<WorkspaceApp>
@SerializedName("version") val version: String,
@SerializedName("apps") val apps: List<WorkspaceApp>,
@SerializedName("latency") val derpLatency: Map<String, DERPRegion>?,
@SerializedName("connection_timeout_seconds") val connectionTimeoutSeconds: Int,
@SerializedName("troubleshooting_url") val troubleshootingURL: String
)

enum class WorkspaceAgentStatus {
@SerializedName("connecting")
CONNECTING,

@SerializedName("connected")
CONNECTED,

@SerializedName("disconnected")
DISCONNECTED,

@SerializedName("timeout")
TIMEOUT
}

data class DERPRegion(
@SerializedName("preferred") val preferred: Boolean,
@SerializedName("latency_ms") val latencyMillis: Double
)
Loading