390 lines
11 KiB
Go
390 lines
11 KiB
Go
package controllers
|
|
|
|
import (
|
|
"github.com/engigu/baihu-panel/internal/constant"
|
|
"github.com/engigu/baihu-panel/internal/database"
|
|
"github.com/engigu/baihu-panel/internal/models"
|
|
"github.com/engigu/baihu-panel/internal/models/vo"
|
|
"github.com/engigu/baihu-panel/internal/services"
|
|
"github.com/engigu/baihu-panel/internal/services/relation"
|
|
"github.com/engigu/baihu-panel/internal/utils"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type EnvController struct {
|
|
envService *services.EnvService
|
|
}
|
|
|
|
func NewEnvController(envService *services.EnvService) *EnvController {
|
|
return &EnvController{envService: envService}
|
|
}
|
|
|
|
// GetSecretStatus 获取加密秘钥状态
|
|
// @Summary 获取加密秘钥状态
|
|
// @Description 返回系统是否已配置加密秘钥
|
|
// @Tags Env
|
|
// @Produce json
|
|
// @Success 200 {object} utils.Response{data=bool} "成功"
|
|
// @Router /env/secret-status [get]
|
|
// @Security BearerAuth
|
|
func (ec *EnvController) GetSecretStatus(c *gin.Context) {
|
|
utils.Success(c, utils.IsSecretKeySet())
|
|
}
|
|
|
|
// CreateEnvVar 创建环境变量
|
|
// @Summary 创建环境变量
|
|
// @Description 创建一个新的环境变量
|
|
// @Tags 环境变量
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param body body object true "环境变量信息"
|
|
// @Success 200 {object} utils.Response{data=vo.EnvVO}
|
|
// @Router /env [post]
|
|
func (ec *EnvController) CreateEnvVar(c *gin.Context) {
|
|
userID := c.GetString("userID")
|
|
|
|
var req struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Value string `json:"value" binding:"required"`
|
|
Remark string `json:"remark"`
|
|
Type string `json:"type"`
|
|
Hidden *bool `json:"hidden"`
|
|
Enabled *bool `json:"enabled"`
|
|
Tags string `json:"tags"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
utils.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
|
|
if req.Type == "" {
|
|
req.Type = constant.EnvTypeNormal
|
|
}
|
|
|
|
hidden := true
|
|
if req.Hidden != nil {
|
|
hidden = *req.Hidden
|
|
}
|
|
|
|
enabled := true
|
|
if req.Enabled != nil {
|
|
enabled = *req.Enabled
|
|
}
|
|
|
|
envVar := ec.envService.CreateEnvVar(req.Name, req.Value, req.Remark, req.Type, hidden, enabled, userID)
|
|
if envVar != nil {
|
|
relation.DataRelation.SaveTags(envVar.ID, constant.RelationTypeEnvTag, req.Tags)
|
|
envVar.Tags = req.Tags
|
|
}
|
|
|
|
// Broadcast tasks to all agents because global envs changed
|
|
services.GetAgentWSManager().BroadcastTasksToAll()
|
|
|
|
utils.Success(c, vo.ToEnvVO(envVar))
|
|
}
|
|
|
|
// GetEnvVars 获取环境变量列表
|
|
// @Summary 获取环境变量列表
|
|
// @Description 分页获取环境变量列表,支持按名称筛选
|
|
// @Tags 环境变量
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param name query string false "按名称模糊查询"
|
|
// @Param page query int false "页码"
|
|
// @Param page_size query int false "每页数量"
|
|
// @Param type query string false "按类型筛选"
|
|
// @Param tags query string false "按标签筛选"
|
|
// @Success 200 {object} utils.Response{data=utils.PaginationData{data=[]vo.EnvVO}}
|
|
// @Router /env [get]
|
|
func (ec *EnvController) GetEnvVars(c *gin.Context) {
|
|
userID := c.GetString("userID")
|
|
p := utils.ParsePagination(c)
|
|
name := c.DefaultQuery("name", "")
|
|
envType := c.DefaultQuery("type", "")
|
|
tags := c.DefaultQuery("tags", "")
|
|
envVars, total := ec.envService.GetEnvVarsWithPagination(userID, name, envType, tags, p.Page, p.PageSize)
|
|
utils.PaginatedResponse(c, vo.ToEnvVOListFromModels(envVars), total, p)
|
|
}
|
|
|
|
// GetAllEnvVars 获取所有环境变量
|
|
// @Summary 获取所有环境变量
|
|
// @Description 获取当前用户的所有环境变量(不分页)
|
|
// @Tags 环境变量
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Success 200 {object} utils.Response{data=[]vo.EnvVO}
|
|
// @Router /env/all [get]
|
|
func (ec *EnvController) GetAllEnvVars(c *gin.Context) {
|
|
userID := c.GetString("userID")
|
|
envVars := ec.envService.GetEnvVarsByUserID(userID)
|
|
utils.Success(c, vo.ToEnvVOListFromModels(envVars))
|
|
}
|
|
|
|
// GetEnvVar 获取环境变量详情
|
|
// @Summary 获取环境变量详情
|
|
// @Description 根据 ID 获取环境变量详情
|
|
// @Tags 环境变量
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param id path string true "环境变量ID"
|
|
// @Success 200 {object} utils.Response{data=vo.EnvVO}
|
|
// @Failure 404 {object} utils.Response
|
|
// @Router /env/{id} [get]
|
|
func (ec *EnvController) GetEnvVar(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
utils.BadRequest(c, "无效的环境变量ID")
|
|
return
|
|
}
|
|
|
|
envVar := ec.envService.GetEnvVarByID(id)
|
|
if envVar == nil {
|
|
utils.NotFound(c, "环境变量不存在")
|
|
return
|
|
}
|
|
|
|
utils.Success(c, vo.ToEnvVO(envVar))
|
|
}
|
|
|
|
// UpdateEnvVar 更新环境变量
|
|
// @Summary 更新环境变量
|
|
// @Description 根据 ID 更新环境变量信息
|
|
// @Tags 环境变量
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param id path string true "环境变量ID"
|
|
// @Param body body object true "环境变量更新信息"
|
|
// @Success 200 {object} utils.Response{data=vo.EnvVO}
|
|
// @Failure 404 {object} utils.Response
|
|
// @Router /env/{id} [put]
|
|
func (ec *EnvController) UpdateEnvVar(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
utils.BadRequest(c, "无效的环境变量ID")
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
Name string `json:"name"`
|
|
Value string `json:"value"`
|
|
Remark string `json:"remark"`
|
|
Type string `json:"type"`
|
|
Hidden *bool `json:"hidden"`
|
|
Enabled *bool `json:"enabled"`
|
|
Tags string `json:"tags"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
utils.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
|
|
if req.Type == "" {
|
|
req.Type = constant.EnvTypeNormal
|
|
}
|
|
|
|
// 对于更新,获取现有数据
|
|
existing := ec.envService.GetEnvVarByID(id)
|
|
if existing == nil {
|
|
utils.NotFound(c, "环境变量不存在")
|
|
return
|
|
}
|
|
|
|
hidden := existing.Hidden
|
|
if req.Hidden != nil {
|
|
hidden = req.Hidden
|
|
}
|
|
|
|
enabled := existing.Enabled
|
|
if req.Enabled != nil {
|
|
enabled = req.Enabled
|
|
}
|
|
|
|
envVar := ec.envService.UpdateEnvVar(id, req.Name, req.Value, req.Remark, req.Type, utils.DerefBool(hidden, true), utils.DerefBool(enabled, true))
|
|
if envVar == nil {
|
|
utils.NotFound(c, "环境变量不存在")
|
|
return
|
|
}
|
|
|
|
relation.DataRelation.SaveTags(envVar.ID, constant.RelationTypeEnvTag, req.Tags)
|
|
envVar.Tags = req.Tags
|
|
|
|
// Broadcast tasks to all agents because global envs changed
|
|
services.GetAgentWSManager().BroadcastTasksToAll()
|
|
|
|
utils.Success(c, vo.ToEnvVO(envVar))
|
|
}
|
|
|
|
// DeleteEnvVar 删除环境变量
|
|
// @Summary 删除环境变量
|
|
// @Description 根据 ID 删除环境变量
|
|
// @Tags 环境变量
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param id path string true "环境变量ID"
|
|
// @Param force query boolean false "强制删除(忽略任务关联)"
|
|
// @Success 200 {object} utils.Response
|
|
// @Failure 404 {object} utils.Response
|
|
// @Failure 409 {object} utils.Response{data=[]vo.TaskVO}
|
|
// @Router /env/{id} [delete]
|
|
func (ec *EnvController) DeleteEnvVar(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
utils.BadRequest(c, "无效的环境变量ID")
|
|
return
|
|
}
|
|
|
|
force := c.Query("force") == "true"
|
|
success, associatedTasks := ec.envService.DeleteEnvVar(id, force)
|
|
|
|
if len(associatedTasks) > 0 {
|
|
c.JSON(200, utils.Response{
|
|
Code: 409,
|
|
Msg: "该环境变量已被任务引用,请先在任务中删除引用或选择强制删除",
|
|
Data: vo.ToTaskVOListFromModels(associatedTasks),
|
|
})
|
|
return
|
|
}
|
|
|
|
if !success {
|
|
utils.NotFound(c, "环境变量不存在或删除失败")
|
|
return
|
|
}
|
|
|
|
// Broadcast tasks to all agents because global envs changed
|
|
services.GetAgentWSManager().BroadcastTasksToAll()
|
|
|
|
utils.SuccessMsg(c, "删除成功")
|
|
}
|
|
|
|
// GetAssociatedTasks 获取关联任务
|
|
// @Summary 获取关联任务
|
|
// @Description 获取引用了该环境变量的任务列表
|
|
// @Tags 环境变量
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param id path string true "环境变量ID"
|
|
// @Success 200 {object} utils.Response{data=[]vo.TaskVO}
|
|
// @Router /env/{id}/tasks [get]
|
|
func (ec *EnvController) GetAssociatedTasks(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if id == "" {
|
|
utils.BadRequest(c, "无效的环境变量ID")
|
|
return
|
|
}
|
|
tasks := ec.envService.GetAssociatedTasks(id)
|
|
utils.Success(c, vo.ToTaskVOListFromModels(tasks))
|
|
}
|
|
|
|
// GetTags 获取所有环境变量标签
|
|
// @Summary 获取所有环境变量标签
|
|
// @Description 获取所有环境变量中使用的标签列表
|
|
// @Tags 环境变量
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Success 200 {object} utils.Response{data=[]string}
|
|
// @Router /env/tags [get]
|
|
func (ec *EnvController) GetTags(c *gin.Context) {
|
|
tags, err := ec.envService.GetAllEnvTags()
|
|
if err != nil {
|
|
utils.ServerError(c, "获取标签失败")
|
|
return
|
|
}
|
|
utils.Success(c, tags)
|
|
}
|
|
|
|
// BulkSaveEnv 批量保存环境变量
|
|
func (ec *EnvController) BulkSaveEnv(c *gin.Context) {
|
|
var reqs []struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name" binding:"required"`
|
|
Value string `json:"value" binding:"required"`
|
|
Remark string `json:"remark"`
|
|
Type string `json:"type"`
|
|
Hidden *bool `json:"hidden"`
|
|
Enabled *bool `json:"enabled"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&reqs); err != nil {
|
|
utils.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
|
|
userID := c.GetString("userID")
|
|
|
|
for _, req := range reqs {
|
|
if req.Type == constant.EnvTypeSecret {
|
|
continue // 二次严苛拦截,机密变量不应下发/保存
|
|
}
|
|
|
|
hidden := true
|
|
if req.Hidden != nil {
|
|
hidden = *req.Hidden
|
|
}
|
|
enabled := true
|
|
if req.Enabled != nil {
|
|
enabled = *req.Enabled
|
|
}
|
|
|
|
var existingEnv *models.EnvironmentVariable
|
|
// 优先按 ID 匹配
|
|
if req.ID != "" {
|
|
var e models.EnvironmentVariable
|
|
if err := database.DB.Where("id = ?", req.ID).First(&e).Error; err == nil {
|
|
existingEnv = &e
|
|
}
|
|
}
|
|
// 如果 ID 没找到,按 Name 匹配
|
|
if existingEnv == nil {
|
|
var e models.EnvironmentVariable
|
|
if err := database.DB.Where("name = ?", req.Name).First(&e).Error; err == nil {
|
|
existingEnv = &e
|
|
}
|
|
}
|
|
|
|
if existingEnv != nil {
|
|
existingEnv.Name = req.Name
|
|
existingEnv.Value = models.BigText(req.Value)
|
|
existingEnv.Remark = req.Remark
|
|
existingEnv.Type = req.Type
|
|
existingEnv.Hidden = &hidden
|
|
existingEnv.Enabled = &enabled
|
|
database.DB.Save(existingEnv)
|
|
|
|
if req.ID != "" && existingEnv.ID != req.ID {
|
|
database.DB.Model(existingEnv).Update("id", req.ID)
|
|
}
|
|
} else {
|
|
envVar := &models.EnvironmentVariable{
|
|
ID: req.ID,
|
|
Name: req.Name,
|
|
Value: models.BigText(req.Value),
|
|
Remark: req.Remark,
|
|
Type: req.Type,
|
|
Hidden: &hidden,
|
|
Enabled: &enabled,
|
|
UserID: userID,
|
|
CreatedAt: models.Now(),
|
|
UpdatedAt: models.Now(),
|
|
}
|
|
if envVar.ID == "" {
|
|
envVar.ID = utils.GenerateID()
|
|
}
|
|
database.DB.Create(envVar)
|
|
}
|
|
}
|
|
|
|
services.GetAgentWSManager().BroadcastTasksToAll()
|
|
utils.Success(c, nil)
|
|
}
|