mail, context
This commit is contained in:
parent
f5e83ef690
commit
da1322b7cb
31
config.yml
31
config.yml
@ -1,3 +1,6 @@
|
|||||||
|
mail:
|
||||||
|
host: localhost:25
|
||||||
|
|
||||||
directories:
|
directories:
|
||||||
- path: /tmp/foo
|
- path: /tmp/foo
|
||||||
recursive: false
|
recursive: false
|
||||||
@ -5,7 +8,9 @@ directories:
|
|||||||
pollingInterval: 60
|
pollingInterval: 60
|
||||||
regex: "/[^\\.][^/]+.xml$"
|
regex: "/[^\\.][^/]+.xml$"
|
||||||
actions:
|
actions:
|
||||||
- type: http
|
- id: postXML
|
||||||
|
description: POST xml
|
||||||
|
type: http
|
||||||
method: post
|
method: post
|
||||||
url: http://localhost:8080/api/v1/_/renz_einfo/xml
|
url: http://localhost:8080/api/v1/_/renz_einfo/xml
|
||||||
header:
|
header:
|
||||||
@ -13,12 +18,32 @@ directories:
|
|||||||
ContentType: application/xml
|
ContentType: application/xml
|
||||||
# content: PLAIN IS FILECONTENT
|
# content: PLAIN IS FILECONTENT
|
||||||
onError:
|
onError:
|
||||||
- type: move
|
- id: moveXMLError
|
||||||
|
description: MOVE xml to error dir
|
||||||
|
type: move
|
||||||
to: /tmp/error/{{ filename }}
|
to: /tmp/error/{{ filename }}
|
||||||
|
- id: mailXMLError
|
||||||
|
description: eInfo Import ERROR on POST xml
|
||||||
|
type: mail
|
||||||
|
to: sebastian@webmakers.de
|
||||||
|
subject: "{{ action.Description }}"
|
||||||
|
body: |
|
||||||
|
path: {{ path }}
|
||||||
|
event: {{ event }}
|
||||||
|
|
||||||
|
http status: {{ context.postXML.response.Status }}
|
||||||
|
|
||||||
|
http response body
|
||||||
|
------------------
|
||||||
|
{{ context.postXML.response.Body }}
|
||||||
|
|
||||||
|
from: noreply@webmakers.de
|
||||||
stop: true
|
stop: true
|
||||||
|
|
||||||
onSuccess:
|
onSuccess:
|
||||||
- type: delete
|
- id: deleteXML
|
||||||
|
description: DELETE xml after POST
|
||||||
|
type: delete
|
||||||
|
|
||||||
- path: /tmp/foo
|
- path: /tmp/foo
|
||||||
recursive: false
|
recursive: false
|
||||||
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module gitbase.de/apairon/fstrigger
|
|||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/domodwyer/mailyak/v3 v3.3.3
|
||||||
github.com/flosch/pongo2/v4 v4.0.2
|
github.com/flosch/pongo2/v4 v4.0.2
|
||||||
github.com/rjeczalik/notify v0.9.2
|
github.com/rjeczalik/notify v0.9.2
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
|
4
go.sum
4
go.sum
@ -1,5 +1,5 @@
|
|||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/domodwyer/mailyak/v3 v3.3.3 h1:E9cjqDUiwY1QSE5G2CbWHM7EJV5FybKPHnGovc2iaA8=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/domodwyer/mailyak/v3 v3.3.3/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c=
|
||||||
github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw=
|
github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw=
|
||||||
github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8=
|
github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
145
main.go
145
main.go
@ -13,13 +13,16 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/domodwyer/mailyak/v3"
|
||||||
"github.com/flosch/pongo2/v4"
|
"github.com/flosch/pongo2/v4"
|
||||||
"github.com/rjeczalik/notify"
|
"github.com/rjeczalik/notify"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ActionConfig struct {
|
type ActionConfig struct {
|
||||||
Type string
|
Id string
|
||||||
|
Type string
|
||||||
|
Description string
|
||||||
|
|
||||||
// http
|
// http
|
||||||
Method *string
|
Method *string
|
||||||
@ -30,6 +33,12 @@ type ActionConfig struct {
|
|||||||
// move
|
// move
|
||||||
To *string
|
To *string
|
||||||
|
|
||||||
|
// mail
|
||||||
|
// To *string
|
||||||
|
Subject *string
|
||||||
|
Body *string
|
||||||
|
From *string
|
||||||
|
|
||||||
Stop bool
|
Stop bool
|
||||||
OnSuccess []ActionConfig `yaml:"onSuccess"`
|
OnSuccess []ActionConfig `yaml:"onSuccess"`
|
||||||
OnError []ActionConfig `yaml:"onError"`
|
OnError []ActionConfig `yaml:"onError"`
|
||||||
@ -45,10 +54,17 @@ type DirectoryConfig struct {
|
|||||||
Actions []ActionConfig
|
Actions []ActionConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MailConfig struct {
|
||||||
|
Host *string
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
Mail MailConfig
|
||||||
Directories []DirectoryConfig
|
Directories []DirectoryConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var conf = Config{}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
type pollInfo struct {
|
type pollInfo struct {
|
||||||
@ -68,6 +84,8 @@ func (p pollInfo) Sys() interface{} {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type actionCtx map[string]map[string]interface{}
|
||||||
|
|
||||||
func startWatcher(directory *DirectoryConfig) {
|
func startWatcher(directory *DirectoryConfig) {
|
||||||
c := make(chan notify.EventInfo, 1000)
|
c := make(chan notify.EventInfo, 1000)
|
||||||
monitoredEvents := []notify.Event{}
|
monitoredEvents := []notify.Event{}
|
||||||
@ -140,10 +158,14 @@ func startWatcher(directory *DirectoryConfig) {
|
|||||||
|
|
||||||
if eventInfo != nil {
|
if eventInfo != nil {
|
||||||
p := eventInfo.Path()
|
p := eventInfo.Path()
|
||||||
log.Printf("path: %s; event: %s\n", p, eventInfo.Event().String())
|
eventStr := eventInfo.Event().String()
|
||||||
|
if eventInfo.Event() == 0 {
|
||||||
|
eventStr = "POLLING"
|
||||||
|
}
|
||||||
|
log.Printf("path: %s; event: %s\n", p, eventStr)
|
||||||
if directory._regex == nil || directory._regex.MatchString(p) {
|
if directory._regex == nil || directory._regex.MatchString(p) {
|
||||||
for _, action := range directory.Actions {
|
for _, action := range directory.Actions {
|
||||||
contin, _ := runAction(&action, eventInfo)
|
contin, _ := runAction(&action, eventInfo, nil)
|
||||||
if !contin {
|
if !contin {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -180,41 +202,46 @@ func startWatcher(directory *DirectoryConfig) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runAction(action *ActionConfig, eventInfo notify.EventInfo) (contin bool, err error) {
|
func runAction(action *ActionConfig, eventInfo notify.EventInfo, ctx actionCtx) (contin bool, err error) {
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = make(actionCtx)
|
||||||
|
}
|
||||||
|
add2Ctx(action, ctx, "action", action)
|
||||||
|
|
||||||
contin = !action.Stop
|
contin = !action.Stop
|
||||||
log.Printf("path: %s; action: %s; stop: %v\n", eventInfo.Path(), action.Type, !contin)
|
log.Printf("path: %s; action: %s; stop: %v\n", eventInfo.Path(), action.Id, !contin)
|
||||||
|
|
||||||
switch action.Type {
|
switch action.Type {
|
||||||
case "http":
|
case "http":
|
||||||
err = actionHttp(action, eventInfo)
|
err = actionHttp(action, eventInfo, ctx)
|
||||||
case "move":
|
case "move":
|
||||||
err = actionMove(action, eventInfo)
|
err = actionMove(action, eventInfo, ctx)
|
||||||
case "delete":
|
case "delete":
|
||||||
err = actionDelete(action, eventInfo)
|
err = actionDelete(action, eventInfo, ctx)
|
||||||
case "log":
|
case "log":
|
||||||
err = actionLog(action, eventInfo)
|
err = actionLog(action, eventInfo, ctx)
|
||||||
|
case "mail":
|
||||||
|
err = actionMail(action, eventInfo, ctx)
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("action type %s unknown", action.Type)
|
err = fmt.Errorf("action type %s unknown", action.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("path: %s; action: %s; error %s", eventInfo.Path(), action.Type, err)
|
add2Ctx(action, ctx, "error", err.Error())
|
||||||
|
|
||||||
|
log.Printf("path: %s; action: %s; error %s", eventInfo.Path(), action.Id, err)
|
||||||
for _, aE := range action.OnError {
|
for _, aE := range action.OnError {
|
||||||
_c, errE := runAction(&aE, eventInfo)
|
_c, _ := runAction(&aE, eventInfo, ctx)
|
||||||
contin = contin && _c
|
contin = contin && _c
|
||||||
if errE != nil {
|
|
||||||
log.Printf("path: %s; action: %s; onError %s, error %s", eventInfo.Path(), action.Type, aE.Type, errE)
|
|
||||||
}
|
|
||||||
if !contin {
|
if !contin {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, aS := range action.OnSuccess {
|
for _, aS := range action.OnSuccess {
|
||||||
_c, errS := runAction(&aS, eventInfo)
|
_c, errS := runAction(&aS, eventInfo, ctx)
|
||||||
contin = contin && _c
|
contin = contin && _c
|
||||||
if errS != nil {
|
if errS != nil {
|
||||||
log.Printf("path: %s; action: %s; onSuccess %s, error %s", eventInfo.Path(), action.Type, aS.Type, errS)
|
|
||||||
err = errS
|
err = errS
|
||||||
}
|
}
|
||||||
if !contin {
|
if !contin {
|
||||||
@ -226,10 +253,19 @@ func runAction(action *ActionConfig, eventInfo notify.EventInfo) (contin bool, e
|
|||||||
return contin, err
|
return contin, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func actionHttp(action *ActionConfig, eventInfo notify.EventInfo) error {
|
func add2Ctx(action *ActionConfig, ctx actionCtx, key string, val interface{}) {
|
||||||
|
if action.Id != "" {
|
||||||
|
if ctx[action.Id] == nil {
|
||||||
|
ctx[action.Id] = make(map[string]interface{})
|
||||||
|
}
|
||||||
|
ctx[action.Id][key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func actionHttp(action *ActionConfig, eventInfo notify.EventInfo, ctx actionCtx) error {
|
||||||
method := "POST"
|
method := "POST"
|
||||||
if action.Method != nil {
|
if action.Method != nil {
|
||||||
m, err := tpl2String(*action.Method, action, eventInfo)
|
m, err := tpl2String(*action.Method, action, eventInfo, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -238,7 +274,7 @@ func actionHttp(action *ActionConfig, eventInfo notify.EventInfo) error {
|
|||||||
if action.URL == nil {
|
if action.URL == nil {
|
||||||
return fmt.Errorf("missing url in http action")
|
return fmt.Errorf("missing url in http action")
|
||||||
}
|
}
|
||||||
url, err := tpl2String(*action.URL, action, eventInfo)
|
url, err := tpl2String(*action.URL, action, eventInfo, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -253,7 +289,7 @@ func actionHttp(action *ActionConfig, eventInfo notify.EventInfo) error {
|
|||||||
}
|
}
|
||||||
postData = bytes.NewBuffer(postBytes)
|
postData = bytes.NewBuffer(postBytes)
|
||||||
} else {
|
} else {
|
||||||
p, err := tpl2String(*action.Content, action, eventInfo)
|
p, err := tpl2String(*action.Content, action, eventInfo, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -281,6 +317,12 @@ func actionHttp(action *ActionConfig, eventInfo notify.EventInfo) error {
|
|||||||
fmt.Println(string(body))
|
fmt.Println(string(body))
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
add2Ctx(action, ctx, "response", map[string]interface{}{
|
||||||
|
"Status": resp.Status,
|
||||||
|
"StatusCode": resp.StatusCode,
|
||||||
|
"Body": string(body),
|
||||||
|
})
|
||||||
|
|
||||||
if resp.StatusCode >= 400 {
|
if resp.StatusCode >= 400 {
|
||||||
return fmt.Errorf("response status %s", resp.Status)
|
return fmt.Errorf("response status %s", resp.Status)
|
||||||
}
|
}
|
||||||
@ -288,12 +330,12 @@ func actionHttp(action *ActionConfig, eventInfo notify.EventInfo) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func actionMove(action *ActionConfig, eventInfo notify.EventInfo) error {
|
func actionMove(action *ActionConfig, eventInfo notify.EventInfo, ctx actionCtx) error {
|
||||||
if action.To == nil {
|
if action.To == nil {
|
||||||
return fmt.Errorf("missing to: as destination for move action")
|
return fmt.Errorf("missing to: as destination for move action")
|
||||||
}
|
}
|
||||||
|
|
||||||
to, err := tpl2String(*action.To, action, eventInfo)
|
to, err := tpl2String(*action.To, action, eventInfo, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -302,11 +344,11 @@ func actionMove(action *ActionConfig, eventInfo notify.EventInfo) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func actionDelete(action *ActionConfig, eventInfo notify.EventInfo) error {
|
func actionDelete(action *ActionConfig, eventInfo notify.EventInfo, ctx actionCtx) error {
|
||||||
return os.Remove(eventInfo.Path())
|
return os.Remove(eventInfo.Path())
|
||||||
}
|
}
|
||||||
|
|
||||||
func actionLog(action *ActionConfig, eventInfo notify.EventInfo) error {
|
func actionLog(action *ActionConfig, eventInfo notify.EventInfo, ctx actionCtx) error {
|
||||||
var logstr string
|
var logstr string
|
||||||
if action.Content != nil {
|
if action.Content != nil {
|
||||||
logstr = *action.Content
|
logstr = *action.Content
|
||||||
@ -317,7 +359,55 @@ func actionLog(action *ActionConfig, eventInfo notify.EventInfo) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func tpl2String(tpl string, action *ActionConfig, eventInfo notify.EventInfo) (string, error) {
|
func actionMail(action *ActionConfig, eventInfo notify.EventInfo, ctx actionCtx) error {
|
||||||
|
if conf.Mail.Host == nil {
|
||||||
|
return fmt.Errorf("missing host in mail: config")
|
||||||
|
}
|
||||||
|
if action.To == nil {
|
||||||
|
return fmt.Errorf("missing to: as recipient mail address")
|
||||||
|
}
|
||||||
|
if action.Subject == nil {
|
||||||
|
return fmt.Errorf("missing subject: action")
|
||||||
|
}
|
||||||
|
if action.Body == nil {
|
||||||
|
return fmt.Errorf("missing body: action")
|
||||||
|
}
|
||||||
|
if action.From == nil {
|
||||||
|
return fmt.Errorf("missing from: in action")
|
||||||
|
}
|
||||||
|
|
||||||
|
mail := mailyak.New(*conf.Mail.Host, nil)
|
||||||
|
|
||||||
|
to, err := tpl2String(*action.To, action, eventInfo, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mail.To(to)
|
||||||
|
|
||||||
|
from, err := tpl2String(*action.From, action, eventInfo, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mail.From(from)
|
||||||
|
|
||||||
|
mail.FromName("fstrigger")
|
||||||
|
|
||||||
|
subject, err := tpl2String(*action.Subject, action, eventInfo, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mail.Subject(subject)
|
||||||
|
|
||||||
|
body, err := tpl2String(*action.Body, action, eventInfo, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mail.Plain().Set(body)
|
||||||
|
|
||||||
|
return mail.Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
func tpl2String(tpl string, action *ActionConfig, eventInfo notify.EventInfo, ctx actionCtx) (string, error) {
|
||||||
_tpl, err := pongo2.FromString(tpl)
|
_tpl, err := pongo2.FromString(tpl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -328,13 +418,14 @@ func tpl2String(tpl string, action *ActionConfig, eventInfo notify.EventInfo) (s
|
|||||||
"path": p,
|
"path": p,
|
||||||
"dirname": filepath.Dir(p),
|
"dirname": filepath.Dir(p),
|
||||||
"filename": filepath.Base(p),
|
"filename": filepath.Base(p),
|
||||||
|
"event": eventInfo.Event().String(),
|
||||||
|
"action": action,
|
||||||
|
"context": ctx,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
conf := Config{}
|
|
||||||
|
|
||||||
confDat, err := ioutil.ReadFile("./config.yml")
|
confDat, err := ioutil.ReadFile("./config.yml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("error %v", err)
|
log.Fatalf("error %v", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user