feat(delivery): switch AWX delivery to callbacks
This commit is contained in:
@@ -19,42 +19,54 @@ func NewDeliveryHandler(s *service.DeliveryService) *DeliveryHandler {
|
||||
return &DeliveryHandler{service: s}
|
||||
}
|
||||
|
||||
type ExecutionHandler struct {
|
||||
type DeliveryCallbackHandler struct {
|
||||
service *service.DeliveryService
|
||||
token string
|
||||
}
|
||||
|
||||
func NewExecutionHandler(s *service.DeliveryService, token string) *ExecutionHandler {
|
||||
return &ExecutionHandler{service: s, token: strings.TrimSpace(token)}
|
||||
func NewDeliveryCallbackHandler(s *service.DeliveryService, token string) *DeliveryCallbackHandler {
|
||||
return &DeliveryCallbackHandler{service: s, token: strings.TrimSpace(token)}
|
||||
}
|
||||
|
||||
type executionPayload struct {
|
||||
TaskID string `json:"task_id" binding:"required"`
|
||||
PayloadHash string `json:"payload_hash" binding:"required"`
|
||||
IdempotencyKey string `json:"idempotency_key" binding:"required"`
|
||||
}
|
||||
|
||||
func (h *ExecutionHandler) Create(c *gin.Context) {
|
||||
provided := strings.TrimPrefix(c.GetHeader("Authorization"), "Bearer ")
|
||||
func (h *DeliveryCallbackHandler) authorize(c *gin.Context) bool {
|
||||
provided := strings.TrimSpace(strings.TrimPrefix(c.GetHeader("Authorization"), "Bearer "))
|
||||
if h.token == "" || subtle.ConstantTimeCompare([]byte(provided), []byte(h.token)) != 1 {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid service credential"})
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *DeliveryCallbackHandler) StageEvent(c *gin.Context) {
|
||||
if !h.authorize(c) {
|
||||
return
|
||||
}
|
||||
var req executionPayload
|
||||
var req service.DeliveryStageEventInput
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
job, replay, err := h.service.CreateExecution(c.Request.Context(), req.TaskID, req.PayloadHash, req.IdempotencyKey)
|
||||
if err != nil {
|
||||
if err := h.service.HandleStageEvent(c.Request.Context(), c.Param("id"), req); err != nil {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
status := http.StatusCreated
|
||||
if replay {
|
||||
status = http.StatusOK
|
||||
c.JSON(http.StatusAccepted, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
func (h *DeliveryCallbackHandler) AWXJobEvent(c *gin.Context) {
|
||||
if !h.authorize(c) {
|
||||
return
|
||||
}
|
||||
c.JSON(status, gin.H{"execution": job, "idempotent_replay": replay})
|
||||
var req service.AWXJobNotificationInput
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid AWX webhook JSON: " + err.Error()})
|
||||
return
|
||||
}
|
||||
if err := h.service.HandleAWXJobNotification(c.Request.Context(), req); err != nil {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusAccepted, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
// CreateMySQL 提交 MySQL 交付请求
|
||||
@@ -114,7 +126,11 @@ func (h *DeliveryHandler) List(c *gin.Context) {
|
||||
if raw := c.Query("business_line_id"); raw != "" {
|
||||
businessLineID, _ = strconv.ParseUint(raw, 10, 64)
|
||||
}
|
||||
items, err := h.service.ListTasks(c.Request.Context(), claims.UserID, claims.IsAdmin, businessLineID)
|
||||
items, err := h.service.ListTasks(c.Request.Context(), claims.UserID, claims.IsAdmin, service.DeliveryTaskListFilter{
|
||||
BusinessLineID: businessLineID,
|
||||
Component: c.Query("component"),
|
||||
ActiveOnly: strings.EqualFold(c.Query("active"), "true"),
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user