diff --git a/cloudapi-model/src/main/kotlin/cn/edu/buaa/scs/model/TicketResponse.kt b/cloudapi-model/src/main/kotlin/cn/edu/buaa/scs/model/TicketResponse.kt new file mode 100644 index 0000000..415abd8 --- /dev/null +++ b/cloudapi-model/src/main/kotlin/cn/edu/buaa/scs/model/TicketResponse.kt @@ -0,0 +1,13 @@ +package cn.edu.buaa.scs.model + +/** + * + * @param ticket 访问凭证 + * @param host 服务器主机地址 + */ +data class TicketResponse( + /* 访问凭证 */ + val ticket: kotlin.String? = null, + /* 服务器主机地址 */ + val host: kotlin.String? = null +) diff --git a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/controller/models/ChatCompletionRequest.kt b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/controller/models/ChatCompletionRequest.kt deleted file mode 100644 index 82933ee..0000000 --- a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/controller/models/ChatCompletionRequest.kt +++ /dev/null @@ -1,29 +0,0 @@ -/** -* cloudapi_v2 -* buaa scs cloud api v2 -* -* The version of the OpenAPI document: 2.0 -* Contact: loheagn@icloud.com -* -* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). -* https://openapi-generator.tech -* Do not edit the class manually. -*/ -package cn.edu.buaa.scs.controller.models - -/** - * - * @param chatId - * @param stream - * @param detail - * @param messages - * @param customUid - */ -data class ChatCompletionRequest( - val chatId: kotlin.String, - val stream: kotlin.Boolean, - val detail: kotlin.Boolean, - val messages: kotlin.collections.List, - val customUid: kotlin.String? = null -) - diff --git a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/controller/models/ChatCompletionRequestMessagesInner.kt b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/controller/models/TicketResponse.kt similarity index 60% rename from cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/controller/models/ChatCompletionRequestMessagesInner.kt rename to cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/controller/models/TicketResponse.kt index 7f07884..6052493 100644 --- a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/controller/models/ChatCompletionRequestMessagesInner.kt +++ b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/controller/models/TicketResponse.kt @@ -14,11 +14,13 @@ package cn.edu.buaa.scs.controller.models /** * - * @param role - * @param content + * @param ticket 访问凭证 + * @param host 服务器主机地址 */ -data class ChatCompletionRequestMessagesInner( - val role: kotlin.String, - val content: kotlin.String +data class TicketResponse( + /* 访问凭证 */ + val ticket: kotlin.String? = null, + /* 服务器主机地址 */ + val host: kotlin.String? = null ) diff --git a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/route/Vm.kt b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/route/Vm.kt index c9441e9..8bd4c9e 100644 --- a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/route/Vm.kt +++ b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/route/Vm.kt @@ -43,6 +43,11 @@ fun Route.vmRoute() { } } + post("/ticket") { + val vmId = call.getVmIdFromPath() + val ticketResponse = call.vm.getWebTicket(vmId) + call.respond(ticketResponse) + } } route("/template") { diff --git a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/service/Vm.kt b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/service/Vm.kt index 3934853..dd3f4c0 100644 --- a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/service/Vm.kt +++ b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/service/Vm.kt @@ -54,6 +54,10 @@ class VmService(val call: ApplicationCall) : IService { return sfClient.getHosts().getOrThrow() } + suspend fun getWebTicket(uuid: String): TicketResponse { + return vmClient.getWebTicket(uuid).getOrThrow() + } + fun getPersonalVms(): List { val vmApplyList = mysql.vmApplyList.filter { ((it.studentId eq call.userId()) or (it.teacherId eq call.userId())) and (it.experimentId eq 0) } diff --git a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/vm/VMModule.kt b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/vm/VMModule.kt index 3d8d94a..8069dbb 100644 --- a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/vm/VMModule.kt +++ b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/vm/VMModule.kt @@ -5,7 +5,7 @@ import cn.edu.buaa.scs.vm.sangfor.SangforClient import cn.edu.buaa.scs.vm.vcenter.VCenterClient import io.ktor.server.application.* -lateinit var vmClient: IVMClient +lateinit var vmClient: VCenterClient lateinit var sfClient: SangforClient @Suppress("unused") diff --git a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/vm/vcenter/VCenterClient.kt b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/vm/vcenter/VCenterClient.kt index bd79d23..dc2bffe 100644 --- a/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/vm/vcenter/VCenterClient.kt +++ b/cloudapi-web/src/main/kotlin/cn/edu/buaa/scs/vm/vcenter/VCenterClient.kt @@ -3,6 +3,7 @@ package cn.edu.buaa.scs.vm.vcenter import cn.edu.buaa.scs.config.globalConfig import cn.edu.buaa.scs.error.NotFoundException import cn.edu.buaa.scs.model.Host +import cn.edu.buaa.scs.model.TicketResponse import cn.edu.buaa.scs.model.VirtualMachine import cn.edu.buaa.scs.model.virtualMachines import cn.edu.buaa.scs.storage.mysql @@ -56,6 +57,10 @@ object VCenterClient : IVMClient { client.get("/vm/$uuid").getOrThrow() } + suspend fun getWebTicket(uuid: String): Result = runCatching { + client.post("/vm/$uuid/ticket").getOrThrow() + } + override suspend fun getVMByName(name: String, applyId: String): Result = runCatching { mysql.virtualMachines.find { (it.name eq name) and (it.applyId eq applyId) }?: throw vmNotFound(name) } diff --git a/openapi/cloudapi_v2.yaml b/openapi/cloudapi_v2.yaml index 8ef25a5..6ca0edb 100644 --- a/openapi/cloudapi_v2.yaml +++ b/openapi/cloudapi_v2.yaml @@ -1022,6 +1022,27 @@ paths: in: query name: sync description: 表示该请求是否同步返回,默认为false,即默认异步。client需要在后续查询具体的执行情况 + '/vm/{vmId}/ticket': + parameters: + - schema: + type: string + name: vmId + in: path + required: true + description: vm uuid + post: + summary: 创建 Web 访问凭证 + tags: + - 虚拟机 + description: 创建虚拟机的 Web 访问凭证,返回 ticket 和 host。 + operationId: post-vm-vmId-ticket + responses: + '200': + description: 成功创建访问凭证 + content: + application/json: + schema: + $ref: '#/components/schemas/TicketResponse' /vms: get: summary: get Virtual Machine list @@ -4977,6 +4998,15 @@ components: type: integer loadCustomFeedbacks: type: boolean + TicketResponse: + type: object + properties: + ticket: + type: string + description: 访问凭证 + host: + type: string + description: 服务器主机地址 securitySchemes: Authorization: type: apiKey diff --git a/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/Connection.kt b/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/Connection.kt index 02ac38f..fce0932 100644 --- a/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/Connection.kt +++ b/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/Connection.kt @@ -4,6 +4,7 @@ import com.vmware.photon.controller.model.adapters.vsphere.util.connection.Conne import com.vmware.photon.controller.model.adapters.vsphere.util.connection.GetMoRef import com.vmware.vim25.ManagedObjectReference import com.vmware.vim25.RetrieveOptions +import com.vmware.vim25.VirtualMachineTicket fun Connection.getMoRef(): GetMoRef { return GetMoRef(this) diff --git a/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/VCenterRoute.kt b/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/VCenterRoute.kt index fb6f4b2..f85f2db 100644 --- a/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/VCenterRoute.kt +++ b/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/VCenterRoute.kt @@ -59,6 +59,11 @@ fun Application.vcenterRouting() { VCenterWrapper.convertVMToTemplate(call.getVmUuid()).getOrThrow() call.respond("OK") } + + post("/ticket") { + val ticketResponse = VCenterWrapper.getWebTicket(call.getVmUuid()) + call.respond(ticketResponse) + } } route("/health") { diff --git a/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/VCenterWrapper.kt b/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/VCenterWrapper.kt index cdeef06..37cac5a 100644 --- a/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/VCenterWrapper.kt +++ b/vcenter/src/main/kotlin/cn/edu/buaa/scs/vcenter/VCenterWrapper.kt @@ -4,6 +4,7 @@ import cn.edu.buaa.scs.config.globalConfig import cn.edu.buaa.scs.model.VirtualMachine import cn.edu.buaa.scs.model.VirtualMachineExtraInfo import cn.edu.buaa.scs.model.applyExtraInfo +import cn.edu.buaa.scs.model.TicketResponse import cn.edu.buaa.scs.utils.jsonMapper import cn.edu.buaa.scs.utils.logger import cn.edu.buaa.scs.vm.ConfigVmOptions @@ -360,6 +361,17 @@ object VCenterWrapper { }.getOrThrow() } + suspend fun getWebTicket(uuid: String): TicketResponse { + return baseSyncTask { connection -> + val vmRef = connection.getVmRefByUuid(uuid) + val vmTicket = connection.vimPort.acquireTicket(vmRef, "webmks") + TicketResponse( + ticket = vmTicket.ticket, + host = vmTicket.host + ) + }.getOrThrow() + } + suspend fun convertVMToTemplate(uuid: String): Result { return baseSyncTask { connection -> val vmRef = connection.getVmRefByUuid(uuid)