diff --git a/pkg/core/disk.go b/pkg/core/disk.go index 8e7198a..4cba980 100644 --- a/pkg/core/disk.go +++ b/pkg/core/disk.go @@ -22,10 +22,10 @@ const ( ) type DiskCommand struct { - Action string - Size uint64 - Path string - FillByFallocate bool + Action string `json:"action"` + Size uint64 `json:"size"` + Path string `json:"path"` + FillByFallocate bool `json:"fill_by_fallocate"` } func (d *DiskCommand) Validate() error { diff --git a/pkg/server/chaosd/disk.go b/pkg/server/chaosd/disk.go index 4e76603..cf7bd42 100644 --- a/pkg/server/chaosd/disk.go +++ b/pkg/server/chaosd/disk.go @@ -167,3 +167,11 @@ func (s *Server) DiskFill(fill *core.DiskCommand) (uid string, err error) { return uid, err } + +func (s *Server) RecoverDiskAttack(uid string, attack *core.DiskCommand) error { + log.Info("Recover disk attack will do nothing, because delete | truncate data is too dangerous.") + if err := s.exp.Update(context.Background(), uid, core.Destroyed, "", attack.String()); err != nil { + return errors.WithStack(err) + } + return nil +} diff --git a/pkg/server/httpserver/server.go b/pkg/server/httpserver/server.go index 46288a7..abd5e90 100644 --- a/pkg/server/httpserver/server.go +++ b/pkg/server/httpserver/server.go @@ -14,6 +14,7 @@ package httpserver import ( + "fmt" "net/http" "github.com/gin-gonic/gin" @@ -78,6 +79,7 @@ func handler(s *httpServer) { attack.POST("/process", s.createProcessAttack) attack.POST("/stress", s.createStressAttack) attack.POST("/network", s.createNetworkAttack) + attack.POST("/disk", s.createDiskAttack) attack.DELETE("/:uid", s.recoverAttack) } @@ -158,6 +160,45 @@ func (s *httpServer) createStressAttack(c *gin.Context) { c.JSON(http.StatusOK, utils.AttackSuccessResponse(uid)) } +// @Summary Create disk attack. +// @Description Create disk attack. +// @Tags attack +// @Produce json +// @Param request body core.DiskCommand true "Request body" +// @Success 200 {object} utils.Response +// @Failure 400 {object} utils.APIError +// @Failure 500 {object} utils.APIError +// @Router /api/attack/disk [post] +func (s *httpServer) createDiskAttack(c *gin.Context) { + attack := &core.DiskCommand{} + if err := c.ShouldBindJSON(attack); err != nil { + c.AbortWithError(http.StatusBadRequest, utils.ErrInternalServer.WrapWithNoMessage(err)) + return + } + + var uid string + var err error + switch attack.Action { + case core.DiskFillAction: + uid, err = s.chaos.DiskFill(attack) + case core.DiskReadPayloadAction: + uid, err = s.chaos.DiskPayload(attack) + case core.DiskWritePayloadAction: + uid, err = s.chaos.DiskPayload(attack) + default: + c.AbortWithError(http.StatusBadRequest, + utils.ErrInvalidRequest.WrapWithNoMessage(fmt.Errorf("invalid disk attack action %v", attack.Action))) + return + } + + if err != nil { + _ = c.AbortWithError(http.StatusInternalServerError, utils.ErrInternalServer.WrapWithNoMessage(err)) + return + } + + c.JSON(http.StatusOK, utils.AttackSuccessResponse(uid)) +} + // @Summary Create recover attack. // @Description Create recover attack. // @Tags attack diff --git a/pkg/server/utils/recover.go b/pkg/server/utils/recover.go index 6c4477d..f824b4a 100644 --- a/pkg/server/utils/recover.go +++ b/pkg/server/utils/recover.go @@ -70,6 +70,15 @@ func RecoverExp(expStore core.ExperimentStore, chaos *chaosd.Server, uid string) if err := chaos.RecoverStressAttack(uid, scmd); err != nil { return err } + case core.DiskAttack: + scmd := &core.DiskCommand{} + if err := json.Unmarshal([]byte(exp.RecoverCommand), scmd); err != nil { + return err + } + + if err := chaos.RecoverDiskAttack(uid, scmd); err != nil { + return err + } default: return errors.Errorf("chaos experiment kind %s not found", exp.Kind) }