Files
HellreigN/backend/internal/handlers/jobs.go
T
2026-04-04 17:33:36 +03:00

107 lines
3.2 KiB
Go

package handlers
import (
"fmt"
"log"
"net/http"
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/backend/internal/grpcsrv/commander"
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/backend/internal/models"
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/backend/internal/service"
"github.com/gin-gonic/gin"
)
type JobsHandlers struct {
cmder *commander.Commander
svc *service.ScriptService
}
func NewJobsHandlers(cmder *commander.Commander, svc *service.ScriptService) JobsHandlers {
return JobsHandlers{cmder: cmder, svc: svc}
}
type AddJobIn struct {
Command string `json:"command" binding:"required"`
InterpreterID int64 `json:"interpreter_id"`
Stdin *string `json:"stdin"`
AgentID string `json:"agent_id" binding:"required"`
}
type AddJobOut struct {
ID int64 `json:"id"`
Command []string `json:"command"`
Stdin *string `json:"stdin"`
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
Status int32 `json:"status"`
}
// AddJob creates and executes a job on a target agent.
// @Summary Create and run a job on an agent
// @Description Sends a command to the specified agent, waits for execution, and returns the result
// @Tags jobs
// @Accept json
// @Produce json
// @Param body body AddJobIn true "Job request"
// @Success 201 {object} AddJobOut
// @Router /jobs [post]
func (self *JobsHandlers) AddJob(c *gin.Context) {
log.Printf("[DEBUG] AddJob handler: request received")
err := func() error {
var in AddJobIn
if err := c.Bind(&in); err != nil {
log.Printf("[DEBUG] AddJob handler: bind failed: %v", err)
return err
}
log.Printf("[DEBUG] AddJob handler: agent_id=%s, command=%s, interpreter_id=%d", in.AgentID, in.Command, in.InterpreterID)
agent, ok := self.cmder.GetAgent(in.AgentID)
if !ok {
log.Printf("[DEBUG] AddJob handler: agent %s not found", in.AgentID)
c.Status(http.StatusNotFound)
return fmt.Errorf("agent not found")
}
log.Printf("[DEBUG] AddJob handler: agent found, resolving command")
var command []string
if in.InterpreterID == 0 {
command = []string{"sh", "-c", in.Command}
} else {
var err error
command, err = self.svc.ResolveCommand(c.Request.Context(), in.InterpreterID, in.Command)
if err != nil {
log.Printf("[DEBUG] AddJob handler: ResolveCommand failed: %v", err)
return err
}
}
log.Printf("[DEBUG] AddJob handler: calling agent.AddJob with command=%v", command)
jid, err := agent.AddJob(models.JobForInsert{
Command: command,
Stdin: in.Stdin,
})
if err != nil {
log.Printf("[DEBUG] AddJob handler: agent.AddJob failed: %v", err)
return err
}
log.Printf("[DEBUG] AddJob handler: agent.AddJob returned jid=%d, calling WaitJob", jid)
job, err := agent.WaitJob(jid)
if err != nil {
log.Printf("[DEBUG] AddJob handler: agent.WaitJob failed: %v", err)
return err
}
log.Printf("[DEBUG] AddJob handler: agent.WaitJob returned job id=%d, status=%d", job.ID, job.Status)
c.JSON(http.StatusCreated, AddJobOut{
ID: job.ID,
Command: job.Command,
Stdin: job.Stdin,
Stdout: job.Stdout,
Stderr: job.Stderr,
Status: job.Status,
})
log.Printf("[DEBUG] AddJob handler: response sent")
return nil
}()
if err != nil {
c.Error(err)
}
}