mirror of
https://github.com/semaphoreui/semaphore.git
synced 2024-12-03 14:51:05 +01:00
228 lines
5.7 KiB
Go
228 lines
5.7 KiB
Go
package projects
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/semaphoreui/semaphore/api/helpers"
|
|
"github.com/semaphoreui/semaphore/db"
|
|
"github.com/semaphoreui/semaphore/services/schedules"
|
|
"github.com/gorilla/context"
|
|
)
|
|
|
|
// SchedulesMiddleware ensures a template exists and loads it to the context
|
|
func SchedulesMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
project := context.Get(r, "project").(db.Project)
|
|
scheduleID, err := helpers.GetIntParam("schedule_id", w, r)
|
|
if err != nil { // not specified schedule_id
|
|
return
|
|
}
|
|
|
|
schedule, err := helpers.Store(r).GetSchedule(project.ID, scheduleID)
|
|
|
|
if err != nil {
|
|
helpers.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
context.Set(r, "schedule", schedule)
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
func refreshSchedulePool(r *http.Request) {
|
|
pool := context.Get(r, "schedule_pool").(schedules.SchedulePool)
|
|
pool.Refresh()
|
|
}
|
|
|
|
// GetSchedule returns single template by ID
|
|
func GetSchedule(w http.ResponseWriter, r *http.Request) {
|
|
schedule := context.Get(r, "schedule").(db.Schedule)
|
|
helpers.WriteJSON(w, http.StatusOK, schedule)
|
|
}
|
|
|
|
func GetProjectSchedules(w http.ResponseWriter, r *http.Request) {
|
|
project := context.Get(r, "project").(db.Project)
|
|
|
|
tplSchedules, err := helpers.Store(r).GetProjectSchedules(project.ID)
|
|
if err != nil {
|
|
helpers.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
helpers.WriteJSON(w, http.StatusOK, tplSchedules)
|
|
}
|
|
func GetTemplateSchedules(w http.ResponseWriter, r *http.Request) {
|
|
project := context.Get(r, "project").(db.Project)
|
|
templateID, err := helpers.GetIntParam("template_id", w, r)
|
|
if err != nil {
|
|
helpers.WriteJSON(w, http.StatusBadRequest, map[string]string{
|
|
"error": "template_id must be provided",
|
|
})
|
|
return
|
|
}
|
|
|
|
tplSchedules, err := helpers.Store(r).GetTemplateSchedules(project.ID, templateID)
|
|
if err != nil {
|
|
helpers.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
helpers.WriteJSON(w, http.StatusOK, tplSchedules)
|
|
}
|
|
|
|
func validateCronFormat(cronFormat string, w http.ResponseWriter) bool {
|
|
err := schedules.ValidateCronFormat(cronFormat)
|
|
if err == nil {
|
|
return true
|
|
}
|
|
helpers.WriteJSON(w, http.StatusBadRequest, map[string]string{
|
|
"error": "Cron: " + err.Error(),
|
|
})
|
|
return false
|
|
}
|
|
|
|
func ValidateScheduleCronFormat(w http.ResponseWriter, r *http.Request) {
|
|
var schedule db.Schedule
|
|
if !helpers.Bind(w, r, &schedule) {
|
|
return
|
|
}
|
|
|
|
_ = validateCronFormat(schedule.CronFormat, w)
|
|
}
|
|
|
|
// AddSchedule adds a template to the database
|
|
func AddSchedule(w http.ResponseWriter, r *http.Request) {
|
|
project := context.Get(r, "project").(db.Project)
|
|
|
|
var schedule db.Schedule
|
|
if !helpers.Bind(w, r, &schedule) {
|
|
return
|
|
}
|
|
|
|
if !validateCronFormat(schedule.CronFormat, w) {
|
|
return
|
|
}
|
|
|
|
schedule.ProjectID = project.ID
|
|
schedule, err := helpers.Store(r).CreateSchedule(schedule)
|
|
if err != nil {
|
|
helpers.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
helpers.EventLog(r, helpers.EventLogCreate, helpers.EventLogItem{
|
|
UserID: helpers.UserFromContext(r).ID,
|
|
ProjectID: project.ID,
|
|
ObjectType: db.EventSchedule,
|
|
ObjectID: schedule.ID,
|
|
Description: fmt.Sprintf("Schedule ID %d created", schedule.ID),
|
|
})
|
|
|
|
refreshSchedulePool(r)
|
|
|
|
helpers.WriteJSON(w, http.StatusCreated, schedule)
|
|
}
|
|
|
|
// UpdateSchedule writes a schedule to an existing key in the database
|
|
func UpdateSchedule(w http.ResponseWriter, r *http.Request) {
|
|
oldSchedule := context.Get(r, "schedule").(db.Schedule)
|
|
|
|
var schedule db.Schedule
|
|
if !helpers.Bind(w, r, &schedule) {
|
|
return
|
|
}
|
|
|
|
// project ID and schedule ID in the body and the path must be the same
|
|
|
|
if schedule.ID != oldSchedule.ID {
|
|
helpers.WriteJSON(w, http.StatusBadRequest, map[string]string{
|
|
"error": "schedule id in URL and in body must be the same",
|
|
})
|
|
return
|
|
}
|
|
|
|
if schedule.ProjectID != oldSchedule.ProjectID {
|
|
helpers.WriteJSON(w, http.StatusBadRequest, map[string]string{
|
|
"error": "You can not move schedule to other project",
|
|
})
|
|
return
|
|
}
|
|
|
|
if !validateCronFormat(schedule.CronFormat, w) {
|
|
return
|
|
}
|
|
|
|
err := helpers.Store(r).UpdateSchedule(schedule)
|
|
if err != nil {
|
|
helpers.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
helpers.EventLog(r, helpers.EventLogUpdate, helpers.EventLogItem{
|
|
UserID: helpers.UserFromContext(r).ID,
|
|
ProjectID: oldSchedule.ProjectID,
|
|
ObjectType: db.EventSchedule,
|
|
ObjectID: oldSchedule.ID,
|
|
Description: fmt.Sprintf("Schedule ID %d updated", schedule.ID),
|
|
})
|
|
|
|
refreshSchedulePool(r)
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
func SetScheduleActive(w http.ResponseWriter, r *http.Request) {
|
|
oldSchedule := context.Get(r, "schedule").(db.Schedule)
|
|
|
|
var schedule struct {
|
|
Active bool `json:"active"`
|
|
}
|
|
|
|
if !helpers.Bind(w, r, &schedule) {
|
|
return
|
|
}
|
|
|
|
err := helpers.Store(r).SetScheduleActive(oldSchedule.ProjectID, oldSchedule.ID, schedule.Active)
|
|
if err != nil {
|
|
helpers.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
helpers.EventLog(r, helpers.EventLogUpdate, helpers.EventLogItem{
|
|
UserID: helpers.UserFromContext(r).ID,
|
|
ProjectID: oldSchedule.ProjectID,
|
|
ObjectType: db.EventSchedule,
|
|
ObjectID: oldSchedule.ID,
|
|
Description: fmt.Sprintf("Schedule ID %d updated", oldSchedule.ID),
|
|
})
|
|
|
|
refreshSchedulePool(r)
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
// RemoveSchedule deletes a schedule from the database
|
|
func RemoveSchedule(w http.ResponseWriter, r *http.Request) {
|
|
schedule := context.Get(r, "schedule").(db.Schedule)
|
|
|
|
err := helpers.Store(r).DeleteSchedule(schedule.ProjectID, schedule.ID)
|
|
if err != nil {
|
|
helpers.WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
helpers.EventLog(r, helpers.EventLogDelete, helpers.EventLogItem{
|
|
UserID: helpers.UserFromContext(r).ID,
|
|
ProjectID: schedule.ProjectID,
|
|
ObjectType: db.EventSchedule,
|
|
ObjectID: schedule.ID,
|
|
Description: fmt.Sprintf("Schedule ID %d deleted", schedule.ID),
|
|
})
|
|
|
|
refreshSchedulePool(r)
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|