mirror of https://github.com/statping/statping
237 lines
5.7 KiB
Go
237 lines
5.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/gorilla/mux"
|
|
"github.com/razorpay/statping/types/downtimes"
|
|
"github.com/razorpay/statping/types/services"
|
|
"github.com/razorpay/statping/utils"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
)
|
|
|
|
func findDowntime(r *http.Request) (*downtimes.Downtime, error) {
|
|
vars := mux.Vars(r)
|
|
id := utils.ToInt(vars["id"])
|
|
downtime, err := downtimes.Find(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return downtime, nil
|
|
}
|
|
|
|
func convertToMap(query url.Values) map[string]string {
|
|
vars := make(map[string]string)
|
|
if query.Get("start") != "" {
|
|
vars["start"] = query.Get("start")
|
|
}
|
|
if query.Get("end") != "" {
|
|
vars["end"] = query.Get("end")
|
|
}
|
|
if query.Get("sub_status") != "" {
|
|
vars["sub_status"] = query.Get("sub_status")
|
|
}
|
|
if query.Get("service_id") != "" {
|
|
vars["service_id"] = query.Get("service_id")
|
|
}
|
|
if query.Get("type") != "" {
|
|
vars["type"] = query.Get("type")
|
|
}
|
|
if query.Get("skip") != "" {
|
|
vars["skip"] = query.Get("skip")
|
|
}
|
|
if query.Get("count") != "" {
|
|
vars["count"] = query.Get("count")
|
|
}
|
|
return vars
|
|
}
|
|
|
|
type DowntimeService struct {
|
|
Id int64 `gorm:"primary_key;column:id" json:"id"`
|
|
Service *services.Service `gorm:"foreignKey:service" json:"service"`
|
|
ServiceId int64 `gorm:"index;column:service" json:"service_id"`
|
|
SubStatus string `gorm:"column:sub_status" json:"sub_status"`
|
|
Failures int `gorm:"column:failures" json:"failures"`
|
|
Start *time.Time `gorm:"index;column:start" json:"start"`
|
|
End *time.Time `gorm:"column:end" json:"end"`
|
|
Type string `gorm:"default:'auto';column:type" json:"type"`
|
|
}
|
|
|
|
func apiAllDowntimes(w http.ResponseWriter, r *http.Request) {
|
|
query := r.URL.Query()
|
|
vars := convertToMap(query)
|
|
downtime, err := downtimes.FindAll(vars)
|
|
var downtimeWithService []DowntimeService
|
|
servicesMap := services.All()
|
|
if downtime == nil {
|
|
sendJsonAction(downtimeWithService, "fetch", w, r)
|
|
return
|
|
}
|
|
for _, dtime := range *downtime {
|
|
var downtimeWithServiceVar DowntimeService
|
|
downtimeWithServiceVar.Id = dtime.Id
|
|
downtimeWithServiceVar.ServiceId = dtime.ServiceId
|
|
downtimeWithServiceVar.SubStatus = dtime.SubStatus
|
|
downtimeWithServiceVar.Failures = dtime.Failures
|
|
downtimeWithServiceVar.Start = dtime.Start
|
|
downtimeWithServiceVar.End = dtime.End
|
|
downtimeWithServiceVar.Type = dtime.Type
|
|
downtimeWithServiceVar.Service = servicesMap[dtime.ServiceId]
|
|
downtimeWithService = append(downtimeWithService, downtimeWithServiceVar)
|
|
}
|
|
if err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
sendJsonAction(downtimeWithService, "fetch", w, r)
|
|
}
|
|
|
|
func apiAllDowntimesForServiceHandler(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
serviceId := utils.ToInt(vars["service_id"])
|
|
ninetyDaysAgo := time.Now().Add(time.Duration(-90*24) * time.Hour)
|
|
|
|
downtime, err := downtimes.FindByServiceAndDuration(serviceId, ninetyDaysAgo, time.Now())
|
|
if err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
sendJsonAction(downtime, "fetch", w, r)
|
|
}
|
|
|
|
func apiCreateDowntimeHandler(w http.ResponseWriter, r *http.Request) {
|
|
var downtime *downtimes.Downtime
|
|
if err := DecodeJSON(r, &downtime); err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
|
|
if downtime.CheckOverlapping() {
|
|
err := fmt.Errorf("downtime interval overlapping error")
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
|
|
s, err := services.FindFirstFromDB(downtime.ServiceId)
|
|
if err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
|
|
downtime.Type = "manual"
|
|
downtime.Id = zeroInt64
|
|
|
|
if err := downtime.Create(); err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
|
|
if downtime.End == nil {
|
|
updateFields := map[string]interface{}{
|
|
"online": false,
|
|
"current_downtime": downtime.Id,
|
|
"manual_downtime": true,
|
|
}
|
|
|
|
if err := s.UpdateSpecificFields(updateFields); err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
}
|
|
|
|
sendJsonAction(downtime, "create", w, r)
|
|
}
|
|
|
|
func apiDowntimeHandler(w http.ResponseWriter, r *http.Request) {
|
|
downtime, err := findDowntime(r)
|
|
if downtime == nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
sendJsonAction(downtime, "fetch", w, r)
|
|
}
|
|
|
|
func apiPatchDowntimeHandler(w http.ResponseWriter, r *http.Request) {
|
|
downtime, err := findDowntime(r)
|
|
if err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
var req downtimes.Downtime
|
|
if err := DecodeJSON(r, &req); err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
|
|
s, err := services.FindFirstFromDB(downtime.ServiceId)
|
|
if err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
|
|
if downtime.End != nil && req.End == nil {
|
|
fmt.Errorf("Cannot reopen a downtime!")
|
|
}
|
|
|
|
if downtime.End == nil && req.End != nil {
|
|
updateFields := map[string]interface{}{
|
|
"online": true,
|
|
"failure_counter": 0,
|
|
"current_downtime": 0,
|
|
"manual_downtime": false,
|
|
}
|
|
|
|
if err := s.UpdateSpecificFields(updateFields); err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
}
|
|
|
|
downtime.Start = req.Start
|
|
downtime.End = req.End
|
|
downtime.Type = "manual"
|
|
downtime.Failures = req.Failures
|
|
downtime.SubStatus = req.SubStatus
|
|
|
|
if err := downtime.Update(); err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
|
|
sendJsonAction(downtime, "update", w, r)
|
|
}
|
|
|
|
func apiDeleteDowntimeHandler(w http.ResponseWriter, r *http.Request) {
|
|
downtime, err := findDowntime(r)
|
|
if err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
if downtime.End == nil {
|
|
s2, err := services.FindFirstFromDB(downtime.ServiceId)
|
|
if err != nil {
|
|
fmt.Errorf("Error updating service")
|
|
}
|
|
s2.LastProcessingTime = zeroTime
|
|
s2.Online = true
|
|
s2.FailureCounter = 0
|
|
s2.CurrentDowntime = 0
|
|
s2.ManualDowntime = false
|
|
|
|
if err := s2.Update(); err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
}
|
|
|
|
err = downtime.Delete()
|
|
if err != nil {
|
|
sendErrorJson(err, w, r)
|
|
return
|
|
}
|
|
|
|
sendJsonAction(downtime, "delete", w, r)
|
|
}
|