feat: 完整游戏运维功能
This commit is contained in:
@@ -0,0 +1,352 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"browser.local/platform/dto"
|
||||
)
|
||||
|
||||
// serverClientManagerLifecycles godoc
|
||||
// @Summary List Client Manager lifecycle installations
|
||||
// @Description Returns safe durable lifecycle, health, real job progress, and action availability for the authorized server without component secrets or machine details.
|
||||
// @Tags client-managers
|
||||
// @Produce json
|
||||
// @Param id path string true "Server instance ID"
|
||||
// @Success 200 {object} dto.ClientManagerInstallationListResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Failure 403 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/server-instances/{id}/client-managers [get]
|
||||
func (h *coreHandlers) serverClientManagerLifecycles(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
writeMethodNotAllowed(w, http.MethodGet)
|
||||
return
|
||||
}
|
||||
views, err := h.core.ListClientManagerLifecyclesForSession(bearerToken(r), r.PathValue("id"))
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, dto.ClientManagerLifecycleViewsFromDomain(views))
|
||||
}
|
||||
|
||||
// serverClientManagerLifecycleDetail godoc
|
||||
// @Summary Get one Client Manager lifecycle installation
|
||||
// @Tags client-managers
|
||||
// @Produce json
|
||||
// @Param id path string true "Server instance ID"
|
||||
// @Param profileKey path string true "Client Manager profile key"
|
||||
// @Success 200 {object} dto.ClientManagerInstallationResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Failure 403 {object} dto.ErrorResponse
|
||||
// @Failure 404 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/server-instances/{id}/client-managers/{profileKey} [get]
|
||||
func (h *coreHandlers) serverClientManagerLifecycleDetail(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
writeMethodNotAllowed(w, http.MethodGet)
|
||||
return
|
||||
}
|
||||
view, err := h.core.GetClientManagerLifecycleForSession(bearerToken(r), r.PathValue("id"), r.PathValue("profileKey"))
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, dto.ClientManagerLifecycleViewFromDomain(view))
|
||||
}
|
||||
|
||||
// serverClientManagerDeploy godoc
|
||||
// @Summary Deploy an available Client Manager distribution
|
||||
// @Description Queues a typed Run deployment after server, endpoint, artifact, target, revision, and key-generation authorization.
|
||||
// @Tags client-managers
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Server instance ID"
|
||||
// @Param body body dto.ClientManagerDeployRequest true "Deployment request"
|
||||
// @Success 202 {object} dto.ClientManagerInstallationResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Failure 403 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/server-instances/{id}/client-managers/deploy [post]
|
||||
func (h *coreHandlers) serverClientManagerDeploy(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.ClientManagerDeployRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
view, err := h.core.DeployClientManagerForSession(bearerToken(r), request.ToDomain(r.PathValue("id")))
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view))
|
||||
}
|
||||
|
||||
// serverClientManagerControl godoc
|
||||
// @Summary Control a deployed Client Manager
|
||||
// @Description Queues a declared typed start, stop, restart, status, or rollback operation.
|
||||
// @Tags client-managers
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Server instance ID"
|
||||
// @Param body body dto.ClientManagerControlRequest true "Control request"
|
||||
// @Success 202 {object} dto.ClientManagerInstallationResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Failure 403 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/server-instances/{id}/client-managers/control [post]
|
||||
func (h *coreHandlers) serverClientManagerControl(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.ClientManagerControlRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
view, err := h.core.ControlClientManagerForSession(bearerToken(r), request.ToDomain(r.PathValue("id")))
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view))
|
||||
}
|
||||
|
||||
// serverClientManagerUpdateLifecycle godoc
|
||||
// @Summary Update a Client Manager through staged activation
|
||||
// @Tags client-managers
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Server instance ID"
|
||||
// @Param body body dto.ClientManagerUpdateRequest true "Approved staged update request"
|
||||
// @Success 202 {object} dto.ClientManagerInstallationResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Failure 403 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/server-instances/{id}/client-managers/update [post]
|
||||
func (h *coreHandlers) serverClientManagerUpdateLifecycle(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.ClientManagerUpdateRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
view, err := h.core.UpdateClientManagerForSession(bearerToken(r), request.ToDomain(r.PathValue("id")))
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view))
|
||||
}
|
||||
|
||||
// serverClientManagerRetry godoc
|
||||
// @Summary Retry a failed Client Manager lifecycle intent
|
||||
// @Tags client-managers
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Server instance ID"
|
||||
// @Param body body dto.ClientManagerRetryRequest true "Retry request"
|
||||
// @Success 202 {object} dto.ClientManagerInstallationResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Failure 403 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/server-instances/{id}/client-managers/retry [post]
|
||||
func (h *coreHandlers) serverClientManagerRetry(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.ClientManagerRetryRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
view, err := h.core.RetryClientManagerLifecycleForSession(bearerToken(r), request.ToDomain(r.PathValue("id")))
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view))
|
||||
}
|
||||
|
||||
// serverClientManagerRevokeSession godoc
|
||||
// @Summary Revoke the active Client Manager component session
|
||||
// @Tags client-managers
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Server instance ID"
|
||||
// @Param body body dto.ClientManagerRevokeSessionRequest true "Session revoke request"
|
||||
// @Success 200 {object} dto.ClientManagerInstallationResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Failure 403 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/server-instances/{id}/client-managers/revoke-session [post]
|
||||
func (h *coreHandlers) serverClientManagerRevokeSession(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.ClientManagerRevokeSessionRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
view, err := h.core.RevokeClientManagerSessionForSession(bearerToken(r), request.ToDomain(r.PathValue("id")))
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, dto.ClientManagerLifecycleViewFromDomain(view))
|
||||
}
|
||||
|
||||
// serverClientManagerUninstall godoc
|
||||
// @Summary Safely uninstall a Client Manager
|
||||
// @Description Stops the supervised process and removes only the controlled installation workspace while retaining audit and distribution history.
|
||||
// @Tags client-managers
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Server instance ID"
|
||||
// @Param body body dto.ClientManagerUninstallRequest true "Confirmed uninstall request"
|
||||
// @Success 202 {object} dto.ClientManagerInstallationResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Failure 403 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/server-instances/{id}/client-managers/uninstall [post]
|
||||
func (h *coreHandlers) serverClientManagerUninstall(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.ClientManagerUninstallRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
view, err := h.core.UninstallClientManagerForSession(bearerToken(r), request.ToDomain(r.PathValue("id")))
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusAccepted, dto.ClientManagerLifecycleViewFromDomain(view))
|
||||
}
|
||||
|
||||
// runClientManagerLifecycleInput godoc
|
||||
// @Summary Get fenced Client Manager lifecycle input
|
||||
// @Description Returns a safe typed lifecycle contract only to the authenticated Run endpoint holding the active job lease.
|
||||
// @Tags run-job-channel
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body dto.ClientManagerLifecycleInputRequest true "Fenced lifecycle input request"
|
||||
// @Success 200 {object} dto.ClientManagerLifecycleInputResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/run/jobs/client-manager-input [post]
|
||||
func (h *coreHandlers) runClientManagerLifecycleInput(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.ClientManagerLifecycleInputRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
input, err := h.core.GetClientManagerLifecycleInput(request.ToDomain())
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, dto.ClientManagerLifecycleInputFromDomain(input))
|
||||
}
|
||||
|
||||
// runClientManagerLifecycleChunk godoc
|
||||
// @Summary Read one fenced Client Manager artifact chunk
|
||||
// @Description Streams a checksummed artifact chunk only to the active typed lifecycle job lease.
|
||||
// @Tags run-job-channel
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body dto.RunUpdateChunkRequest true "Fenced chunk request"
|
||||
// @Success 200 {object} dto.RunUpdateChunkResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/run/jobs/client-manager-chunk [post]
|
||||
func (h *coreHandlers) runClientManagerLifecycleChunk(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.RunUpdateChunkRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
chunk, err := h.core.ReadClientManagerLifecycleChunk(request.ToDomain())
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, dto.RunUpdateChunkFromDomain(chunk))
|
||||
}
|
||||
|
||||
// clientManagerRegister godoc
|
||||
// @Summary Register an installed Client Manager component
|
||||
// @Description Verifies a current component-key HMAC, nonce, deployment fence, target, revision, and capabilities before issuing an isolated expiring component session.
|
||||
// @Tags client-manager-component
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body dto.ClientManagerRegisterRequest true "Signed component registration"
|
||||
// @Success 200 {object} dto.ClientManagerRegisterResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/client-managers/register [post]
|
||||
func (h *coreHandlers) clientManagerRegister(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.ClientManagerRegisterRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
result, err := h.core.RegisterClientManager(request.ToDomain())
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, dto.ClientManagerRegisterFromDomain(result))
|
||||
}
|
||||
|
||||
// clientManagerHeartbeat godoc
|
||||
// @Summary Accept a Client Manager component heartbeat
|
||||
// @Description Accepts monotonic health reports using the isolated component session; Run control credentials are not valid here.
|
||||
// @Tags client-manager-component
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body dto.ClientManagerHeartbeatRequest true "Component heartbeat"
|
||||
// @Success 200 {object} dto.ClientManagerHeartbeatResponse
|
||||
// @Failure 400 {object} dto.ErrorResponse
|
||||
// @Failure 401 {object} dto.ErrorResponse
|
||||
// @Router /api/v1/client-managers/heartbeat [post]
|
||||
func (h *coreHandlers) clientManagerHeartbeat(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeMethodNotAllowed(w, http.MethodPost)
|
||||
return
|
||||
}
|
||||
request, err := decodeJSON[dto.ClientManagerHeartbeatRequest](r)
|
||||
if err != nil {
|
||||
writeDecodeError(w, err)
|
||||
return
|
||||
}
|
||||
result, err := h.core.AcceptClientManagerHeartbeat(request.ToDomain())
|
||||
if err != nil {
|
||||
writeServiceError(w, err)
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, dto.ClientManagerHeartbeatFromDomain(result))
|
||||
}
|
||||
Reference in New Issue
Block a user