diff --git a/main.go b/main.go index 69f80c8..c3919fa 100644 --- a/main.go +++ b/main.go @@ -120,35 +120,35 @@ func main() { // {{{ service.Register("/", false, false, staticHandler) - service.Register("/area/new/{name}", false, false, areaNew) - service.Register("/area/rename/{id}/{name}", false, false, areaRename) - service.Register("/area/delete/{id}", false, false, areaDelete) + service.Register("/area/new/{name}", false, false, actionAreaNew) + service.Register("/area/rename/{id}/{name}", false, false, actionAreaRename) + service.Register("/area/delete/{id}", false, false, actionAreaDelete) - service.Register("/section/new/{areaID}/{name}", false, false, sectionNew) - service.Register("/section/rename/{id}/{name}", false, false, sectionRename) - service.Register("/section/delete/{id}", false, false, sectionDelete) + service.Register("/section/new/{areaID}/{name}", false, false, actionSectionNew) + service.Register("/section/rename/{id}/{name}", false, false, actionSectionRename) + service.Register("/section/delete/{id}", false, false, actionSectionDelete) service.Register("/problems", false, false, pageProblems) - service.Register("/problem/acknowledge/{id}", false, false, pageProblemAcknowledge) - service.Register("/problem/unacknowledge/{id}", false, false, pageProblemUnacknowledge) + service.Register("/problem/acknowledge/{id}", false, false, actionProblemAcknowledge) + service.Register("/problem/unacknowledge/{id}", false, false, actionProblemUnacknowledge) service.Register("/datapoints", false, false, pageDatapoints) service.Register("/datapoint/edit/{id}", false, false, pageDatapointEdit) - service.Register("/datapoint/update/{id}", false, false, pageDatapointUpdate) - service.Register("/datapoint/delete/{id}", false, false, pageDatapointDelete) + service.Register("/datapoint/update/{id}", false, false, actionDatapointUpdate) + service.Register("/datapoint/delete/{id}", false, false, actionDatapointDelete) service.Register("/datapoint/values/{id}", false, false, pageDatapointValues) service.Register("/triggers", false, false, pageTriggers) - service.Register("/trigger/create/{sectionID}/{name}", false, false, triggerCreate) + service.Register("/trigger/create/{sectionID}/{name}", false, false, actionTriggerCreate) service.Register("/trigger/edit/{id}", false, false, pageTriggerEdit) service.Register("/trigger/edit/{id}/{sectionID}", false, false, pageTriggerEdit) - service.Register("/trigger/addDatapoint/{id}/{datapointName}", false, false, pageTriggerDatapointAdd) - service.Register("/trigger/update/{id}", false, false, pageTriggerUpdate) - service.Register("/trigger/run/{id}", false, false, pageTriggerRun) + service.Register("/trigger/addDatapoint/{id}/{datapointName}", false, false, actionTriggerDatapointAdd) + service.Register("/trigger/update/{id}", false, false, actionTriggerUpdate) + service.Register("/trigger/run/{id}", false, false, actionTriggerRun) service.Register("/trigger/delete/{id}", false, false, actionTriggerDelete) service.Register("/configuration", false, false, pageConfiguration) - service.Register("/entry/{datapoint}", false, false, entryDatapoint) + service.Register("/entry/{datapoint}", false, false, actionEntryDatapoint) go nodataLoop() @@ -199,7 +199,7 @@ func staticHandler(w http.ResponseWriter, r *http.Request, sess *session.T) { // service.StaticHandler(w, r, sess) } // }}} -func entryDatapoint(w http.ResponseWriter, r *http.Request, sess *session.T) { // {{{ +func actionEntryDatapoint(w http.ResponseWriter, r *http.Request, sess *session.T) { // {{{ dpoint := r.PathValue("datapoint") value, _ := io.ReadAll(r.Body) @@ -370,7 +370,7 @@ func pageIndex(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{ page.Render(w) } // }}} -func areaNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionAreaNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ name := r.PathValue("name") err := AreaCreate(name) if err != nil { @@ -382,7 +382,7 @@ func areaNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ w.WriteHeader(302) return } // }}} -func areaRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionAreaRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { @@ -401,7 +401,7 @@ func areaRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ w.WriteHeader(302) return } // }}} -func areaDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionAreaDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { @@ -420,7 +420,7 @@ func areaDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ return } // }}} -func sectionNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionSectionNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("areaID") areaID, err := strconv.Atoi(idStr) if err != nil { @@ -439,7 +439,7 @@ func sectionNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ w.WriteHeader(302) return } // }}} -func sectionRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionSectionRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { @@ -458,7 +458,7 @@ func sectionRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{ w.WriteHeader(302) return } // }}} -func sectionDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionSectionDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { @@ -512,7 +512,7 @@ func pageProblems(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{ page.Render(w) return } // }}} -func pageProblemAcknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionProblemAcknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { @@ -531,7 +531,7 @@ func pageProblemAcknowledge(w http.ResponseWriter, r *http.Request, _ *session.T return } // }}} -func pageProblemUnacknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionProblemUnacknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { @@ -610,7 +610,7 @@ func pageDatapointEdit(w http.ResponseWriter, r *http.Request, _ *session.T) { / page.Render(w) return } // }}} -func pageDatapointUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionDatapointUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { @@ -636,7 +636,7 @@ func pageDatapointUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { w.Header().Add("Location", "/datapoints") w.WriteHeader(302) } // }}} -func pageDatapointDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionDatapointDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { @@ -712,7 +712,7 @@ func pageTriggers(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{ page.Render(w) } // }}} -func triggerCreate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionTriggerCreate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ name := r.PathValue("name") sectionIDStr := r.PathValue("sectionID") sectionID, err := strconv.Atoi(sectionIDStr) @@ -799,7 +799,7 @@ func pageTriggerEdit(w http.ResponseWriter, r *http.Request, _ *session.T) { // page.Render(w) } // }}} -func pageTriggerDatapointAdd(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionTriggerDatapointAdd(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ triggerID := r.PathValue("id") dpName := r.PathValue("datapointName") @@ -831,7 +831,7 @@ func pageTriggerDatapointAdd(w http.ResponseWriter, r *http.Request, _ *session. w.Header().Add("Content-Type", "application/json") w.Write(j) } // }}} -func pageTriggerUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionTriggerUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { @@ -866,7 +866,7 @@ func pageTriggerUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { / w.Header().Add("Location", "/triggers") w.WriteHeader(302) } // }}} -func pageTriggerRun(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ +func actionTriggerRun(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { diff --git a/notification/factory.go b/notification/factory.go index db0a4b7..90c5cfe 100644 --- a/notification/factory.go +++ b/notification/factory.go @@ -16,7 +16,16 @@ func ServiceFactory(t string, config []byte, prio int, ackURL string, logger *sl err = werr.Wrap(err).WithData(config) return nil, err } + ntfy.SetLogger(logger) return ntfy, nil + case "SCRIPT": + script, err := NewScript(config, prio, ackURL) + if err != nil { + err = werr.Wrap(err).WithData(config) + return nil, err + } + script.SetLogger(logger) + return script, nil } return nil, werr.New("Unknown notification service, '%s'", t).WithCode("002-0000") diff --git a/notification/script.go b/notification/script.go new file mode 100644 index 0000000..1e8fcca --- /dev/null +++ b/notification/script.go @@ -0,0 +1,70 @@ +package notification + +import ( + // External + werr "git.gibonuddevalla.se/go/wrappederror" + + // Standard + "encoding/json" + "log/slog" + "os/exec" + "strconv" + "strings" +) + +type Script struct { + Filename string + Prio int + AcknowledgeURL string + logger *slog.Logger +} + +func NewScript(config []byte, prio int, ackURL string) (instance *Script, err error) { + instance = new(Script) + err = json.Unmarshal(config, &instance) + if err != nil { + err = werr.Wrap(err).WithCode("002-0001").WithData(config) + return + } + instance.Prio = prio + instance.AcknowledgeURL = ackURL + return instance, nil +} + +func (script *Script) SetLogger(l *slog.Logger) { + script.logger = l +} + +func (script *Script) GetType() string { + return "SCRIPT" +} + +func (script *Script) GetPrio() int { + return script.Prio +} + +func (script Script) Send(problemID int, msg []byte) (err error) { + var errbuf strings.Builder + cmd := exec.Command(script.Filename, strconv.Itoa(problemID), script.AcknowledgeURL, string(msg)) + cmd.Stderr = &errbuf + + err = cmd.Run() + if err != nil { + script.logger.Error("notification", "type", "script", "error", err) + err = werr.Wrap(err).WithData( + struct { + Filename string + ProblemID int + Msg string + StdErr string + }{ + script.Filename, + problemID, + string(msg), + errbuf.String(), + }, + ).Log() + } + + return +}