feat(delivery): expose rollback retry, release ack and CloudDM retry APIs
- POST /delivery/tasks/:id/rollback/retry (platform admin) re-launches the rollback job after a previous cleanup failure - POST /delivery/tasks/:id/rollback/release (platform admin) releases bookkeeping after the operator verified the target host manually - POST /delivery/tasks/:id/clouddm/retry retries only the CloudDM registration step for an already healthy instance - task logs now include rollback AWX job stdout and localized text/classes for the new rollback states
This commit is contained in:
@@ -175,6 +175,55 @@ func (h *DeliveryHandler) Cancel(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
// RetryRollback retries the compensating AWX job after a previous cleanup failure.
|
||||
func (h *DeliveryHandler) RetryRollback(c *gin.Context) {
|
||||
if !requirePlatformAdmin(c) {
|
||||
return
|
||||
}
|
||||
if err := h.service.RetryRollback(c.Request.Context(), c.Param("id")); err != nil {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusAccepted, gin.H{"ok": true, "status": model.TaskRollbackPending})
|
||||
}
|
||||
|
||||
// AcknowledgeRollbackRelease releases bookkeeping after an administrator has
|
||||
// independently verified that no instance artifacts remain on the target host.
|
||||
func (h *DeliveryHandler) AcknowledgeRollbackRelease(c *gin.Context) {
|
||||
if !requirePlatformAdmin(c) {
|
||||
return
|
||||
}
|
||||
if err := h.service.AcknowledgeRollbackRelease(c.Request.Context(), c.Param("id")); err != nil {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true, "status": model.TaskRollbackAck})
|
||||
}
|
||||
|
||||
// RetryCloudDMRegistration retries only the CloudDM registration step for an
|
||||
// already healthy and accounted-for MySQL instance.
|
||||
func (h *DeliveryHandler) RetryCloudDMRegistration(c *gin.Context) {
|
||||
claims, ok := CurrentClaims(c)
|
||||
if !ok {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "missing current user"})
|
||||
return
|
||||
}
|
||||
taskID := c.Param("id")
|
||||
if _, _, err := h.service.GetTask(c.Request.Context(), taskID, claims.UserID, claims.IsAdmin); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "task not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if err := h.service.RetryCloudDMRegistration(c.Request.Context(), taskID); err != nil {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusAccepted, gin.H{"ok": true, "status": model.TaskFinished})
|
||||
}
|
||||
|
||||
// Targets 获取可用部署目标
|
||||
// @Summary 获取可用部署目标
|
||||
// @Description 从 AWX 动态返回可用 Job Template 及其 Inventory hosts
|
||||
|
||||
Reference in New Issue
Block a user