smon/notification/script.go
2024-06-28 17:18:08 +02:00

132 lines
2.4 KiB
Go

package notification
import (
// External
werr "git.gibonuddevalla.se/go/wrappederror"
// Standard
"encoding/json"
"log/slog"
"net/url"
"os/exec"
"strconv"
"strings"
)
type Script struct {
Filename string
Prio int
AcknowledgeURL string
logger *slog.Logger
exists bool
updated Service
}
func init() {
allServices = append(allServices, &Script{})
}
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) SetPrio(prio int) {
script.Prio = prio
}
func (script *Script) SetExists(exists bool) {
script.exists = exists
}
func (script Script) Exists() bool {
return script.exists
}
func (script *Script) String() string {
return script.Filename
}
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
}
func (script *Script) Update(values url.Values) (err error) {
updated := Script{}
script.updated = &updated
updated.Prio, err = strconv.Atoi(values.Get("prio"))
if err != nil {
return werr.Wrap(err)
}
givenFilename := values.Get("filename")
if strings.TrimSpace(givenFilename) == "" {
return werr.New("Filename cannot be empty")
}
updated.Filename = strings.TrimSpace(givenFilename)
return
}
func (script *Script) Updated() Service {
return script.updated
}
func (script *Script) Commit() {
updated := script.updated.(*Script)
script.Prio = updated.Prio
script.Filename = updated.Filename
}
func (script Script) JSON() []byte {
data := struct {
Filename string `json:"filename"`
}{
script.Filename,
}
j, _ := json.Marshal(data)
return j
}