Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions .air.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ tmp_dir = "tmp"

[build]
# 构建命令
# 注意:Swagger 文档自动生成已禁用,请使用 make swagger 手动生成
pre_cmd = [
"echo '🔄 开始构建...'",
"echo '📄 检查 Swagger 文档生成设置...'",
"if [ \"${SWAGGER_ENABLED:-true}\" = \"false\" ]; then echo '⏭️ Swagger 文档生成已禁用,跳过生成'; else echo '📄 自动生成 Swagger 文档...'; go generate; echo '✅ Swagger 文档已自动更新'; fi"
"echo '📝 提示: 如需生成 Swagger 文档,请手动运行 make swagger'"
]

# 编译后的二进制文件名
Expand Down
78 changes: 18 additions & 60 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,13 @@ swagger-manual:
@echo "API文档已生成到 docs/ 目录"
@echo "访问地址: http://localhost:8889/swagger/index.html"

# 生成 Swagger API 文档(无需手动注释,同步到 docs.go)
# 生成 Swagger API 文档
swagger:
@echo "🚀 正在生成API文档..."
@echo "📄 使用生成工具生成文档..."
@bash scripts/generate-swagger.sh
@echo "✅ Swagger 文档生成完成!"

# 禁用 Swagger 生成(设置环境变量)
swagger-disable:
@echo "🔒 禁用 Swagger 文档生成..."
@export SWAGGER_ENABLED=false
@export SWAGGER_VERBOSE=false
@echo "✅ Swagger 生成已禁用"
@echo "💡 提示: 使用 'export SWAGGER_ENABLED=false' 永久禁用"

# 兼容旧的命令名
openai: swagger

Expand Down Expand Up @@ -83,33 +75,11 @@ swagger-clean:
@rm -f docs/docs.go docs/swagger.json docs/swagger.yaml
@echo "✅ 文档已清理"

# 完整的 Swagger 工作流(包含同步
# 完整的 Swagger 工作流(手动生成
swagger-all: swagger-clean swagger swagger-validate swagger-check
@echo "🎉 Swagger 文档生成并同步完成!"

# 安装 Git hooks 和同步机制
swagger-setup:
@echo "设置 Swagger 生成和同步..."
@bash scripts/setup-git-hooks.sh

# 启用监控模式(开发时使用)
swagger-watch:
@echo "⚠️ 监控功能已被禁用以防止循环生成问题"
@echo "💡 建议手动使用: make swagger"
@echo "🔧 如需启用监控,请联系开发者进行安全配置"

# 快速构建(包含 swagger 生成)
build-with-docs: swagger
@echo "构建项目(包含文档)..."
@go build -o bin/ai-cloudops main.go
@echo "✅ 构建完成,可执行文件: bin/ai-cloudops"

# 开发模式启动(生成文档)
dev-with-docs: swagger
@echo "开发模式启动(包含最新文档)..."
@go run main.go

# 检查并自动修复 Swagger 注解
@echo "🎉 Swagger 文档生成完成!"

# 检查并修复 Swagger 注解
swagger-fix:
@echo "检查并修复 Swagger 注解..."
@bash scripts/swagger-helper.sh fix
Expand All @@ -121,41 +91,29 @@ install-dev-tools:
@go install github.com/swaggo/swag/cmd/swag@latest
@echo "✅ 开发工具安装完成"

# 使用 Air 启动开发服务器(支持热重载和生成 Swagger)
# 使用 Air 启动开发服务器(不自动生成 Swagger)
dev-air:
@if ! command -v air &> /dev/null; then \
echo "❌ air 工具未安装,正在安装..."; \
go install github.com/air-verse/air@latest; \
fi
@echo "🚀 启动开发服务器 (Air + Swagger 生成)..."
@echo "🚀 启动开发服务器 (Air 热重载)..."
@echo "💡 提示: 如需生成文档,请手动运行 make swagger"
@air

# 检查文档同步状态
swagger-sync-check:
@echo "检查 Swagger 文档同步状态..."
@bash scripts/swagger-auto-sync.sh verify

# 手动同步文档
swagger-sync:
@echo "手动同步 Swagger 文档..."
@bash scripts/swagger-auto-sync.sh sync

# 强制重新同步文档
swagger-sync-force:
@echo "强制重新同步 Swagger 文档..."
@bash scripts/swagger-auto-sync.sh force

# 开发环境完整设置
dev-setup: swagger-setup install-dev-tools
# 开发环境设置(不包含自动生成功能)
dev-setup: install-dev-tools
@echo "🎉 开发环境设置完成!"
@echo ""
@echo "可用命令:"
@echo " make dev-air # 使用 Air 热重载启动"
@echo " make swagger-watch # 监控 Swagger 文档变化"
@echo " make swagger # 生成文档并同步"
@echo " make swagger-sync # 手动同步文档"
@echo " make swagger-sync-check # 检查同步状态"
@echo " go generate # 使用 Go generate 生成文档"
@echo " make swagger # 手动生成 Swagger 文档"
@echo " make swagger-manual # 使用传统方式生成"
@echo " make swagger-validate # 验证生成的文档"
@echo " make swagger-check # 检查注解完整性"
@echo " make swagger-clean # 清理生成的文档"
@echo ""
@echo "📝 注意: Swagger 文档需要手动生成"

docker-build:
docker build -t Bamboo/gomodd:v1.23.1 .
Expand All @@ -177,4 +135,4 @@ docker-net-remove:

dev: docker-build docker-start-env docker-start-server

stop: docker-stop-env docker-stop-server docker-net-remove
stop: docker-stop-env docker-stop-server docker-net-remove
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ require (
github.com/imdario/mergo v0.3.16
github.com/joho/godotenv v1.5.1
github.com/jonboulle/clockwork v0.5.0
github.com/mark3labs/mcp-go v0.25.0
github.com/openkruise/kruise-api v1.7.0
github.com/pkg/errors v0.9.1
github.com/prometheus/alertmanager v0.28.1
Expand Down Expand Up @@ -58,7 +57,6 @@ require (
github.com/go-redis/redis/v8 v8.11.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/robfig/cron/v3 v3.0.1
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
)

require (
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,6 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mark3labs/mcp-go v0.25.0 h1:UUpcMT3L5hIhuDy7aifj4Bphw4Pfx1Rf8mzMXDe8RQw=
github.com/mark3labs/mcp-go v0.25.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
Expand Down Expand Up @@ -675,8 +673,6 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
24 changes: 12 additions & 12 deletions internal/cron/executor/ssh_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ func NewSSHExecutor(logger *zap.Logger, treeLocalDAO dao.TreeLocalDAO) *SSHExecu
}

// ExecuteSSHJob 执行SSH任务
func (e *SSHExecutor) ExecuteSSHJob(ctx context.Context, job *model.CronJob) (string, error) {
func (s *SSHExecutor) ExecuteSSHJob(ctx context.Context, job *model.CronJob) (string, error) {
resourceID := 0
if job.SSHResourceID != nil {
resourceID = *job.SSHResourceID
}

e.logger.Info("开始执行SSH任务",
s.logger.Info("开始执行SSH任务",
zap.String("任务名称", job.Name),
zap.Int("资源ID", resourceID))

Expand All @@ -76,9 +76,9 @@ func (e *SSHExecutor) ExecuteSSHJob(ctx context.Context, job *model.CronJob) (st
}

// 获取SSH资源信息
resource, err := e.treeLocalDAO.GetByID(ctx, *job.SSHResourceID)
resource, err := s.treeLocalDAO.GetByID(ctx, *job.SSHResourceID)
if err != nil {
e.logger.Error("获取SSH资源失败",
s.logger.Error("获取SSH资源失败",
zap.Int("资源ID", *job.SSHResourceID),
zap.Error(err))
return "", fmt.Errorf("获取SSH资源失败: %w", err)
Expand All @@ -94,10 +94,10 @@ func (e *SSHExecutor) ExecuteSSHJob(ctx context.Context, job *model.CronJob) (st
}

// 创建SSH连接
sshClient := ssh.NewSSH(e.logger)
sshClient := ssh.NewSSH(s.logger)
defer func() {
if closeErr := sshClient.Close(); closeErr != nil {
e.logger.Error("关闭SSH连接失败", zap.Error(closeErr))
s.logger.Error("关闭SSH连接失败", zap.Error(closeErr))
}
}()

Expand All @@ -119,18 +119,18 @@ func (e *SSHExecutor) ExecuteSSHJob(ctx context.Context, job *model.CronJob) (st
0, // 系统任务使用用户ID 0
)
if err != nil {
e.logger.Error("SSH连接失败",
s.logger.Error("SSH连接失败",
zap.String("地址", resource.IpAddr),
zap.Int("端口", resource.Port),
zap.String("用户名", resource.Username),
zap.Error(err))
return "", fmt.Errorf("SSH连接失败: %w", err)
}

e.logger.Info("SSH连接成功", zap.String("地址", resource.IpAddr))
s.logger.Info("SSH连接成功", zap.String("地址", resource.IpAddr))

// 构建执行命令
command := e.buildSSHCommand(job)
command := s.buildSSHCommand(job)

// 设置超时控制
cmdCtx, cancel := context.WithTimeout(ctx, time.Duration(job.Timeout)*time.Second)
Expand All @@ -154,20 +154,20 @@ func (e *SSHExecutor) ExecuteSSHJob(ctx context.Context, job *model.CronJob) (st
case <-cmdCtx.Done():
return "", fmt.Errorf("SSH命令执行超时: %d秒", job.Timeout)
case err := <-errorCh:
e.logger.Error("SSH命令执行失败",
s.logger.Error("SSH命令执行失败",
zap.String("命令", command),
zap.Error(err))
return "", fmt.Errorf("SSH命令执行失败: %w", err)
case output := <-resultCh:
e.logger.Info("SSH命令执行成功",
s.logger.Info("SSH命令执行成功",
zap.String("命令", command),
zap.String("输出长度", fmt.Sprintf("%d字符", len(output))))
return output, nil
}
}

// buildSSHCommand 构建SSH执行命令
func (e *SSHExecutor) buildSSHCommand(job *model.CronJob) string {
func (s *SSHExecutor) buildSSHCommand(job *model.CronJob) string {
var commandParts []string

// 设置工作目录
Expand Down
26 changes: 13 additions & 13 deletions internal/cron/handler/executors.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ type CommandTask struct {
}

// Execute 执行命令,返回输出字符串
func (e *CommandExecutor) Execute(ctx context.Context, task *CommandTask) (string, error) {
func (h *CommandExecutor) Execute(ctx context.Context, task *CommandTask) (string, error) {
// 设置超时
timeout := time.Duration(task.Timeout) * time.Second
if timeout <= 0 {
Expand Down Expand Up @@ -103,7 +103,7 @@ func (e *CommandExecutor) Execute(ctx context.Context, task *CommandTask) (strin
cmd.Stdout = &stdout
cmd.Stderr = &stderr

e.logger.Info("执行命令",
h.logger.Info("执行命令",
zap.String("command", task.Command),
zap.Any("args", task.Args))

Expand All @@ -120,13 +120,13 @@ func (e *CommandExecutor) Execute(ctx context.Context, task *CommandTask) (strin
}

if err != nil {
e.logger.Error("命令执行失败",
h.logger.Error("命令执行失败",
zap.String("command", task.Command),
zap.Error(err))
return output, fmt.Errorf("命令执行失败: %w", err)
}

e.logger.Info("命令执行成功", zap.String("command", task.Command))
h.logger.Info("命令执行成功", zap.String("command", task.Command))
return output, nil
}

Expand Down Expand Up @@ -156,7 +156,7 @@ type HTTPTask struct {
}

// Execute 执行HTTP请求,返回响应字符串
func (e *HTTPExecutor) Execute(ctx context.Context, task *HTTPTask) (string, error) {
func (h *HTTPExecutor) Execute(ctx context.Context, task *HTTPTask) (string, error) {
// 设置超时
timeout := time.Duration(task.Timeout) * time.Second
if timeout <= 0 {
Expand All @@ -182,14 +182,14 @@ func (e *HTTPExecutor) Execute(ctx context.Context, task *HTTPTask) (string, err
req.Header.Set(header.Key, header.Value)
}

e.logger.Info("执行HTTP请求",
h.logger.Info("执行HTTP请求",
zap.String("method", task.Method),
zap.String("url", task.URL))

// 发送请求
resp, err := e.client.Do(req)
resp, err := h.client.Do(req)
if err != nil {
e.logger.Error("HTTP请求失败", zap.Error(err))
h.logger.Error("HTTP请求失败", zap.Error(err))
return "", fmt.Errorf("HTTP请求失败: %w", err)
}
defer resp.Body.Close()
Expand All @@ -202,7 +202,7 @@ func (e *HTTPExecutor) Execute(ctx context.Context, task *HTTPTask) (string, err

response := string(body)

e.logger.Info("HTTP请求完成",
h.logger.Info("HTTP请求完成",
zap.String("url", task.URL),
zap.Int("statusCode", resp.StatusCode))

Expand Down Expand Up @@ -234,7 +234,7 @@ type ScriptTask struct {
}

// Execute 执行脚本,返回输出字符串
func (e *ScriptExecutor) Execute(ctx context.Context, task *ScriptTask) (string, error) {
func (h *ScriptExecutor) Execute(ctx context.Context, task *ScriptTask) (string, error) {
// 设置超时
timeout := time.Duration(task.Timeout) * time.Second
if timeout <= 0 {
Expand Down Expand Up @@ -265,7 +265,7 @@ func (e *ScriptExecutor) Execute(ctx context.Context, task *ScriptTask) (string,
cmd.Stdout = &stdout
cmd.Stderr = &stderr

e.logger.Info("执行脚本",
h.logger.Info("执行脚本",
zap.String("type", task.Type),
zap.String("interpreter", interpreter))

Expand All @@ -282,12 +282,12 @@ func (e *ScriptExecutor) Execute(ctx context.Context, task *ScriptTask) (string,
}

if err != nil {
e.logger.Error("脚本执行失败",
h.logger.Error("脚本执行失败",
zap.String("type", task.Type),
zap.Error(err))
return output, fmt.Errorf("脚本执行失败: %w", err)
}

e.logger.Info("脚本执行成功", zap.String("type", task.Type))
h.logger.Info("脚本执行成功", zap.String("type", task.Type))
return output, nil
}
Loading