diff --git a/handlers/routes.go b/handlers/routes.go index 04dae630..47040c87 100644 --- a/handlers/routes.go +++ b/handlers/routes.go @@ -131,6 +131,7 @@ func Router() *mux.Router { // API SERVICE Routes api.Handle("/api/services", scoped(apiAllServicesHandler)).Methods("GET") + api.Handle("/api/services/status", authenticated(apiAllServicesStatusHandler, false)).Methods("GET") api.Handle("/api/services", authenticated(apiCreateServiceHandler, false)).Methods("POST") api.Handle("/api/services/{id}", authenticatedV2(apiServiceHandler)).Methods("GET") api.Handle("/api/services/{id}/sub_services", scoped(apiAllSubServicesHandler)).Methods("GET") diff --git a/handlers/services.go b/handlers/services.go index 2e67238b..e4640de4 100644 --- a/handlers/services.go +++ b/handlers/services.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/gorilla/mux" "github.com/statping/statping/database" + "github.com/statping/statping/types/downtimes" "github.com/statping/statping/types/errors" "github.com/statping/statping/types/failures" "github.com/statping/statping/types/hits" @@ -39,6 +40,19 @@ func findService(r *http.Request) (*services.Service, error) { return servicer, nil } +func findAllDowntimes(t string) []downtimes.Downtime { + timeVar := time.Now() + if t != "" { + var e error + timeVar, e = utils.ConvertToUnixTime(t) + if e != nil { + return nil + } + } + downTime := downtimes.FindDowntime(timeVar) + return downTime +} + func findPublicSubService(r *http.Request, service *services.Service) (*services.Service, error) { vars := mux.Vars(r) id := utils.ToInt(vars["sub_id"]) @@ -524,6 +538,29 @@ func apiAllServicesHandler(r *http.Request) interface{} { return srvs } +func apiAllServicesStatusHandler(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + var t string + if query.Get("time") != "" { + t = query.Get("time") + } + var srvs []services.ServiceWithDowntime + dtime := findAllDowntimes(t) + m := make(map[int64]downtimes.Downtime) + for i := 0; i < len(dtime); i += 1 { + m[dtime[i].ServiceId] = dtime[i] + } + for _, v := range services.AllInOrder() { + var serviceDowntimeVar services.ServiceWithDowntime + serviceDowntimeVar.Service = v + if vv, ok := m[v.Id]; ok == true { + serviceDowntimeVar.Downtime = &vv + } + srvs = append(srvs, serviceDowntimeVar) + } + sendJsonAction(srvs, "fetch", w, r) +} + func apiAllSubServicesHandler(r *http.Request) interface{} { var srvs []services.Service service, err := findService(r) diff --git a/types/downtimes/database.go b/types/downtimes/database.go index addcee4d..0c12c90e 100644 --- a/types/downtimes/database.go +++ b/types/downtimes/database.go @@ -3,6 +3,7 @@ package downtimes import ( "fmt" "github.com/statping/statping/database" + "github.com/statping/statping/utils" "strconv" "time" ) @@ -59,14 +60,11 @@ func FindByService(service int64, start time.Time, end time.Time) (*[]Downtime, return &downtime, q.Error() } -func ConvertToUnixTime(str string) (time.Time, error) { - i, err := strconv.ParseInt(str, 10, 64) - var t time.Time - if err != nil { - return t, err - } - tm := time.Unix(i, 0) - return tm, nil +func FindDowntime(timeVar time.Time) []Downtime { + var downtime []Downtime + q := db.Where("start <= ? and \"end\" >= ?", timeVar, timeVar) + q = q.Order("id ASC").Find(&downtime) + return downtime } func FindAll(vars map[string]string) (*[]Downtime, error) { @@ -78,11 +76,11 @@ func FindAll(vars map[string]string) (*[]Downtime, error) { startInt, err := strconv.ParseInt(st, 10, 64) endInt, err := strconv.ParseInt(en, 10, 64) if err1 && err2 && (endInt > startInt) { - start, err = ConvertToUnixTime(vars["start"]) + start, err = utils.ConvertToUnixTime(vars["start"]) if err != nil { return &downtime, err } - end, err = ConvertToUnixTime(vars["end"]) + end, err = utils.ConvertToUnixTime(vars["end"]) if err != nil { return &downtime, err } @@ -120,6 +118,7 @@ func FindAll(vars map[string]string) (*[]Downtime, error) { q = q.Limit((int)(count)).Offset((int)(skip)).Find(&downtime) return &downtime, q.Error() } + func (c *Downtime) Create() error { q := db.Create(c) return q.Error() diff --git a/types/services/struct.go b/types/services/struct.go index a6d99ce1..179a423b 100644 --- a/types/services/struct.go +++ b/types/services/struct.go @@ -4,6 +4,7 @@ import ( "database/sql/driver" "encoding/json" "github.com/statping/statping/types/checkins" + "github.com/statping/statping/types/downtimes" "github.com/statping/statping/types/failures" "github.com/statping/statping/types/incidents" "github.com/statping/statping/types/messages" @@ -11,6 +12,11 @@ import ( "time" ) +type ServiceWithDowntime struct { + Service + Downtime *downtimes.Downtime `gorm:"-" json:"downtime" yaml:"-"` +} + // Service is the main struct for Services type Service struct { Id int64 `gorm:"primary_key;column:id" json:"id" yaml:"id"` diff --git a/utils/utils.go b/utils/utils.go index 2b12480b..b802e341 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -29,6 +29,16 @@ func NotNumber(val string) bool { return err != nil } +func ConvertToUnixTime(str string) (time.Time, error) { + i, err := strconv.ParseInt(str, 10, 64) + var t time.Time + if err != nil { + return t, err + } + tm := time.Unix(i, 0) + return tm, nil +} + // ToInt converts a int to a string func ToInt(s interface{}) int64 { switch v := s.(type) {