// IncrementState updates the ReaperState of a Resource // returns a boolean of whether it was updated func (a *Resource) IncrementState() (updated bool) { var newState state.StateEnum until := time.Now() switch a.reaperState.State { default: fallthrough case state.InitialState: // set state to the FirstState newState = state.FirstState until = until.Add(config.Notifications.FirstStateDuration.Duration) case state.FirstState: // go to SecondState at the end of FirstState newState = state.SecondState until = until.Add(config.Notifications.SecondStateDuration.Duration) case state.SecondState: // go to ThirdState at the end of SecondState newState = state.ThirdState until = until.Add(config.Notifications.ThirdStateDuration.Duration) case state.ThirdState: // go to FinalState at the end of ThirdState newState = state.FinalState case state.FinalState: // keep same state newState = state.FinalState case state.IgnoreState: // keep same state newState = state.IgnoreState } if newState != a.reaperState.State { updated = true a.reaperState = state.NewStateWithUntilAndState(until, newState) log.Info("Updating state for %s. New state: %s.", a.ReapableDescriptionTiny(), newState.String()) } return updated }
func processToken(h *HTTPApi) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, req *http.Request) { if err := req.ParseForm(); err != nil { writeResponse(w, http.StatusBadRequest, "Bad query string") return } userToken := req.Form.Get(h.conf.Token) if userToken == "" { writeResponse(w, http.StatusBadRequest, "Token Missing") return } if u, err := url.QueryUnescape(userToken); err == nil { userToken = u } else { writeResponse(w, http.StatusBadRequest, "Invalid Token, could not decode data") return } job, err := token.Untokenize(h.conf.TokenSecret, userToken) if err != nil { writeResponse(w, http.StatusBadRequest, "Invalid Token, Could not untokenize") return } if job.Expired() == true { writeResponse(w, http.StatusBadRequest, "Token expired") return } // find reapable associated with the job r, err := reapables.Get(reapable.Region(job.Region), reapable.ID(job.ID)) if err != nil { writeResponse(w, http.StatusInternalServerError, err.Error()) return } switch job.Action { case token.J_DELAY: log.Debug("Delay request received for %s in region %s until %s", job.ID, job.Region, job.IgnoreUntil.String()) s := r.ReaperState() ok, err := r.Save(state.NewStateWithUntilAndState(s.Until.Add(job.IgnoreUntil), s.State)) if err != nil { writeResponse(w, http.StatusInternalServerError, err.Error()) return } if !ok { writeResponse(w, http.StatusInternalServerError, fmt.Sprintf("Delay failed for %s.", r.ReapableDescriptionTiny())) return } reaperevents.NewEvent("Reaper: Delay Request Received", fmt.Sprintf("Delay for %s in region %s until %s", job.ID, job.Region, job.IgnoreUntil.String()), nil, []string{}, ) reaperevents.NewCountStatistic("reaper.reapables.requests", []string{"type:delay"}) case token.J_TERMINATE: log.Debug("Terminate request received for %s in region %s.", job.ID, job.Region) ok, err := r.Terminate() if err != nil { writeResponse(w, http.StatusInternalServerError, err.Error()) return } if !ok { writeResponse(w, http.StatusInternalServerError, fmt.Sprintf("Terminate failed for %s.", r.ReapableDescriptionTiny())) return } reaperevents.NewEvent("Reaper: Terminate Request Received", r.ReapableDescriptionShort(), nil, []string{}) reaperevents.NewCountStatistic("reaper.reapables.requests", []string{"type:terminate"}) case token.J_WHITELIST: log.Debug("Whitelist request received for %s in region %s", job.ID, job.Region) ok, err := r.Whitelist() if err != nil { writeResponse(w, http.StatusInternalServerError, err.Error()) return } if !ok { writeResponse(w, http.StatusInternalServerError, fmt.Sprintf("Whitelist failed for %s.", r.ReapableDescriptionTiny())) return } reaperevents.NewEvent("Reaper: Whitelist Request Received", r.ReapableDescriptionShort(), nil, []string{}) reaperevents.NewCountStatistic("reaper.reapables.requests", []string{"type:whitelist"}) case token.J_STOP: log.Debug("Stop request received for %s in region %s", job.ID, job.Region) ok, err := r.Stop() if err != nil { writeResponse(w, http.StatusInternalServerError, err.Error()) return } if !ok { writeResponse(w, http.StatusInternalServerError, fmt.Sprintf("Stop failed for %s.", r.ReapableDescriptionTiny())) return } reaperevents.NewEvent("Reaper: Stop Request Received", r.ReapableDescriptionShort(), nil, []string{}) reaperevents.NewCountStatistic("reaper.reapables.requests", []string{"type:stop"}) default: log.Error("Unrecognized job token received.") writeResponse(w, http.StatusInternalServerError, "Unrecognized job token.") return } var consoleURL *url.URL switch t := r.(type) { case *reaperaws.Instance: consoleURL = t.AWSConsoleURL() case *reaperaws.AutoScalingGroup: consoleURL = t.AWSConsoleURL() default: log.Error("No AWSConsoleURL") } writeResponse(w, http.StatusOK, fmt.Sprintf("Success. Check %s out on the <a href=\"%s\">AWS Console.</a>", r.ReapableDescriptionTiny(), consoleURL)) } }