105 lines
3.1 KiB
Go
105 lines
3.1 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"git.pcux.cn/xuans/Scert/backend/internal/domain"
|
|
)
|
|
|
|
const maxSSHKeyRequestBytes = 2 * 1024 * 1024
|
|
|
|
type sshKeyRequest struct {
|
|
Name string `json:"name" binding:"required"`
|
|
PrivateKey string `json:"private_key" binding:"required"`
|
|
Passphrase string `json:"passphrase"`
|
|
ProjectID string `json:"project_id"`
|
|
}
|
|
|
|
func (s *Server) listSSHKeys(c *gin.Context) {
|
|
if s.sshKeys == nil {
|
|
s.writeError(c, http.StatusNotImplemented, "SSH 私钥管理接口尚未配置", errors.New("SSH 私钥管理服务未配置"))
|
|
return
|
|
}
|
|
projectID := strings.TrimSpace(c.Query("project_id"))
|
|
if projectID == "" {
|
|
projectID = domain.DefaultProjectID
|
|
}
|
|
if !s.authorizeServerMutation(c, projectID) {
|
|
return
|
|
}
|
|
items, err := s.sshKeys.ListForProject(c.Request.Context(), projectID)
|
|
if err != nil {
|
|
s.writeError(c, http.StatusInternalServerError, "查询 SSH 私钥失败", err)
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"items": items})
|
|
}
|
|
|
|
func (s *Server) createSSHKey(c *gin.Context) {
|
|
if s.sshKeys == nil {
|
|
s.writeError(c, http.StatusNotImplemented, "SSH 私钥管理接口尚未配置", errors.New("SSH 私钥管理服务未配置"))
|
|
return
|
|
}
|
|
var request sshKeyRequest
|
|
if err := bindJSON(c, &request, maxSSHKeyRequestBytes); err != nil {
|
|
var tooLarge *http.MaxBytesError
|
|
if errors.As(err, &tooLarge) {
|
|
s.writeError(c, http.StatusRequestEntityTooLarge, "SSH 私钥请求内容过大", err)
|
|
return
|
|
}
|
|
s.writeError(c, http.StatusBadRequest, "请求参数无效", err)
|
|
return
|
|
}
|
|
projectID := strings.TrimSpace(request.ProjectID)
|
|
if projectID == "" {
|
|
projectID = domain.DefaultProjectID
|
|
}
|
|
if !s.authorizeServerMutation(c, projectID) {
|
|
return
|
|
}
|
|
item, err := s.sshKeys.CreateForProject(c.Request.Context(), request.Name, request.PrivateKey, request.Passphrase, projectID)
|
|
if err != nil {
|
|
s.writeError(c, http.StatusBadRequest, "SSH 私钥无效", err)
|
|
return
|
|
}
|
|
c.JSON(http.StatusCreated, item)
|
|
}
|
|
|
|
func (s *Server) deleteSSHKey(c *gin.Context) {
|
|
if s.sshKeys == nil || s.servers == nil {
|
|
s.writeError(c, http.StatusNotImplemented, "SSH 私钥管理接口尚未配置", errors.New("SSH 私钥或服务器管理服务未配置"))
|
|
return
|
|
}
|
|
reference, err := s.sshKeys.Reference(c.Param("id"))
|
|
if err != nil {
|
|
s.writeError(c, http.StatusBadRequest, "SSH 私钥 ID 无效", err)
|
|
return
|
|
}
|
|
metadata, err := s.sshKeys.ValidateReference(c.Request.Context(), reference)
|
|
if err != nil {
|
|
s.writeError(c, http.StatusBadRequest, "SSH 私钥引用无效", err)
|
|
return
|
|
}
|
|
if !s.authorizeServerMutation(c, metadata.ProjectID) {
|
|
return
|
|
}
|
|
used, err := s.servers.IsPrivateKeyRefUsed(c.Request.Context(), reference)
|
|
if err != nil {
|
|
s.writeError(c, http.StatusInternalServerError, "检查 SSH 私钥占用状态失败", err)
|
|
return
|
|
}
|
|
if used {
|
|
s.writeError(c, http.StatusConflict, "SSH 私钥仍被部署服务器使用", errors.New("SSH 私钥引用正在使用"))
|
|
return
|
|
}
|
|
if err := s.sshKeys.Delete(c.Request.Context(), c.Param("id")); err != nil {
|
|
s.writeError(c, http.StatusNotFound, "SSH 私钥不存在", err)
|
|
return
|
|
}
|
|
c.Status(http.StatusNoContent)
|
|
}
|