mirror of
https://github.com/semaphoreui/semaphore.git
synced 2024-11-25 06:15:56 +01:00
3b7436e22c
I have updated all dependencies within go.mod by executing `go get -u ./...`, beside that I had to replace the imports for logrus, mergo and squirrel to match the right names from their modules.
206 lines
4.9 KiB
Go
206 lines
4.9 KiB
Go
package projects
|
|
|
|
import (
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/ansible-semaphore/semaphore/api/helpers"
|
|
"github.com/ansible-semaphore/semaphore/db"
|
|
"github.com/ansible-semaphore/semaphore/services/schedules"
|
|
"github.com/gorilla/context"
|
|
"net/http"
|
|
"strconv"
|
|
)
|
|
|
|
// 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 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
|
|
}
|
|
|
|
user := context.Get(r, "user").(*db.User)
|
|
objType := db.EventSchedule
|
|
desc := "Schedule ID " + strconv.Itoa(schedule.ID) + " created"
|
|
_, err = helpers.Store(r).CreateEvent(db.Event{
|
|
UserID: &user.ID,
|
|
ProjectID: &project.ID,
|
|
ObjectType: &objType,
|
|
ObjectID: &schedule.ID,
|
|
Description: &desc,
|
|
})
|
|
if err != nil {
|
|
log.Error(err)
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
user := context.Get(r, "user").(*db.User)
|
|
|
|
desc := "Schedule ID " + strconv.Itoa(schedule.ID) + " updated"
|
|
objType := db.EventSchedule
|
|
|
|
_, err = helpers.Store(r).CreateEvent(db.Event{
|
|
UserID: &user.ID,
|
|
ProjectID: &schedule.ProjectID,
|
|
Description: &desc,
|
|
ObjectID: &schedule.ID,
|
|
ObjectType: &objType,
|
|
})
|
|
|
|
if err != nil {
|
|
log.Error(err)
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
user := context.Get(r, "user").(*db.User)
|
|
desc := "Schedule ID " + strconv.Itoa(schedule.ID) + " deleted"
|
|
_, err = helpers.Store(r).CreateEvent(db.Event{
|
|
UserID: &user.ID,
|
|
ProjectID: &schedule.ProjectID,
|
|
Description: &desc,
|
|
})
|
|
|
|
if err != nil {
|
|
log.Error(err)
|
|
}
|
|
|
|
refreshSchedulePool(r)
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|