package main import ( "encoding/json" "fmt" "net/http" "slices" "time" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" "github.com/tidwall/pretty" ) func ApiRun(c *gin.Context) { log.WithFields(log.Fields{}).Debugf("starting") log.WithFields(log.Fields{}).Debugf("done") cfg.Run(true) c.JSON(http.StatusOK, gin.H{ "message": "done", }) } func ApiSnapshotAdd(c *gin.Context) { log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("starting") log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("done") if app, ok := cfg.apps[c.Param("app")]; ok { schedule := c.Param("schedule") if _, ok := app.schedule[schedule]; ok { if err := app.RunStandaloneSchedule(schedule); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) } else { c.JSON(http.StatusOK, gin.H{ "message": "done", }) } } else { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "no schedule found", }) } } else { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "no app found", }) } } func ApiSnapshotDel(c *gin.Context) { log.WithFields(log.Fields{}).Debugf("starting") log.WithFields(log.Fields{}).Debugf("done") c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "not implemented", }) } func ApiSnapshotList(c *gin.Context) { log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("starting") log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("done") if app, ok := cfg.apps[c.Param("app")]; ok { if snapshots, err := app.Snapshots(); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) } else { c.JSON(http.StatusOK, gin.H{ "message": "done", "snapshots": snapshots, }) } } else { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "no app found", }) } } // FIXME func ApiScheduleAdd(c *gin.Context) { log.WithFields(log.Fields{}).Debugf("starting") log.WithFields(log.Fields{}).Debugf("done") c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "not implemented", }) } // FIXME func ApiScheduleDel(c *gin.Context) { log.WithFields(log.Fields{}).Debugf("starting") log.WithFields(log.Fields{}).Debugf("done") c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "not implemented", }) } // FIXME func ApiScheduleList(c *gin.Context) { log.WithFields(log.Fields{}).Debugf("starting") log.WithFields(log.Fields{}).Debugf("done") c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "not implemented", }) } func ApiRunApp(c *gin.Context) { log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("starting") log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("done") if app, ok := cfg.apps[c.Param("app")]; ok { if err := app.RunStandaloneTime(time.Now()); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) } else { c.JSON(http.StatusOK, gin.H{ "message": "done", }) } } else { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "no app found", }) } } func ApiSave(c *gin.Context) { log.WithFields(log.Fields{}).Debugf("starting") log.WithFields(log.Fields{}).Debugf("done") if err := cfg.Save(true); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) } else { c.JSON(http.StatusOK, gin.H{ "message": "done", }) } } func ApiConfig(c *gin.Context) { log.WithFields(log.Fields{}).Debugf("starting") log.WithFields(log.Fields{}).Debugf("done") if b, err := cfg.Pretty(true); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) } else { c.Data(http.StatusOK, "application/json", b) } } func ApiConfigApp(c *gin.Context) { log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("starting") log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("done") name := c.Param("app") found := false CfgLock() defer CfgUnlock() for _, app := range cfg.Apps { if app.Name == name { found = true if b, err := app.Pretty(false); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) } else { c.Data(http.StatusOK, "application/json", b) } } } if !found { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "no app found", }) } } func ApiAppList(c *gin.Context) { log.WithFields(log.Fields{}).Debugf("starting") log.WithFields(log.Fields{}).Debugf("done") list := make([]string, 0) CfgLock() defer CfgUnlock() for _, app := range cfg.Apps { list = append(list, app.Name) } slices.Sort(list) b, err := json.Marshal(list) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } c.Data(http.StatusOK, "application/json", pretty.PrettyOptions(b, &pretty.Options{Indent: " "})) } func ApiListSchedule(c *gin.Context) { log.WithFields(log.Fields{"schedule": c.Param("schedule")}).Debugf("starting") log.WithFields(log.Fields{"schedule": c.Param("schedule")}).Debugf("done") name := c.Param("schedule") list := make([]string, 0) CfgLock() defer CfgUnlock() for _, app := range cfg.Apps { for _, sched := range app.Schedule { if sched == name && !slices.Contains(list, app.Name) { list = append(list, app.Name) } } } slices.Sort(list) b, err := json.Marshal(list) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } c.Data(http.StatusOK, "application/json", pretty.PrettyOptions(b, &pretty.Options{Indent: " "})) } func ApiAppAdd(c *gin.Context) { log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("starting") log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("done") name := c.Param("app") found := false CfgLock() defer CfgUnlock() for _, app := range cfg.Apps { if app.Name == name { found = true } } if found { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "app already exist", }) return } app := &AppConfig{ Name: name, Active: false, } cfg.Apps = append(cfg.Apps, app) err := cfg.Save(false) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } c.JSON(http.StatusOK, gin.H{ "message": "done", }) } func ApiAppDel(c *gin.Context) { log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("starting") log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("done") name := c.Param("app") found := false CfgLock() defer CfgUnlock() for id, app := range cfg.Apps { if app.Name == name { if app.Active { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "app still active", }) return } found = true cfg.Apps[id] = cfg.Apps[len(cfg.Apps)-1] cfg.Apps = cfg.Apps[:len(cfg.Apps)-1] } } if !found { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "no app found", }) return } err := cfg.Save(false) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } c.JSON(http.StatusOK, gin.H{ "message": "done", }) } func ApiAppActivate(c *gin.Context) { log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("starting") log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("done") name := c.Param("app") CfgLock() defer CfgUnlock() for _, app := range cfg.Apps { if app.Name == name { if app.Active { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "app already active", }) return } a, err := cfg.NewApp(app.Name, app.Sources, app.Destinations, app.Schedule, app.Before, app.After) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } cfg.apps[app.Name] = a } } err := cfg.Save(false) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } c.JSON(http.StatusOK, gin.H{ "message": "done", }) } func ApiAppDeactivate(c *gin.Context) { log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("starting") log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("done") name := c.Param("app") CfgLock() defer CfgUnlock() if _, ok := cfg.apps[name]; ok { delete(cfg.apps, name) } else { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "app is not active", }) return } for _, app := range cfg.Apps { if app.Name == name { app.Active = false } } err := cfg.Save(false) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } c.JSON(http.StatusOK, gin.H{ "message": "done", }) } func ApiAppSourceList(c *gin.Context) { log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("starting") log.WithFields(log.Fields{"app": c.Param("app")}).Debugf("done") name := c.Param("app") found := false app := &AppConfig{} CfgLock() defer CfgUnlock() for _, a := range cfg.Apps { if a.Name == name { found = true app = a } } if !found { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "app does not exist", }) return } b, err := json.Marshal(app.Sources) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } c.Data(http.StatusOK, "application/json", pretty.PrettyOptions(b, &pretty.Options{Indent: " "})) } func ApiAppSourceAdd(c *gin.Context) { app := c.Param("app") src := c.Param("src") src = src[1:] // cut first char from wildcard match log.WithFields(log.Fields{"app": app, "src": src}).Debugf("starting") log.WithFields(log.Fields{"app": app, "src": src}).Debugf("done") found := false ac := &AppConfig{} CfgLock() defer CfgUnlock() for _, a := range cfg.Apps { if a.Name == app { found = true ac = a } } if !found { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "app does not exist", }) return } s := Addr(src) if s.Box() == "" { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "source box incorrect", }) return } if _, ok := cfg.box[s.Box()]; !ok { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "source box doesn't exist", }) return } if s.Path() == "" { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "source path incorrect", }) return } if slices.Contains(ac.Sources, s.String()) { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "source already exists", }) return } ac.Sources = append(ac.Sources, s.String()) if ac.Active { a, err := cfg.NewApp(ac.Name, ac.Sources, ac.Destinations, ac.Schedule, ac.Before, ac.After) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } cfg.apps[a.name] = a } err := cfg.Save(false) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } c.JSON(http.StatusOK, gin.H{ "message": "done", }) } func ApiAppSourceDel(c *gin.Context) { app := c.Param("app") src := c.Param("src") src = src[1:] // cut first char from wildcard match log.WithFields(log.Fields{"app": app, "src": src}).Debugf("starting") log.WithFields(log.Fields{"app": app, "src": src}).Debugf("done") found := false ac := &AppConfig{} CfgLock() defer CfgUnlock() for _, a := range cfg.Apps { if a.Name == app { found = true ac = a } } if !found { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "app does not exist", }) return } if !slices.Contains(ac.Sources, src) { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": "source does not exist", }) return } for id, s := range ac.Sources { if s == src { ac.Sources[id] = ac.Sources[len(ac.Sources)-1] ac.Sources = ac.Sources[:len(ac.Sources)-1] } } if ac.Active { a, err := cfg.NewApp(ac.Name, ac.Sources, ac.Destinations, ac.Schedule, ac.Before, ac.After) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } cfg.apps[a.name] = a } err := cfg.Save(false) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "message": "error", "error": fmt.Sprint(err), }) return } c.JSON(http.StatusOK, gin.H{ "message": "done", }) }