示例#1
0
// 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
}
示例#2
0
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))
	}
}