134 lines
2.9 KiB
Go
134 lines
2.9 KiB
Go
package rules
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"iwarma.ru/console/correlator/events"
|
|
"net/http"
|
|
"text/template"
|
|
"time"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const (
|
|
HttpActionType = "http"
|
|
)
|
|
|
|
// HttpAction Send record via HTTP. Wil use application/json if empty content type set
|
|
type HttpAction struct {
|
|
Url string
|
|
Template string
|
|
ContentType string
|
|
bodyTemplate *template.Template
|
|
}
|
|
|
|
func (action HttpAction) GetType() string {
|
|
return HttpActionType
|
|
}
|
|
|
|
func (action *HttpAction) Perform(events *[]*events.Event) error {
|
|
contextLogger := log.WithFields(log.Fields{"type": HttpActionType, "event_count": len(*events)})
|
|
contextLogger.Debug("Start action")
|
|
defer contextLogger.Debug("End action")
|
|
|
|
if events == nil {
|
|
contextLogger.Error("Nil events provided")
|
|
return errors.New("nil events provided")
|
|
}
|
|
|
|
// Create template
|
|
if action.bodyTemplate == nil {
|
|
bodyTemplate, err := template.New("Action").Parse(action.Template)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
action.bodyTemplate = bodyTemplate
|
|
}
|
|
|
|
for _, cur := range *events {
|
|
// Render template
|
|
var buf bytes.Buffer
|
|
err := action.bodyTemplate.Execute(&buf, *cur)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
reader := bytes.NewReader(buf.Bytes())
|
|
http.DefaultClient.Timeout = time.Second * 30
|
|
_, err = http.Post(action.Url, action.ContentType, reader)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
}
|
|
http.DefaultClient.CloseIdleConnections()
|
|
return nil
|
|
}
|
|
|
|
func (action HttpAction) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(struct {
|
|
CurType string `json:"type"`
|
|
Url string `json:"url"`
|
|
Template string `json:"template"`
|
|
ContentType string `json:"content_type"`
|
|
}{
|
|
CurType: HttpActionType,
|
|
Url: action.Url,
|
|
Template: action.Template,
|
|
ContentType: action.ContentType,
|
|
})
|
|
}
|
|
|
|
func (action *HttpAction) UnmarshalJSON(b []byte) error {
|
|
|
|
cur := struct {
|
|
CurType string `json:"type"`
|
|
Url string `json:"url"`
|
|
ContentType string `json:"content_type"`
|
|
Template string `json:"template"`
|
|
}{}
|
|
|
|
err := json.Unmarshal(b, &cur)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if cur.CurType != HttpActionType {
|
|
return fmt.Errorf("bad action type. Expect http, got %s", cur.CurType)
|
|
}
|
|
|
|
action.Url = cur.Url
|
|
action.Template = cur.Template
|
|
action.ContentType = cur.ContentType
|
|
|
|
return nil
|
|
}
|
|
|
|
func (action *HttpAction) ParseInterface(v interface{}) error {
|
|
m, ok := v.(map[string]interface{})
|
|
if !ok {
|
|
return fmt.Errorf("can't parse %v from %T", v, v)
|
|
}
|
|
|
|
action.Url, ok = m["url"].(string)
|
|
if !ok {
|
|
return fmt.Errorf("can't get URL")
|
|
}
|
|
|
|
// Template can be in data or template
|
|
if action.Template, ok = m["data"].(string); !ok {
|
|
if action.Template, ok = m["template"].(string); !ok {
|
|
return fmt.Errorf("can't get template")
|
|
}
|
|
}
|
|
|
|
if action.ContentType, ok = m["content_type"].(string); !ok {
|
|
return fmt.Errorf("no content type provided")
|
|
}
|
|
|
|
return nil
|
|
}
|